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

问题描述 投票:0回答:3

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

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

现在,每个

.cxx
文件都有一个
main()
方法,因此我需要为每个与该文件同名的文件添加不同的可执行文件。

此外,这些

.cxx
文件可能不会链接到相同的外部库。

我想在 CMake 中编写这个构建,我是个新手,我该怎么做?

c++ build cmake executable
3个回答
139
投票

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

  1. 使用
    .cpp
    .h
    add_library
  2. 文件构建库
  3. 迭代所有
    .cxx
    文件并使用
    add_executable
    foreach
  4. 创建可执行文件

建立图书馆

这可能很简单

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} )
    # Cut off the file extension and directory path
    get_filename_component( testname ${testsourcefile} NAME_WE )
    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 标志表示
    file(GLOB ...)
  • 手动设置源文件需要更改 CMakeLists.txt,这会触发重建。请参阅这个问题了解通配符的(反)优点。

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


7
投票

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

下面的设置将为每个 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 社区 2019 版本 16.8.3

入门模板

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


1
投票

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} )
© www.soinside.com 2019 - 2024. All rights reserved.