如何编译目录中的所有 cpp 文件?
How can you compile all cpp files in a directory?
我在很多文件夹中有很多源文件。.有没有办法一次性编译所有这些文件而不必命名它们?
我知道我可以说
g++ -o out *.cpp
但是当我尝试
g++ -o out *.cpp folder/*.cpp
我收到一个错误。
正确的做法是什么?我知道使用 makefile 是可行的,但是可以直接使用 g++ 来完成吗?
通过指定 folder/*.cpp
,您告诉 g++ 在 folder
中编译 cpp 文件。没错。
您可能缺少的是告诉 g++ 在哪里可以找到那些 cpp 文件 #include
的其他文件。
为此,请告诉您的编译器也 include
带有 -I
的目录,如下所示:
g++ -o out -I ./folder *.cpp folder/*.cpp
在某些情况下,我让编译器忘记了 root/current 目录中的内容,所以我用另一个 -I
手动将其指定到当前目录 .
g++ -o out -I . -I ./folder *.cpp folder/*.cpp
想通了! :) 我讨厌必须使用 make 或构建系统来编译我的代码的想法,但我想将我的代码拆分到子文件夹中以保持其整洁有序。
运行 这个(替换 RootFolderName(例如用 .
)和 OutputName):
g++ -g $(find RootFolderName -type f -iregex ".*\.cpp") -o OutputName
查找命令将对文件 (-type f
) 进行递归的不区分大小写的正则表达式搜索 (-iregex
)。将其放在 $()
中,然后会将结果注入到您的 g++
调用中。美丽的! :)
当然,请确保您使用的命令正确;你总是可以做一个测试 运行.
对于那些使用 Visual Studio 代码进行编译的人,我必须在 tasks.json args: []
任务中使用 "command": "g++"
:
执行此操作
"-g",
"$(find",
"code",
"-type",
"f",
"-iregex",
"'.*\.cpp')",
"-o",
"program"
(否则它会将 $()
全部用单引号引起来。)
(感谢:user405725 @ 评论)
所以我 运行 看到了上面的 vscode 任务,并管理了一个不同的解决方案。这将从同一目录中获取所有头文件和 c 文件。然后将使用 F5 键。
tasks.json
{
"tasks": [
{
"type": "shell",
"label": "C/C++: gcc-7 build active file",
"command": "/usr/bin/gcc-7",
"args": [
"-I",
"${fileDirname}",
"-g",
"${fileDirname}/*.c",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
],
"version": "2.0.0"
}
如果所有文件都包含自己的主文件并且不存在相同的部分 project/program,您可能希望保留它们的原始名称并为每个文件创建一个可执行文件。如果是这种情况,您可以使用 awk
:
awk '{n=split(FILENAME, a, "."); outfile=sprintf("%s.out",a[n-1]); command=sprintf("g++ -I . %s -o %s", FILENAME, outfile); system(command); nextfile } ' *.cpp
首先,您使用 split
分隔文件名和扩展名,并将结果存储到数组 a
中。基本名称位于索引 n-1
,扩展名位于索引 n
。因此,我们将扩展名更改为 .out
并使用 sprintf
存储到 outfile
变量中。同样的,我们在shell.
中创建system
函数执行的命令
上述命令的最短版本是:
awk '{n=split(FILENAME, a, "."); command=sprintf("g++ -I . %s -o %s.out", FILENAME, a[n-1]); system(command); nextfile } ' *.cpp
您还可以按照@Bit Fracture 的建议将命令修改为 #include
附加文件 -I
。
注意:如果任何文件名包含 space 或多个点,则此解决方案效果不佳。在执行命令之前,这些字符需要用下划线替换,例如 here:
find . -type f -name "* *.cpp" -exec bash -c 'mv "[=12=]" "${0// /_}"' {} \;
我在很多文件夹中有很多源文件。.有没有办法一次性编译所有这些文件而不必命名它们?
我知道我可以说
g++ -o out *.cpp
但是当我尝试
g++ -o out *.cpp folder/*.cpp
我收到一个错误。
正确的做法是什么?我知道使用 makefile 是可行的,但是可以直接使用 g++ 来完成吗?
通过指定 folder/*.cpp
,您告诉 g++ 在 folder
中编译 cpp 文件。没错。
您可能缺少的是告诉 g++ 在哪里可以找到那些 cpp 文件 #include
的其他文件。
为此,请告诉您的编译器也 include
带有 -I
的目录,如下所示:
g++ -o out -I ./folder *.cpp folder/*.cpp
在某些情况下,我让编译器忘记了 root/current 目录中的内容,所以我用另一个 -I
手动将其指定到当前目录 .
g++ -o out -I . -I ./folder *.cpp folder/*.cpp
想通了! :) 我讨厌必须使用 make 或构建系统来编译我的代码的想法,但我想将我的代码拆分到子文件夹中以保持其整洁有序。
运行 这个(替换 RootFolderName(例如用 .
)和 OutputName):
g++ -g $(find RootFolderName -type f -iregex ".*\.cpp") -o OutputName
查找命令将对文件 (-type f
) 进行递归的不区分大小写的正则表达式搜索 (-iregex
)。将其放在 $()
中,然后会将结果注入到您的 g++
调用中。美丽的! :)
当然,请确保您使用的命令正确;你总是可以做一个测试 运行.
对于那些使用 Visual Studio 代码进行编译的人,我必须在 tasks.json args: []
任务中使用 "command": "g++"
:
"-g",
"$(find",
"code",
"-type",
"f",
"-iregex",
"'.*\.cpp')",
"-o",
"program"
(否则它会将 $()
全部用单引号引起来。)
(感谢:user405725 @ 评论)
所以我 运行 看到了上面的 vscode 任务,并管理了一个不同的解决方案。这将从同一目录中获取所有头文件和 c 文件。然后将使用 F5 键。
tasks.json
{
"tasks": [
{
"type": "shell",
"label": "C/C++: gcc-7 build active file",
"command": "/usr/bin/gcc-7",
"args": [
"-I",
"${fileDirname}",
"-g",
"${fileDirname}/*.c",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
],
"version": "2.0.0"
}
如果所有文件都包含自己的主文件并且不存在相同的部分 project/program,您可能希望保留它们的原始名称并为每个文件创建一个可执行文件。如果是这种情况,您可以使用 awk
:
awk '{n=split(FILENAME, a, "."); outfile=sprintf("%s.out",a[n-1]); command=sprintf("g++ -I . %s -o %s", FILENAME, outfile); system(command); nextfile } ' *.cpp
首先,您使用 split
分隔文件名和扩展名,并将结果存储到数组 a
中。基本名称位于索引 n-1
,扩展名位于索引 n
。因此,我们将扩展名更改为 .out
并使用 sprintf
存储到 outfile
变量中。同样的,我们在shell.
system
函数执行的命令
上述命令的最短版本是:
awk '{n=split(FILENAME, a, "."); command=sprintf("g++ -I . %s -o %s.out", FILENAME, a[n-1]); system(command); nextfile } ' *.cpp
您还可以按照@Bit Fracture 的建议将命令修改为 #include
附加文件 -I
。
注意:如果任何文件名包含 space 或多个点,则此解决方案效果不佳。在执行命令之前,这些字符需要用下划线替换,例如 here:
find . -type f -name "* *.cpp" -exec bash -c 'mv "[=12=]" "${0// /_}"' {} \;