我正在尝试使用 cmake 创建一个简单的库并创建一个使用它的应用程序。 但是,在创建应用程序时,我必须指定库中使用的头文件的路径才能成功构建。 我想创建一个仅包含库而没有头文件路径的应用程序。
创建库
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(mylibrary)
include_directories("/path/to/src")
add_library(mylib SHARED ./foo.cpp ./foo.h)
target_include_directories(mylib PRIVATE "/path/to/src")
target_link_directories(mylib PRIVATE "/path/to/src)
set_property(TARGET mylib PROPERTY CXX_STANDARD 17)
创建应用程序
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(myapp)
add_executable(test ./main.cpp)
# target_include_directories(test PRIVATE "/path/to/src")
target_link_libraries(test PRIVATE "/path/to/src/libmylib.dylib")
target_link_directories(test PRIVATE "/path/to/src")
set_property(TARGET test PROPERTY CXX_STANDARD 17)
并在main.cpp中包含头文件
#include "foo.h"
int main(int argc, const char** argv) {
return 0;
}
如果我像这样构建,就会发生错误。
'foo.h' file not found #include "foo.h"
但是
target_include_directories(test PRIVATE "/path/to/src")
如果我添加此命令并指定头文件的路径,构建将正常进行。 这不仅适用于我创建的库,也适用于外部库。
我以为只要我有一个库,我就可以导入并使用其中的头文件。 我想这样使用它。
有没有办法在没有头文件路径的情况下使用库??
CMake 知道如何链接另一个 CMake 库目标的输出。您可以使用
add_subdirectory
将您的库添加到构建中,这使得您的 mylib
库目标在可执行项目中可用:
add_subdirectory(/path/to/mylib)
target_link_libraries(test mylib)
这样做的好处是它会自动将所需的构建标志传播到您的主应用程序,包括包含路径。但是,这只发生在包含路径为
PUBLIC
而不是 PRIVATE
的情况下,因此在您的库项目中您需要:
target_include_directories(mylib PUBLIC "/path/to/src")
完整示例:
mylib/CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(mylibrary)
# Don't mention header files here, just implementation files.
add_library(mylib SHARED ./foo.cpp)
target_include_directories(mylib PUBLIC "/path/to/src")
set_property(TARGET mylib PROPERTY CXX_STANDARD 17)
myapp/CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(myapp)
add_executable(test ./main.cpp)
# Second argument, `mylib`, is the build output directory.
# This is only required if `mylib` is not in a subdirectory of `myapp`.
add_subdirectory("/path/to/mylib" mylib)
# `mylib` is the name of the library target given to `add_library`.
target_link_libraries(test mylib)
set_property(TARGET test PROPERTY CXX_STANDARD 17)