我应该只对原始 cpp 文件使用 add_executable() 还是通过 add_library() 创建一个库?

Posted

技术标签:

【中文标题】我应该只对原始 cpp 文件使用 add_executable() 还是通过 add_library() 创建一个库?【英文标题】:Should I use only add_executable() with raw cpp files or make a library via add_library()? 【发布时间】:2019-06-27 02:11:19 【问题描述】:

我正在学习 CMake,但我有点挣扎。我的“项目”正在使用作为一个 .cpp 文件和两个 .h 文件提供的 JsonCpp“库”。结构如下:

myProject
    build/

    json/
       CMakeLists.txt
       jsoncpp.cpp
       include/
           json.h
           json-forward.h

    CMakeLists.txt 
    main.cpp

构建/CMakeLists.txt:

cmake_minimum_required(VERSION 3.6.0)
project(myProject)
add_subdirectory(json)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE json)
# add_executable(app main.cpp json/jsoncpp.cpp json/include/json.h json/include/json-forwards.h)

json/CMakeLists.txt:

cmake_minimum_required(VERSION 3.6.0)

add_library(
    json
    jsoncpp.cpp
    include/json.h
    include/json-forwards.h
)

target_include_directories(json PUBLIC '$CMAKE_CURRENT_SOURCE_DIR/include')

仅对所有 .cpp 文件使用 add_executable() 与使用将 jsoncpp 转换为静态库然后链接它的 target_link_libraries 有什么区别?我应该选择什么方法?

接下来让我感到困惑的是 target_include_directories()。使用此功能有什么好处?如果我评论它,并运行 cmake(然后 makefile 并启动应用程序)一切仍然正常。如果我从 add_library() 中删除 "include/json.h" "include/json-forward.h",一切仍然有效。

【问题讨论】:

【参考方案1】:

仅对所有 .cpp 文件使用 add_executable() 与使用将 jsoncpp 转换为静态库然后链接它的 target_link_libraries 有什么区别?我应该选择什么方法?

当您有 2 个使用相同 jsoncpp 代码的可执行文件时,需要使用 add_library。在这种情况下,如果您在两个 add_executable() 调用中列出 jsoncpp 源,则必须编译两次。将它们分组到add_library() 将使其只编译一次,然后链接到两个可执行文件。

使用add_library 的另一个原因是模块的纯粹逻辑组合。

【讨论】:

以上是关于我应该只对原始 cpp 文件使用 add_executable() 还是通过 add_library() 创建一个库?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不应该包含 cpp 文件而使用标头?

如何使用 yaml-cpp 发出和解析原始二进制数据

如何在Eclipse中一次构建多个源文件

如何找到只对所有者具有特定权限的文件?

在 Visual Studio (2015) 中编译更改的 cpp 文件

3 个 .h 和 3 个 .cpp 文件