在 CMake 中添加多个可执行文件
Posted
技术标签:
【中文标题】在 CMake 中添加多个可执行文件【英文标题】:Adding multiple executables in CMake 【发布时间】:2012-12-27 17:11:22 【问题描述】:我在一个 C++ 项目中的代码组织如下
我有几个.cpp
和 .h
文件,其中包含我的课程
我有几个 .cxx
文件必须针对 .cpp
文件和一些外部库进行编译。
现在,每个.cxx
文件都有一个main()
方法,所以我需要为每个与文件同名的文件添加不同的可执行文件。
此外,这些.cxx
文件可能不会链接到相同的外部库。
我想在 CMake 中编写这个构建,我是一个新手,我该怎么做?
【问题讨论】:
【参考方案1】:我的建议是分两个阶段解决这个问题:
-
从
.cpp
和.h
文件构建一个库,使用add_library
遍历所有.cxx
文件并使用add_executable
和foreach
从每个文件创建一个可执行文件
构建库
这可能很简单
file( GLOB LIB_SOURCES lib/*.cpp )
file( GLOB LIB_HEADERS lib/*.h )
add_library( YourLib $LIB_SOURCES $LIB_HEADERS )
构建所有可执行文件
只需遍历所有 .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 )
一些警告:
file( GLOB )
通常不推荐,因为如果添加新文件,CMake 不会自动重建。我在这里使用它,因为我不知道你的源文件。
在某些情况下,可以找到带有完整路径名的源文件。如有必要,请使用RELATIVE flag for find( GLOB ... )
。
手动设置源文件需要更改 CMakeLists.txt,这会触发重建。请参阅 this question 了解通配符的(不利)优势。
我使用string( REPLACE ... )
生成了测试名称。我可以将get_filename_component 与NAME_WE
标志一起使用。
关于“一般”CMake 信息,我建议您阅读一些已在 *** 上提出的广泛的“CMake 概述”问题。例如:
CMake tutorial What are the dusty corners a newcomer to CMake will want to know?【讨论】:
+1 不错的答案。可执行文件会全部构建到同一个***build/
目录中,还是会尊重底层源代码树的目录结构?另见this question
我没有测试过,但假设它会在类似于 source-dir 的目录结构中生成可执行文件。无耻插件:看看***.com/questions/13556885如何修改输出路径...
如果你使用较新的cmake(3.0.2是我发现的最早的),你可以使用get_filename_component(testname $testsourcefile NAME_WE)
而不是string(REPLACE...
来获取文件名。好处是这也会删除路径的其余部分,如果您使用EXECUTABLE_OUTPUT_PATH
设置二进制文件的位置,这很方便。
@André 有什么替代 file( GLOB APP_SOURCES app/*.cxx )
在使用它之前,我必须进行相当多的修改。我的配置如下:file( GLOB APP_SOURCES $CMAKE_CURRENT_SOURCE_DIR/*.cpp ) foreach( sourcefile $APP_SOURCES ) file(RELATIVE_PATH filename $CMAKE_CURRENT_SOURCE_DIR $sourcefile) string( REPLACE ".cpp" "" file $filename ) add_executable( $file $sourcefile ) target_link_libraries( $file ndn-cxx boost_system ) endforeach( sourcefile $APP_SOURCES )
【参考方案2】:
我发现自己在组织一个包含多个示例文件的 OpenGL 项目时遇到了类似的情况,其中每个文件都包含一个 main 方法。
以下设置将为每个 c/cpp 文件生成一个单独的可执行文件,并将所需的依赖项复制到目标 bin 文件夹。
文件夹结构
my-project
│── ch01_01.c
│── ch02_01.cpp
│── CMakeLists.txt
│── Resources
│ │── Libraries
│ │ │── glew
│ │ │ │── bin
│ │ │ │── include
│ │ │ │── lib
│ │ │── glfw
│ │ │ │── include
│ │ │ │── lib
CMakeLists.txt
cmake_minimum_required (VERSION 3.9)
project ("my-project")
include_directories(Resources/Libraries/glew/include
Resources/Libraries/glfw/include)
link_directories(Resources/Libraries/glew/lib
Resources/Libraries/glfw/lib)
link_libraries(opengl32.lib
glew32.lib
glfw3.lib)
set(CMAKE_EXE_LINKER_FLAGS "/NODEFAULTLIB:MSVCRT")
file(GLOB SOURCE_FILES *.c *.cpp)
foreach(SOURCE_PATH $SOURCE_FILES)
get_filename_component(EXECUTABLE_NAME $SOURCE_PATH NAME_WE)
add_executable($EXECUTABLE_NAME $SOURCE_PATH)
# Copy required DLLs to the target folder
add_custom_command(TARGET $EXECUTABLE_NAME POST_BUILD
COMMAND $CMAKE_COMMAND -E copy_if_different "$CMAKE_SOURCE_DIR/Resources/Libraries/glew/bin/glew32.dll"
"$CMAKE_BINARY_DIR/glew32.dll")
endforeach(SOURCE_PATH $SOURCE_FILES)
可选步骤
在 Visual Studio 中
在开始窗口中使用“打开本地文件夹”选项打开项目
添加新文件时,您可以:
取消要求自动将add_executable
发送到CMakeLists.txt 的对话框
通过取消选中Tools > Options > CMake
中的“为文件夹视图中的文件操作启用自动 CMake 脚本修改”来禁用此行为
由于 CMakeLists.txt 永远不会更改,因此不会自动拾取新添加的文件,因此只需像这样重新生成缓存:
Project > CMake Cache (x64-Debug) > Delete Cache
Project > Generate Cache for my-project
现在您只需右键单击给定的 c/cpp 文件和 Set as Startup Item
即可使用 F5
对其进行调试。
环境
cmake 版本 3.18.20081302-MSVC_2 Microsoft Visual Studio Community 2019 版本 16.8.3入门模板
我把这个starter template放在GitHub上,以防你感兴趣。
【讨论】:
【参考方案3】:这个CMakeLists.txt
适用于我的 OpenCV 项目
假设*.cpp
文件与CMakeLists.txt
位于同一目录中
cmake_minimum_required(VERSION 3.5)
project(opencv LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(OpenCV REQUIRED)
include_directories( $OpenCV_INCLUDE_DIRS )
file( GLOB APP_SOURCES $CMAKE_CURRENT_SOURCE_DIR/*.cpp )
foreach( sourcefile $APP_SOURCES )
file(RELATIVE_PATH filename $CMAKE_CURRENT_SOURCE_DIR $sourcefile)
string( REPLACE ".cpp" "" file $filename )
add_executable( $file $sourcefile )
target_link_libraries( $file $OpenCV_LIBS )
endforeach( sourcefile $APP_SOURCES )
【讨论】:
以上是关于在 CMake 中添加多个可执行文件的主要内容,如果未能解决你的问题,请参考以下文章