VSCodeで複数のCファイルをコンパイルしてリンクする方法
最近、ZYNQのプログラムをVSCodeで書いてarm-elf-gccでコンパイルまでするようにしています。
小さなプログラムなら下記のようなtasks.jsonを書いて、CTRL+SHIFT+B一発でコンパイルできてよかったのですが、
{
// tasks.json 形式の詳細についての資料は、
// https://go.microsoft.com/fwlink/?LinkId=733558 をご覧ください
"version": "2.0.0",
"tasks": [
{
"label": "Deploy", //①ビルド後にターゲットボードへコピーする
"type": "shell",
"command": "cp",
"args": [
"${fileDirname}/${fileBasenameNoExtension}",
"//cosmoz/Share" //コピー先のターゲットボードのホスト名とフォルダ名
],
"problemMatcher": [],
"dependsOn": "Build by ARM g++",
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "shell",
"label": "Build by ARM g++",
"command": "D:/Xilinx/SDK/2018.3/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++.exe",
"args": [
"-g",
"[${file}]",
"-L${workspaceFolder}",
"-I../cszapi/src", //ライブラリのインクルードディレクトリ
"-L../cszapi/Debug", //ライブラリのあるフォルダ
"-lcszapi", //ライブラリ名
"-o",
"${fileDirname}\\${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
これだと、現在編集中のファイルをgccでコンパイルして実行ファイルを作るので、プログラムを複数のファイルに分割した場合には対応していません。
ですが、プログラムがだんだん大きくなってきてくるとソースを複数に分割する必要が出てきました。
「VSCode C ファイル 複数」のようなキーワードで検索しても出てこないのですが、基本的にはcmakeを使うかべた書きするしかないようです。実際にVSCodeのcmake extensionを入れて試してみたのですが、cmakeが呼び出すmakeがborlandのmakeを呼び出してしまったり、cmakeの環境構築中に動くサンプルのビルドに失敗します。
cmake extensionを入れれば誰の環境でも同じように使えるというわけではなさそうです。
そこで、ベタベタに書く方法を試してみました。
次のtasks.jsonは、もともとcszserver.cppというファイルがあったのを、cszserver.cpp、eventcap.cpp、uppmca.cppに分割しています。
{
// tasks.json 形式の詳細についての資料は、
// https://go.microsoft.com/fwlink/?LinkId=733558 をご覧ください
"version": "2.0.0",
"tasks": [
{
"label": "Deploy",
"type": "shell",
"command": "cp",
"args": [
"${fileDirname}/cszserver", // コピーしたい実行ファイル名を直接書く
"//cosmoz/Share"
],
"problemMatcher": [],
"dependsOn": "Build by ARM g++",
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "shell",
"label": "Build by ARM g++",
"command": "D:/Xilinx/SDK/2018.3/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++.exe",
"args": [
"-g",
"${workspaceFolder}/cszserver.cpp", // 分割したソースファイル名を直接書く
"${workspaceFolder}/eventcap.cpp", // 分割したソースファイル名を直接書く
"${workspaceFolder}/uppmca.cpp", // 分割したソースファイル名を直接書く
"-L${workspaceFolder}",
"-I../cszapi/src",
"-L../cszapi/Debug",
"-lcszapi",
"-o",
"${fileDirname}/cszserver" // 作りたい実行ファイル名を直接書く
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
これで、3つのファイルをコンパイルしてリンクしてくれるようになりました。
さらに一方進めて、ファイルごとに分割してコンパイルするようにしてみました。
{
// tasks.json 形式の詳細についての資料は、
// https://go.microsoft.com/fwlink/?LinkId=733558 をご覧ください
"version": "2.0.0",
"tasks": [
{
"label": "Deploy",
"type": "shell",
"command": "cp",
"args": [
"${fileDirname}/cszserver",
"//cosmoz/Share"
],
"problemMatcher": [],
"dependsOn": "Link",
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Link",
"type": "shell",
"command": "D:/Xilinx/SDK/2018.3/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++.exe",
"args": [
"${workspaceFolder}/cszserver.o",
"${workspaceFolder}/eventcap.o",
"${workspaceFolder}/uppmca.o",
"-L${workspaceFolder}",
"-L../cszapi/Debug",
"-lcszapi",
"-o",
"${fileDirname}/cszserver"
],
"problemMatcher": [],
"dependsOn": "Build by ARM g++",
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "build",
}
},
{
"type": "shell",
"label": "Build by ARM g++",
"command": "D:/Xilinx/SDK/2018.3/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++.exe",
"args": [
"-g",
"-c",
"${file}",
"-I../cszapi/src",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.o"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
dependsOnとLabelを利用して、DeployというタスクがLinkに依存するよーうに、LinkがBuild by ARM g++に依存するようにしています。これで、一番上にあるDeployを起動しようとすると、編集中のファイルをコンパイルして.oを作り、3つの.oをリンクして実行ファイルを作ってコピーするようになりました。
ただし、すべての.oを個別に作ってあげないとリンク時にmissingになってしまうので、まだ完璧ではありません。
さらに完成度を上げるには、タイムスタンプでコンパイルするべきか否かを判断するような書き方を調べる必要があると思います。
| 固定リンク
コメント
VSCodeでLinuxでの複数フォルダの結合したDebug実行(ブレークポイントを張って)をしてみたいのですがうまくいかないです。
単体ファイルでは、できるのですが。
Makefileを複数作るようなイメージでtasks.jsonや、lnch.jsonも階層ごとに必要なのでしょうか?
make時に、-g -O0オプションをしたも実行ファイルを、実行したときに、
ターミナルから、関数を -b aaaFuncを指定して停止するものをVSCodeでもデバッグ実行でできるようにしたいのですが、難しいでしょうか?
投稿: | 2023.02.24 14:29