我想找到一个目录下的所有.c文件,并将它们全部添加到SRC文件中,以便在cmake中编译。如何在CMakeList.txt中完成此操作?对于我可以创建的常规makefile,
SPECIFIED_SRC_FILE = $(foreach d,$(SPECIFIED_SRC_DIRS),$(wildcard $(addprefix $(d)/*,*.c)))
字符串但是我不知道如何在CMakeList.txt中做这样的事情。
ldxq2e6h1#
来点老球球怎么样?
FILE(GLOB MyCSources *.c) ADD_EXECUTABLE(MyExecutable ${MyCSources})
字符串
cetgtptt2#
试试这个:第一个月查找目录中的所有源文件。
AUX_SOURCE_DIRECTORY(dir VARIABLE)
字符串收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。此命令旨在由使用显式模板示例化的项目使用。模板示例化文件可以存储在“Templates”目录中,并使用此命令自动收集,以避免手动列出所有示例化。使用此命令可以避免为库或可执行目标编写源文件列表,这很有吸引力。CMake无法生成知道何时添加了新的源文件的构建系统。通常,生成的构建系统知道何时需要重新编译CMake,因为CMakeLists.txt文件已被修改以添加新的源。当源文件刚刚添加到如果不修改这个文件,就必须手动编译CMake来生成一个包含新文件的构建系统。
vktxenjb3#
GLOB_RECURSE递归示例
GLOB_RECURSE
它基本上使*也进入子目录:
*
cmake_minimum_required(VERSION 3.0) file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.c") add_executable(main ${SOURCES})
字符串然后我们的源可以定位为例如:
src/main.c src/d/a.c src/d/a.h
型main.c使用#include "d/a.h",a.c使用#include "a.h"。在CMake顶层使用GLOB_RECURSE(即"*.c"而不是"src/*.c")可能是一个坏主意,因为它可以拾取由CMake本身生成的.c文件,这些文件放在build/下。可运行示例on GitHub。
main.c
#include "d/a.h"
a.c
#include "a.h"
"*.c"
"src/*.c"
.c
build/
8wigbo564#
1.开发人员已经明确指出这样做是错误的。这应该让你给予暂停。如果你遇到问题,开发人员可能不会接受为你修复它,而是会告诉你列出你的来源。
aux_source_directory
file(GLOB
file(GLOB_RECURSE
CONFIGURE_DEPENDS
**注意:**我们不建议使用GLOB从源代码树中收集源代码文件列表。如果在添加或删除源代码时CMakeLists.txt文件未发生更改,则生成的构建系统无法知道何时要求CMake重新生成。CONFIGURE_DEPENDS标志可能无法在所有生成器上可靠地工作,或者如果将来添加了无法支持它的新生成器,则使用它的项目将被卡住。即使CONFIGURE_DEPENDS可靠地工作,在每次重新生成时执行检查仍然会产生成本。
plicqrtu5#
是的,你有两个选择.让我们假设你的文件夹结构类似于此.
├── autopilot │ ├── _AutoPilot.cpp │ ├── _AutoPilot.h │ └── action │ ├── ActionBase.cpp │ ├── ActionBase.h │ ├── APcopter │ │ ├── APcopter_avoid.cpp │ │ ├── APcopter_avoid.h
字符串如果你要使用AUX_SOURCE_DIRECTORY,你必须添加CMakeLists.txt的每一个子目录。然后你必须包括和链接所有这些子目录。这是一个相当困难的任务。所以你可以你GLOB和做这项工作很容易。这是如何完成的。
AUX_SOURCE_DIRECTORY
file(GLOB autopilot_sources ./**.cpp ./**.c) SET( autopilot ${autopilot_sources})
型如果你想使用上面的源代码创建一个库,这是命令:
ADD_LIBRARY ( autopilot ${autopilot_sources}) TARGET_LINK_LIBRARIES ( autopilot)
型如果你想使用上面的源代码创建一个可执行文件,这是命令:
ADD_EXECUTABLE(autopilot ${autopilot_sources})
型
r8xiu3jd6#
你可以像@whitequark描述的那样使用AUX_SOURCE_DIRECTORY,但它不会像你期望的那样工作,因为CMake将无法确定何时添加新文件(这是使用一个JavaScript的全部要点)。
6条答案
按热度按时间ldxq2e6h1#
来点老球球怎么样?
字符串
cetgtptt2#
试试这个:
第一个月
查找目录中的所有源文件。
字符串
收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。此命令旨在由使用显式模板示例化的项目使用。模板示例化文件可以存储在“Templates”目录中,并使用此命令自动收集,以避免手动列出所有示例化。
使用此命令可以避免为库或可执行目标编写源文件列表,这很有吸引力。CMake无法生成知道何时添加了新的源文件的构建系统。通常,生成的构建系统知道何时需要重新编译CMake,因为CMakeLists.txt文件已被修改以添加新的源。当源文件刚刚添加到如果不修改这个文件,就必须手动编译CMake来生成一个包含新文件的构建系统。
vktxenjb3#
GLOB_RECURSE
递归示例它基本上使
*
也进入子目录:字符串
然后我们的源可以定位为例如:
型
main.c
使用#include "d/a.h"
,a.c
使用#include "a.h"
。在CMake顶层使用
GLOB_RECURSE
(即"*.c"
而不是"src/*.c"
)可能是一个坏主意,因为它可以拾取由CMake本身生成的.c
文件,这些文件放在build/
下。可运行示例on GitHub。
8wigbo564#
1.开发人员已经明确指出这样做是错误的。这应该让你给予暂停。如果你遇到问题,开发人员可能不会接受为你修复它,而是会告诉你列出你的来源。
aux_source_directory
函数是完全错误的,因为它不能检测文件系统中的更改。出于同样的原因,使用file(GLOB
或file(GLOB_RECURSE
而不使用CONFIGURE_DEPENDS
是完全错误的。CONFIGURE_DEPENDS
不能保证工作。(参见第1点)1.事实上,在Ninja 1.10.2之前,它在Windows上存在错误。
1.它还中断了试运行工作流,因为glob检查在父构建中运行,而子(真实的)构建是递归调用的。
1.如果globbing失败,您将很难找出添加或删除了哪些额外的源文件。
1.当执行git平分、切换分支或执行其他源代码控制操作时,Globbing特别可能失败,这些操作会将文件时间戳向后移动。
解释你的来源。
1以下是CMake开发人员对此的看法:
**注意:**我们不建议使用GLOB从源代码树中收集源代码文件列表。如果在添加或删除源代码时CMakeLists.txt文件未发生更改,则生成的构建系统无法知道何时要求CMake重新生成。
CONFIGURE_DEPENDS
标志可能无法在所有生成器上可靠地工作,或者如果将来添加了无法支持它的新生成器,则使用它的项目将被卡住。即使CONFIGURE_DEPENDS
可靠地工作,在每次重新生成时执行检查仍然会产生成本。plicqrtu5#
是的,你有两个选择.让我们假设你的文件夹结构类似于此.
字符串
如果你要使用
AUX_SOURCE_DIRECTORY
,你必须添加CMakeLists.txt的每一个子目录。然后你必须包括和链接所有这些子目录。这是一个相当困难的任务。所以你可以你GLOB和做这项工作很容易。这是如何完成的。型
如果你想使用上面的源代码创建一个库,这是命令:
型
如果你想使用上面的源代码创建一个可执行文件,这是命令:
型
r8xiu3jd6#
你可以像@whitequark描述的那样使用
AUX_SOURCE_DIRECTORY
,但它不会像你期望的那样工作,因为CMake将无法确定何时添加新文件(这是使用一个JavaScript的全部要点)。