我只是想确保我对CMakeLists.txt的理解是正确的.我的虚拟项目结构:
|-+ dummy
|-+ CMakeLists.txt
|-+ src
|-- CMakeLists.txt
|-- Converter.cpp
|-- Converter.hpp
|-- main.cpp
|-+ tests
|-- CMakeLists.txt
|-- Converter_ut.cpp
|-+ thirdparty
|-+ gmock-1.7.0
我的目标是使用CMake创建构建过程.这是我的第一次尝试,所以我认为有一些错误.它有效,但我不确定我是否理解正确,如果你能分享一些意见/建议我会很感激.
虚拟/的CMakeLists.txt
cmake_minimum_required (VERSION 2.8.11)
project (SUB)
add_subdirectory (src)
add_subdirectory (tests)
> cmake_minimum_required非常明显,
> project(SUB)设置项目变量,如${SUB_SOURCE_DIR}和${SUB_BINARY_DIR},
> add_subdirectory,告诉CMake去处理以下目录中的CMakeLists.txt
SRC /的CMakeLists.txt
add_library (Sub
main.cpp
Converter.cpp)
target_include_directories (Sub PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# Executable
add_executable (converter
Converter.cpp)
target_link_libraries (converter Sub)
> add_library,从两个源文件创建名为“Sub”的库,
> target_include_directories,告诉编译器“Sub”库的头文件在哪里(这里真的需要“PUBLIC”吗?),
> add_executable,从Converter.cpp创建“converter”可执行文件(为什么这里不需要main.cpp?),
> target_link_libraries,链接“Sub”库和“converter”可执行文件
测试/的CMakeLists.txt
# GMOCK
set (GMOCK_DIR "../thirdparty/gmock-1.7.0")
add_subdirectory(${GMOCK_DIR} ${CMAKE_BINARY_DIR}/gmock)
include_directories(SYSTEM ${GMOCK_DIR}/include ${GMOCK_DIR}/gtest/include)
# Executable
add_executable (tests
Converter_ut.cpp)
target_link_libraries (tests gmock_main Sub)
> set(GMOCK_DIR …),用我的gmock文件夹位置设置局部变量“GMOCK_DIR”,
> add_subdirectory,告诉CMake跳转到gmock位置并运行他们的CMakeLists.txt,第二个参数是什么? {} CMAKE_BINARY_DIR / gmock?
> add_executable,创建第二个可执行文件
> target_link_libraries,链接gmock_main库和第二个可执行文件,这里需要“Sub”库,因为Converter_ut.cpp
需要在src目录中包含“Converter.hpp”
先感谢您.我已经阅读了很多网站/教程,但我仍然不确定.
还有一件事 – 我无法想象有大量源文件的项目.是否有更好的方法将源文件添加到add_library和add_executable函数而不是手动列出它?像“从当前目录中获取所有* .cpp文件”之类的东西?
谢谢.
最佳答案 Cmake不是一个支持完整范式的编程语言,所以使用它,但是如果可能的话永远不要开始创建“带有它的框架”(如果没有合适的语法糖就会很麻烦),它的目的是让小脚本不要写千字代码行(尽管存在很少的好的framworks,我倾向于不使用它们:“如果我不能用几行编码,那么它对CMAKE来说不是工作”).
这里主要是我在all my projects一直做的事情(具体细节省略但只是微不足道的事情)
重要的部分是(不是稍微不同,我复制粘贴改进的版本,我仍然需要提交):
cmake_minimum_required( VERSION 2.8)
project( Infectorpp2)
# find additional cmake scripts (I'm driving away from this)
set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# create list of files from a glob
file( GLOB INFECTOR_SOURCE_FILES
"include/Infectorpp/priv/*.cpp")
# create list of files from a glob
file( GLOB INFECTOR_HEADER_FILES
"include/Infectorpp/priv/*.hpp"
"include/Infectorpp/*.hpp")
# or just "add_executable" the dollar "${}" just expand the list
add_library( libInfectorpp2 STATIC
${INFECTOR_SOURCE_FILES}
${INFECTOR_HEADER_FILES})
如果您没有使用第三方库,那么您不需要添加target_include_directories,因为对于您自己的应用程序,相对路径就足够了.
对于测试部分,你对我很好,但我会这样做:
enable_testing()
## details omitted...
# create list of files from a glob
file( GLOB GMOCK_TESTS_SOURCE_FILES
"locationToTestFiles/*.cpp")
# Executable
add_executable (tests
${GMOCK_TESTS_SOURCE_FILES})
target_link_libraries (tests gmock_main Sub)
add_test(tests tests)
另请注意,CMAKE是我发现对C文件具有不同扩展名的有用的唯一原因,因为GLOBS,如果要排除某些文件,则必须更改其扩展名(以cc,c,cxx或您喜欢的方式).
您可以执行大多数遵循相同模式的任何事情,请注意,使用GLOB您必须重新配置cmake以检测新添加的文件,但是仍然比手动添加它们以构建脚本更好(并且无论如何不会导致整个重新编译,CMake保持跟踪数据并避免重新编译旧文件)
有些人发现手动将文件添加到Cmake脚本是有用的,因为“我可以保留旧文件”.不要这样做,将旧文件移动到“旧”文件夹,或者只是让你的subversion系统为你保留它们的内存.
您将更早地捕获大多数错误,并且您将有一个“准备发货”项目(您不会意外地留下用户将尝试编译的错误文件)
另一个重点:
从你的剧本做out of source builds,我猜你还没有这样做.