Mat*_* M. 208 c++ ubuntu cmake
大约一年前,我询问了CMake中的头依赖关系.
我最近意识到问题似乎是CMake认为那些头文件是项目外部的.至少,在生成Code :: Blocks项目时,头文件不会出现在项目中(源文件会出现).因此,在我看来,CMake认为这些标题是项目的外部,并且不会在依赖项中跟踪它们.
在CMake教程中快速搜索只指出include_directories
哪个似乎没有我想做的...
向CMake发出信号通知特定目录是否包含要包含的标头的正确方法是什么,并且生成的Makefile应该跟踪这些标头?
Sir*_*ius 226
必须做两件事.
首先添加要包含的目录:
target_include_directories(test PRIVATE ${YOUR_DIRECTORY})
Run Code Online (Sandbox Code Playgroud)
如果您在没有支持的情况下遇到非常旧的CMake版本(2.8.10或更早版本)target_include_directories
,您也可以使用旧版include_directories
:
include_directories(${YOUR_DIRECTORY})
Run Code Online (Sandbox Code Playgroud)
然后,您还必须将头文件添加到当前目标的源文件列表中,例如:
set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})
Run Code Online (Sandbox Code Playgroud)
这样,头文件将在Makefile中显示为依赖项,例如在生成的Visual Studio项目中,如果生成一个.
如何将这些头文件用于多个目标:
set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})
Run Code Online (Sandbox Code Playgroud)
Rei*_*ica 65
首先,您使用include_directories()
告诉CMake将目录添加-I
到编译命令行.其次,列出您add_executable()
或add_library()
电话中的标题.
例如,如果您的项目源是src
,并且您需要标题include
,您可以这样做:
include_directories(include)
add_executable(MyExec
src/main.c
src/other_source.c
include/header1.h
include/header2.h
)
Run Code Online (Sandbox Code Playgroud)
小智 60
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 external //We simulate that code is provided by an "external" library outside of src\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conversion.cpp\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conversion.hpp\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 README.md\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 evolution //propagates the system in a time step\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 evolution.cpp\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 evolution.hpp\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 initial //produces the initial state\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 initial.cpp\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 initial.hpp\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 io //contains a function to print a row\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 io.cpp\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 io.hpp\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.cpp //the main function\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 parser //parses the command-line input\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 parser.cpp\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 parser.hpp\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests //contains two unit tests using the Catch2 library\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 catch.hpp\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test.cpp\n
Run Code Online (Sandbox Code Playgroud)\n1. 顶层 CMakeLists.txt 与配方 1 非常相似,使用函数和宏进行代码重用
\ncmake_minimum_required(VERSION 3.5 FATAL_ERROR)\n \nproject(recipe-07 LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 11)\nset(CMAKE_CXX_EXTENSIONS OFF)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\ninclude(GNUInstallDirs)\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY\n ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY\n ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY\n ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})\n\n# defines targets and sources\nadd_subdirectory(src)\n\n# contains an "external" library we will link to\nadd_subdirectory(external)\n\n# enable testing and define tests\nenable_testing()\nadd_subdirectory(tests)\n
Run Code Online (Sandbox Code Playgroud)\n2.目标和源在src/CMakeLists.txt中定义(转换目标除外)
\nadd_executable(automata main.cpp)\n \nadd_subdirectory(evolution)\nadd_subdirectory(initial)\nadd_subdirectory(io)\nadd_subdirectory(parser)\n\ntarget_link_libraries(automata\n PRIVATE\n conversion\n evolution\n initial\n io\n parser\n )\n
Run Code Online (Sandbox Code Playgroud)\n3.转换库定义在external/CMakeLists.txt中
\nadd_library(conversion "")\n\ntarget_sources(conversion\n PRIVATE\n ${CMAKE_CURRENT_LIST_DIR}/conversion.cpp\n PUBLIC\n ${CMAKE_CURRENT_LIST_DIR}/conversion.hpp\n )\n\ntarget_include_directories(conversion\n PUBLIC\n ${CMAKE_CURRENT_LIST_DIR}\n )\n
Run Code Online (Sandbox Code Playgroud)\n4. src/CMakeLists.txt 文件添加更多子目录,这些子目录又包含 CMakeLists.txt 文件。它们的结构都很相似;src/evolution/CMakeLists.txt 包含以下内容:
\nadd_library(evolution "")\n\ntarget_sources(evolution\n PRIVATE\n ${CMAKE_CURRENT_LIST_DIR}/evolution.cpp\n PUBLIC\n ${CMAKE_CURRENT_LIST_DIR}/evolution.hpp\n )\ntarget_include_directories(evolution\n PUBLIC\n ${CMAKE_CURRENT_LIST_DIR}\n )\n
Run Code Online (Sandbox Code Playgroud)\n5.单元测试注册在tests/CMakeLists.txt中
\nadd_executable(cpp_test test.cpp)\n\ntarget_link_libraries(cpp_test evolution)\n\nadd_test(\n NAME\n test_evolution\n COMMAND\n $<TARGET_FILE:cpp_test>\n )\n
Run Code Online (Sandbox Code Playgroud)\n$ mkdir -p build\n$ cd build\n$ cmake ..\n$ cmake --build .\n
Run Code Online (Sandbox Code Playgroud)\n参考: https: //github.com/sun1211/cmake_with_add_subdirectory
\nbru*_*iuz 12
如果将CMake与其他创建Makefile的方法(例如make或qmake)进行比较,则CMake更像是一种脚本语言.它不像Python那么酷,但仍然如此.
如果在各种开源项目中查看人们如何包含目录,就没有像" 正确的方法 " 这样的东西.但有两种方法可以做到这一点.
粗体include_directories会将目录附加到当前项目以及您将通过一系列add_subdirectory命令追加的所有其他后代项目.有时人们会说这种做法是遗留的.
更优雅的方法是使用target_include_directories.它允许为特定项目/目标附加目录,而不会(可能)不必要的继承或各种包含目录的冲突.还允许执行甚至是微妙的配置,并为此命令附加以下标记之一.
PRIVATE - 仅用于此指定的构建目标
PUBLIC - 将其用于指定目标和与此项目链接的目标
接口 - 仅用于与当前项目链接的目标
PS:
这两个命令都允许将目录标记为SYSTEM,以提示指示目录将包含警告不是您的业务.
类似的答案是其他命令对target_compile_definitions/add_definitions, target_compile_options/CMAKE_C_FLAGS
添加include_directories("/your/path/here")
。
这将类似于gcc
使用-I/your/path/here/
option 调用。
确保在路径两边加上双引号。其他人没有提及,这让我呆了2天。因此,此答案适用于刚接触CMake且非常困惑的人。
我有同样的问题。
我的项目目录如下:
--project
---Classes
----Application
-----.h and .c files
----OtherFolders
--main.cpp
Run Code Online (Sandbox Code Playgroud)
以及我以前在所有这些文件夹中包括的文件:
file(GLOB source_files
"*.h"
"*.cpp"
"Classes/*/*.cpp"
"Classes/*/*.h"
)
add_executable(Server ${source_files})
Run Code Online (Sandbox Code Playgroud)
它完全有效。
小智 5
你有两个选择。
老人:
include_directories(${PATH_TO_DIRECTORY})
Run Code Online (Sandbox Code Playgroud)
和新的
target_include_directories(executable-name PRIVATE ${PATH_TO_DIRECTORY})
Run Code Online (Sandbox Code Playgroud)
要使用target_include_directories
,您需要定义可执行文件 - add_executable(executable-name sourcefiles)
。
所以你的代码应该看起来像
add_executable(executable-name sourcefiles)
target_include_directories(executable-name PRIVATE ${PATH_TO_DIRECTORY})
Run Code Online (Sandbox Code Playgroud)
您可以在此处阅读更多信息https://cmake.org/cmake/help/latest/command/target_include_directories.html
归档时间: |
|
查看次数: |
353740 次 |
最近记录: |