我需要帮助写一个好的CMakeLists.txt的C++项目。
我寻找答案,但我找到了任何东西。这是我的项目结构:
MainProj
| ProjLib/
| | include/
| | | proj_lib.h
| | src/
| | | proj_lib.cc
| | CMakeLists.txt
| ProjExec/
| | include/
| | | proj_exec.h
| | src/
| | | proj_exec.cc
| | CMakeLists.txt
| CMakeLists.txt
字符串
MainProj CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(MainProj CXX)
# enable C and C++ language
enable_language(C CXX)
# Add sub-directories
add_subdirectory(ProjLib)
add_subdirectory(ProjExec)
型
ProjLib CMakeLists.txt
set (PROJLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (PROJLIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(PROJLIB_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/src/proj_lib.cc
)
include_directories("${PROJLIB_SOURCE_DIR}")
include_directories("${PROJLIB_INCLUDE_DIR}")
add_library(ProjLib SHARED ${PROJLIB_SRCS} ${PROJLIB_INCLUDE_DIR})
target_include_directories (ProjLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
型
ProjExec CMakeLists.txt
set (PROJEXEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (PROJEXEC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(PROJEXEC_SRCS
${PROJEXEC_SOURCE_DIR}/proj_exec.cc
)
include_directories("${PROJEXEC_SOURCE_DIR}")
include_directories("${PROJEXEC_INCLUDE_DIR}")
add_executable(ProjExec ${PROJEXEC_SRCS})
target_link_libraries (ProjExec LINK_PUBLIC ProjLib)
型
proj_exec.cc
#include "proj_lib.h"
...
型
在proj_exec.cc文件中找不到proj_lib. h。如果我需要一些额外的条目在一些cmake?
如果你能帮忙的话,我将不胜感激。:)
4条答案
按热度按时间a6b3iqyw1#
您需要使用CMake目标及其属性:
MainProj/CMakeLists.txt:
字符串
ProjLib/CMakeLists.txt
型
ProjExec/CMakeLists.txt
型
target_link_libraries
确保在构建目标时,将适当地使用其依赖项的PUBLIC和INTERFACE包含目录。gg0vcinb2#
您的cmake项目模板看起来很好并且是自包含的。首先,我假设
GAITPARAMS_SRCS
应该是PROJEXEC_SRCS
,它当前指向proj_exec.cc,包含一个main()方法。(如果你要管理一个SRCS列表,注意不要在列表的顶部添加源文件,add_executable期望main函数在第一个条目中)其次,问题出在你的
ProjLib/CMakeLists.txt
上。尝试将您的target_include_directories
调用替换为以下内容:字符串
这将在应用
target_link_libraries
命令时将包含目录信息传播到ProjExec。如果你不想这样做,我想你可以通过#include <include/ProjLib.h>
访问,但这只是令人困惑。我的建议是在include文件夹中添加另一个文件夹(与cmake文件夹命名完全相同),并在其中添加标题。就像这样:型
这使您可以在文件夹名中包含标题(更不用说防止名称冲突了)。就像这样:
型
并配置CMakeLists.txt文件以匹配模式。
qxgroojn3#
以下所有选项都有效,但最佳选项在rubenvb's answer中进行了说明。
你至少有三个选择:
1)在ProjExec/CMakeLists.txt中添加以下行:
字符串
2)您可以通过添加
CACHE INTERNAL
关键字来扩展变量PROJLIB_INCLUDE_DIR
的可见性型
然后在ProjExec/CMakeLists.txt中使用它:
型
请参阅How to set the global variable in a function for cmake?
当然,ProjLib必须在主CMakeLists.txt文件的
add_subdirectory
序列中排在第一位。3)我不能测试这个。如果你在ProjLib的CMakeLists.txt中使用这一行:
型
然后在ProjExec的CMakeLists.txt中,您可以提取属性
INTERFACE_INCLUDE_DIRECTORIES
,并使用它:型
这两行代码可以使用cmake-generator-expressions(未测试)压缩为一行:
型
参见target_include_directories和get_target_property。
其他注意事项:
include_directories
,要么使用target_include_directories
,不要同时使用。include_directories("${PROJLIB_SOURCE_DIR}")
和include_directories("${PROJEXEC_SOURCE_DIR}")
q35jwt9p4#
在设置目标的属性时,一个关键点是理解
target_include_directories
命令及其关键字PRIVATE
、INTERFACE
和PUBLIC
。PRIVATE
表示只有目标需要include目录。INTERFACE
表示当其他目标想要链接这个目标时需要包含目录,cmake
将自动处理它。PUBLIC
意味着这个目标和依赖于它的其他目标都必须将这个目录压缩到它的搜索路径中。所有这些都是由你的代码决定的。