我在C ++项目中的代码组织如下
- 我有几个
.cpp
和.h
文件,其中包含我的班 - 我有几个
.cxx
文件必须针对这些.cpp
文件和一些外部库进行编译。
现在,每个.cxx
文件都有一个main()
方法,因此我需要为每个文件添加与文件名称相同的不同可执行文件。
同样,这些.cxx
文件可能不会链接到相同的外部库。
我想用CMake编写这个版本,我是一个新手,我该如何处理?
Answers:
我的建议是分两个阶段解决此问题:
.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不会自动重建。我在这里使用它是因为我不知道您的源文件。find( GLOB ... )
。 string( REPLACE ... )
。我本可以将get_filename_component与NAME_WE
标志一起使用。关于“常规” CMake信息,我建议您阅读一些关于stackoverflow的广泛的“ CMake概述”问题。例如:
get_filename_component(testname ${testsourcefile} NAME_WE)
而不是使用获取文件名string(REPLACE...
。这样做的好处是,它还将删除路径的其余部分,如果您EXECUTABLE_OUTPUT_PATH
用于设置二进制文件的存放位置,这将很方便。
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} )
这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} )
在组织带有多个示例文件的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.txtTools > Options > CMake
由于新添加的文件不会自动更改,因为CMakeLists.txt从未更改,因此只需重新生成缓存,如下所示:
Project > CMake Cache (x64-Debug) > Delete Cache
Project > Generate Cache for my-project
现在,您可以简单地右键单击给定的c / cpp文件并Set as Startup Item
使用进行调试F5
。
环境
build/
目录中,还是会尊重基础源代码树的目录结构?另请参阅此问题