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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:18:04  来源:igfitidea点击:

Automatically add all files in a folder to a target using CMake?

c++cross-platformcmake

提问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 cmakeif 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 Makefilemanually, you might generate a SRCSvariable using a function to select all .cppand .hfiles. If a source file is later added, re-running makewill 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 Makefileby 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")