我有一些源文件在多个文件夹中.. 有没有一种方法可以在不用一个一个命名它们的情况下将它们全部编译?
我知道我可以这样说
g++ -o out *.cpp
但是当我尝试的时候
g++ -o out *.cpp folder/*.cpp
我遇到了一个错误。
正确的做法是什么?我知道可以通过Makefile来实现,但是能否直接使用g++完成呢?
我有一些源文件在多个文件夹中.. 有没有一种方法可以在不用一个一个命名它们的情况下将它们全部编译?
我知道我可以这样说
g++ -o out *.cpp
但是当我尝试的时候
g++ -o out *.cpp folder/*.cpp
我遇到了一个错误。
正确的做法是什么?我知道可以通过Makefile来实现,但是能否直接使用g++完成呢?
通过指定 folder/*.cpp
,您告诉 g++ 编译 folder
中的 cpp 文件。这是正确的。
您可能忽略了告诉 g++ 额外文件所在的位置,这些文件被 cpp 文件 #include
。
为此,请告诉编译器也使用 -I
包含该目录,如下所示:
g++ -o out -I ./folder *.cpp folder/*.cpp
有时编译器会忘记根/当前目录中的内容,因此我用另一个-I
手动指定了当前目录.
g++ -o out -I . -I ./folder *.cpp folder/*.cpp
想通了! :) 我不喜欢使用 make 或者构建系统来编译我的代码,但是我想将我的代码分成子文件夹以保持整洁和有组织性。
运行以下命令(将 RootFolderName(例如 .
)和 OutputName 替换为实际值):
g++ -g $(find RootFolderName -type f -iregex ".*\.cpp") -o OutputName
使用find命令进行递归不区分大小写的正则表达式搜索(-iregex)文件(-type f)。将其放入$()中,然后将结果注入到您的g++调用中。太棒了!:)
当然,确保您正在正确使用该命令;您始终可以进行测试运行。
对于那些使用Visual Studio Code编译的人,我必须在带有"command": "g++"任务的tasks.json args: []中执行此操作:
"-g",
"$(find",
"code",
"-type",
"f",
"-iregex",
"'.*\\.cpp')",
"-o",
"program"
< p >(否则它会将< code >$()全部用单引号包裹起来。)
(感谢:user405725 @ https://stackoverflow.com/a/9764119/1599699的评论)
["-g", "$(find", "${fileDirname}", "-type", "f", "-iregex", "'.*\\.cpp')", "-o", "${fileDirname}/${fileBasenameNoExtension}"]
。关键点在于变量fileDirname
表示当前文件的父文件夹,以及fileBasenameNoExtension
表示当前文件的名称(不带扩展名)(在Windows上可能需要添加.exe)。 - Alka我遇到了这个问题,看到了上面的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"
}
如果所有文件都包含自己的主函数,并且它们不是同一个项目/程序的一部分,您可能希望保留它们的原始名称并为每个文件创建一个可执行文件。如果是这种情况,您可以使用 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
变量中。同样地,我们通过system
函数在shell中创建要执行的命令。awk '{n=split(FILENAME, a, "."); command=sprintf("g++ -I . %s -o %s.out", FILENAME, a[n-1]); system(command); nextfile } ' *.cpp
你也可以像@Bit Fracture建议的那样,使用-I
来包含其他文件。
注意:如果任何文件名包含空格或多个点,则此解决方案效果不佳。在执行命令之前,这些字符需要替换为下划线,例如,如此处所述:
find . -type f -name "* *.cpp" -exec bash -c 'mv "$0" "${0// /_}"' {} \;
tasks.json
以构建多个C++文件,而不是使用${file}。 但是,该网站使用CL编译器,当我尝试使用g++时似乎无法正常工作。 - Jonas De Schouwer