如何在Cmake构建系统中使用目录中的所有 *.c文件?

vs91vp4v  于 12个月前  发布在  其他
关注(0)|答案(6)|浏览(121)

我想找到一个目录下的所有.c文件,并将它们全部添加到SRC文件中,以便在cmake中编译。如何在CMakeList.txt中完成此操作?
对于我可以创建的常规makefile,

SPECIFIED_SRC_FILE  = $(foreach d,$(SPECIFIED_SRC_DIRS),$(wildcard $(addprefix $(d)/*,*.c)))

字符串
但是我不知道如何在CMakeList.txt中做这样的事情。

ldxq2e6h

ldxq2e6h1#

来点老球球怎么样?

FILE(GLOB MyCSources *.c)
ADD_EXECUTABLE(MyExecutable ${MyCSources})

字符串

cetgtptt

cetgtptt2#

试试这个:
第一个月
查找目录中的所有源文件。

AUX_SOURCE_DIRECTORY(dir VARIABLE)

字符串
收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。此命令旨在由使用显式模板示例化的项目使用。模板示例化文件可以存储在“Templates”目录中,并使用此命令自动收集,以避免手动列出所有示例化。
使用此命令可以避免为库或可执行目标编写源文件列表,这很有吸引力。CMake无法生成知道何时添加了新的源文件的构建系统。通常,生成的构建系统知道何时需要重新编译CMake,因为CMakeLists.txt文件已被修改以添加新的源。当源文件刚刚添加到如果不修改这个文件,就必须手动编译CMake来生成一个包含新文件的构建系统。

vktxenjb

vktxenjb3#

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

8wigbo56

8wigbo564#

  • 唯一的 * 正确答案是 * 不要这样做 *。这在SO上的multipleanswers中有详细说明。我将在这里总结,按重要性递减。

1.开发人员已经明确指出这样做是错误的。这应该让你给予暂停。如果你遇到问题,开发人员可能不会接受为你修复它,而是会告诉你列出你的来源。

  1. aux_source_directory函数是完全错误的,因为它不能检测文件系统中的更改。出于同样的原因,使用file(GLOBfile(GLOB_RECURSE而不使用CONFIGURE_DEPENDS是完全错误的。
  2. CONFIGURE_DEPENDS不能保证工作。(参见第1点)
    1.事实上,在Ninja 1.10.2之前,它在Windows上存在错误。
    1.它还中断了试运行工作流,因为glob检查在父构建中运行,而子(真实的)构建是递归调用的。
    1.如果globbing失败,您将很难找出添加或删除了哪些额外的源文件。
  3. Globbing,尤其是递归globbing,可能会很慢,而且文件越多,情况就越糟。Ext4的性能通常可以接受,但Ext4的性能很差,尤其是通过Linux驱动程序。请参阅:https://github.com/alexreinking/cmake-glob-performance/
    1.当执行git平分、切换分支或执行其他源代码控制操作时,Globbing特别可能失败,这些操作会将文件时间戳向后移动。
    解释你的来源。
    1以下是CMake开发人员对此的看法:

**注意:**我们不建议使用GLOB从源代码树中收集源代码文件列表。如果在添加或删除源代码时CMakeLists.txt文件未发生更改,则生成的构建系统无法知道何时要求CMake重新生成。CONFIGURE_DEPENDS标志可能无法在所有生成器上可靠地工作,或者如果将来添加了无法支持它的新生成器,则使用它的项目将被卡住。即使CONFIGURE_DEPENDS可靠地工作,在每次重新生成时执行检查仍然会产生成本。

plicqrtu

plicqrtu5#

是的,你有两个选择.让我们假设你的文件夹结构类似于此.

├── autopilot
            │   ├── _AutoPilot.cpp
            │   ├── _AutoPilot.h
            │   └── action
            │       ├── ActionBase.cpp
            │       ├── ActionBase.h
            │       ├── APcopter
            │       │   ├── APcopter_avoid.cpp
            │       │   ├── APcopter_avoid.h

字符串
如果你要使用AUX_SOURCE_DIRECTORY,你必须添加CMakeLists.txt的每一个子目录。然后你必须包括和链接所有这些子目录。这是一个相当困难的任务。所以你可以你GLOB和做这项工作很容易。这是如何完成的。

file(GLOB autopilot_sources ./**.cpp ./**.c)
  SET( autopilot ${autopilot_sources})


如果你想使用上面的源代码创建一个库,这是命令:

ADD_LIBRARY ( autopilot  ${autopilot_sources})
  TARGET_LINK_LIBRARIES ( autopilot)


如果你想使用上面的源代码创建一个可执行文件,这是命令:

ADD_EXECUTABLE(autopilot ${autopilot_sources})

r8xiu3jd

r8xiu3jd6#

你可以像@whitequark描述的那样使用AUX_SOURCE_DIRECTORY,但它不会像你期望的那样工作,因为CMake将无法确定何时添加新文件(这是使用一个JavaScript的全部要点)。

相关问题