C++ 使用 CMake 自动将文件夹中的所有文件添加到目标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3201154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Automatically add all files in a folder to a target using CMake?
提问by martjno
I am considering switching a cross platform project from separate build management systems in Visual C++, XCode and makefiles to CMake.
我正在考虑将跨平台项目从 Visual C++、XCode 和 makefile 中的单独构建管理系统切换到 CMake。
One essential feature I need is to add automatically all files in a directory to a target. While this is easy to do with make, it is not easily doable with Visual C++ and XCode (correct me if I am wrong). Is it possible to do it in directly in CMake? How?
我需要的一项基本功能是自动将目录中的所有文件添加到目标。虽然这很容易用 make 做到,但用 Visual C++ 和 XCode 却不容易做到(如果我错了,请纠正我)。是否可以直接在 CMake 中完成?如何?
回答by Kleist
It is possible. E.g. with file(GLOB
:
有可能的。例如file(GLOB
:
cmake_minimum_required(VERSION 2.8)
file(GLOB helloworld_SRC
"*.h"
"*.cpp"
)
add_executable(helloworld ${helloworld_SRC})
Note that this requires manualre-running of cmake
if a source file is added or removed, since the generated build system does not know when to ask CMake to regenerate, and doing it at every build would increase the build time.
请注意,如果添加或删除源文件,这需要手动重新运行cmake
,因为生成的构建系统不知道何时要求 CMake 重新生成,并且在每次构建时都这样做会增加构建时间。
回答by kara deniz
The answer by Kleist certainly works, but there is an important caveat:
克莱斯特的答案当然有效,但有一个重要的警告:
When you write a Makefile
manually, you might generate a SRCS
variable using a function to select all .cpp
and .h
files. If a source file is later added, re-running make
will include it.
当你写一个Makefile
手动,你可能会产生一个SRCS
使用功能选择所有变量.cpp
和.h
文件。如果稍后添加了源文件,则重新运行make
将包括它。
However, CMake (with a command like file(GLOB ...)
) will explicitly generate a file list and place it in the auto-generated Makefile
. If you have a new source file, you will need to re-generate the Makefile
by re-running cmake
.
但是,CMake(使用类似 的命令file(GLOB ...)
)将显式生成文件列表并将其放置在自动生成的Makefile
. 如果您有新的源文件,则需要Makefile
通过重新运行cmake
.
edit: No need to remove the Makefile.
编辑:无需删除 Makefile。
回答by Tsyvarev
Extensionfor @Kleist answer:
扩展为@Kleist答案:
Since CMake 3.12 additional option CONFIGURE_DEPENDSis supportedby commands file(GLOB)
and file(GLOB_RECURSE)
. With this option there is no needsto manuallyre-run CMake after addition/deletion of a source file in the directory - CMake will be re-run automatically on next building the project.
由于CMake的3.12附加选项CONFIGURE_DEPENDS是支持通过命令file(GLOB)
和file(GLOB_RECURSE)
。使用此选项有没有需要以手动添加/删除目录中的源文件后重新运行cmake - CMake的将是重新运行在未来建设项目自动。
However, the option CONFIGURE_DEPENDSimplies that corresponding directory will be re-checked every time building is requested, so buildprocess would consume more timethan without CONFIGURE_DEPENDS.
但是,选项CONFIGURE_DEPENDS意味着每次请求构建时都会重新检查相应的目录,因此构建过程将比没有CONFIGURE_DEPENDS花费更多的时间。
Even with CONFIGURE_DEPENDSoption available CMake documentation still does not recommendusing file(GLOB)
or file(GLOB_RECURSE)
for collect the sources.
即使有CONFIGURE_DEPENDS选项可用,CMake 文档仍然不建议使用file(GLOB)
或file(GLOB_RECURSE)
收集源。
回答by alcoforado
So Why not use powershell to create the list of source files for you. Take a look at this script
那么为什么不使用 powershell 为您创建源文件列表。看看这个脚本
param (
[Parameter(Mandatory=$True)]
[string]$root
)
if (-not (Test-Path -Path $root)) {
throw "Error directory does not exist"
}
#get the full path of the root
$rootDir = get-item -Path $root
$fp=$rootDir.FullName;
$files = Get-ChildItem -Path $root -Recurse -File |
Where-Object { ".cpp",".cxx",".cc",".h" -contains $_.Extension} |
Foreach {$_.FullName.replace("${fp}\","").replace("\","/")}
$CMakeExpr = "set(SOURCES "
foreach($file in $files){
$CMakeExpr+= """$file"" " ;
}
$CMakeExpr+=")"
return $CMakeExpr;
Suppose you have a folder with this structure
假设您有一个具有这种结构的文件夹
C:\Workspace\A
--a.cpp
C:\Workspace\B
--b.cpp
Now save this file as "generateSourceList.ps1" for example, and run the script as
例如,现在将此文件保存为“generateSourceList.ps1”,然后将脚本运行为
~>./generateSourceList.ps1 -root "C:\Workspace" > out.txt
out.txt file will contain
out.txt 文件将包含
set(SOURCE "A/a.cpp" "B/b.cpp")