VSCodeのcode runnerでファイル分割されたC/C++ファイルをコンパイル&実行


環境

  • MacOS Big Sur
  • Visual Studio Code (以下,VSCode)

実現したいこと

VSCodeの拡張機能であるCode Runnerを用いてファイル分割したC/C++の実行をショートカットでできるように設定したい.

code runnerのインストールと設定

次の記事を参考にインストールしてください.

デフォルトの設定の問題点

デフォルトの設定では次のような単一ファイルのみをcode runnerでコンパイル&実行することができる.

hello.c
#include <stdio.h>

int main(void)
{
    printf("hello\n"); // => hello
    return 0;
}

同階層のディレクトリにhelloという実行ファイルが作成されて,コンソールにhelloと出力される.
よって,ここまでは意図した通りに正しく実行できる.

しかし,デフォルトの設定では次のようなケースでは正しくコンパイルできない.

次のようにファイル分割することを考える.

hello.c
#include <stdio.h>

void hello(void)
{
    printf("hello\n");
}
hello.h
#ifndef _HELLO_H_
#define _HELLO_H_

void hello();

#endif //_HELLO_H_
main.c
#include "hello.h"

int main(void)
{
    hello(); // => hello
    return 0;
}

ここではファイルの内容に関して詳しく議論しない.

問題となる点はこれがデフォルトの設定では意図したようにコンパイル&実行されないことである.

デフォルトの設定では次のようにコンパイル時のエラーが出力される.

要するに,helloという関数が定義されてないからどうしたらいいのかわからないといったところである.

問題の本質

分割したhello.cがリンクされていないこと

よって,code runnerを実行した時のコンパイルの仕方を変更する必要性がある.

設定の変更

  1. VSCodeの拡張機能からインストールしたcode runnerを検索する.

  2. code runnerjsonファイルを開く.

  3. C/C++の設定を探すとデフォルトでは次の画像のようになっている.

  4. gcc $filenameの部分を*.cに変更する.ついでに,cppも同様にg++ $filename*.cppに変更する.
    つまり,次のように変更する.

settings.json
      "c": "cd $dir && gcc *.c -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
      "cpp": "cd $dir && g++ *.cpp -o $fileNameWithoutExt && $dir$fileNameWithoutExt",

これでファイル分割したC/C++でもcode runnerhello.cもリンクされ正しく実行できる.

注意

ここでの設定はmain.cを実行しているディレクトリにある.cファイルしかリンクされない.

よってサブディレクトリにある.cファイルはリンクされないので当然ながらコンパイルエラーが出力されるだろう.
もしサブディレクトリに存在するファイルもリンクしたいのなら,
find . -name "*.cpp" -type f | xargs g++ ...
などに変更することで無理矢理実行することはできるかもしれないが,これをしたがために意図しない余計なファイルも同時にリンクされ,実行ファイルのサイズが大きくなったり,関数のバッティングが起こってしまうかもしれない.

なので,この方法はあまりおすすめしない.
どうしても楽に実行することを考えるなら,大人しくMakefileなどを書くことを推していきたい.

おそらくWindowsでも設定方法はほとんど同じであろう.