如何编译目录中的所有 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// /_}"' {} \;