在CMake中添加多个可执行文件

ssb*_*ssb 62 c++ executable build cmake

我在C++项目中的代码组织如下

  • 我有几个.cpp.h文件,其中包含我的班
  • 我有几个.cxx文件必须针对.cpp文件和一些外部库进行编译.

现在,每个.cxx文件都有一个main()方法,所以我需要为这些文件中的每个文件添加一个不同的可执行文件.

此外,这些.cxx文件可能无法链接到相同的外部库.

我想在CMake中编写这个版本,我是一个新手,我该如何解决这个问题?

And*_*dré 93

我的建议是分两个阶段解决这个问题:

  1. 使用.cpp和从.h文件构建库add_library
  2. 遍历所有.cxx文件并使用add_executable和创建每个文件的可执行文件foreach

建立图书馆

这可能很简单

file( GLOB LIB_SOURCES lib/*.cpp )
file( GLOB LIB_HEADERS lib/*.h )
add_library( YourLib ${LIB_SOURCES} ${LIB_HEADERS} )
Run Code Online (Sandbox Code Playgroud)

构建所有可执行文件

只需遍历所有.cpp文件并创建单独的可执行文件.

# If necessary, use the RELATIVE flag, otherwise each source file may be listed 
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
# file( GLOB APP_SOURCES RELATIVE app/*.cxx )
file( GLOB APP_SOURCES app/*.cxx )
foreach( testsourcefile ${APP_SOURCES} )
    # I used a simple string replace, to cut off .cpp.
    string( REPLACE ".cpp" "" testname ${testsourcefile} )
    add_executable( ${testname} ${testsourcefile} )
    # Make sure YourLib is linked to each app
    target_link_libraries( ${testname} YourLib )
endforeach( testsourcefile ${APP_SOURCES} )
Run Code Online (Sandbox Code Playgroud)

一些警告:

  • file( GLOB )通常不推荐使用,因为如果添加新文件,CMake将不会自动重建.我在这里使用它,因为我不知道你的源文件.
  • 在某些情况下,可以使用完整路径名找到源文件.如有必要,请使用RELATIVE标志find( GLOB ... ).
  • 手动设置源文件需要更改CMakeLists.txt,这会触发重建.关于globbing的(dis-)优点,请参阅此问题.
  • 我使用a生成了testname string( REPLACE ... ).我本可以使用带标志的get_filename_componentNAME_WE.

关于"一般"CMake信息,我建议您阅读stackoverflow上已经提到的一些广泛的"CMake概述"问题.例如:

  • 如果您使用的是较新的 cmake(3.0.2 是我发现的最早的),您可以使用 [`get_filename_component(testname ${testsourcefile} NAME_WE)`](https://cmake.org/cmake/help /latest/command/get_filename_component.html) 而不是使用 `string(REPLACE...`。优点是这也将删除路径的其余部分,如果你使用 `EXECUTABLE_OUTPUT_PATH` 来设置二进制文件的位置,这很方便走。 (3认同)

rbe*_*nto 7

当我组织一个包含多个示例文件的 OpenGL 项目时,我发现自己处于类似的情况,其中每个文件都包含一个 main 方法。

\n

下面的设置将为每个 c/cpp 文件生成一个单独的可执行文件,并将所需的依赖项复制到目标 bin 文件夹。

\n

文件夹结构

\n
my-project\n\xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 ch01_01.c\n\xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 ch02_01.cpp\n\xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 Resources\n\xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 Libraries\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 glew\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 glfw    \n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 include \n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82\xe2\x94\x80\xe2\x94\x80 lib \n
Run Code Online (Sandbox Code Playgroud)\n

CMakeLists.txt

\n
cmake_minimum_required (VERSION 3.9)\n\nproject ("my-project")\n\ninclude_directories(Resources/Libraries/glew/include\n                    Resources/Libraries/glfw/include)\n\nlink_directories(Resources/Libraries/glew/lib\n                 Resources/Libraries/glfw/lib)\n\nlink_libraries(opengl32.lib\n               glew32.lib\n               glfw3.lib)\n\nset(CMAKE_EXE_LINKER_FLAGS "/NODEFAULTLIB:MSVCRT")\n\nfile(GLOB SOURCE_FILES *.c *.cpp)\n\nforeach(SOURCE_PATH ${SOURCE_FILES})\n\n    get_filename_component(EXECUTABLE_NAME ${SOURCE_PATH} NAME_WE)\n\n    add_executable(${EXECUTABLE_NAME} ${SOURCE_PATH})\n\n    # Copy required DLLs to the target folder\n    add_custom_command(TARGET ${EXECUTABLE_NAME} POST_BUILD\n                       COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/Resources/Libraries/glew/bin/glew32.dll" \n                                                                     "${CMAKE_BINARY_DIR}/glew32.dll")\n\nendforeach(SOURCE_PATH ${SOURCE_FILES})\n
Run Code Online (Sandbox Code Playgroud)\n

可选步骤

\n

在视觉工作室中

\n
    \n
  • 使用“开始”窗口中的“打开本地文件夹”选项打开项目

    \n
  • \n
  • 添加新文件时,您可以:

    \n
      \n
    • 取消对话框要求自动add_executable到CMakeLists.txt
    • \n
    • 通过取消选中“从文件夹视图为文件操作启用自动 CMake 脚本修改”来禁用此行为Tools > Options > CMake
    • \n
    \n
  • \n
\n

由于新添加的文件不会自动获取,因为 CMakeLists.txt 从未更改,因此只需重新生成缓存,如下所示:

\n
    \n
  • Project > CMake Cache (x64-Debug) > Delete Cache
  • \n
  • Project > Generate Cache for my-project
  • \n
\n

现在,您只需右键单击给定的 c/cpp 文件Set as Startup Item即可使用F5.

\n

环境

\n
    \n
  • cmake 版本 3.18.20081302-MSVC_2
  • \n
  • Microsoft Visual Studio 社区 2019 版本 16.8.3
  • \n
\n

入门模板

\n

我在 GitHub 上整理了这个入门模板,以防您感兴趣。

\n