Mir*_*res 44 c cmake static-libraries
我正在使用C进入CMAKE,实际上我正在创建两个非常小的静态库.
我的目标是:
-lnameoflib
,这是一个编译器标志.好.我准备好了我的CMakeLists.txt,它实际上将*.a文件复制到/ usr/local/lib中.但是,为了能够在程序中使用它们,我还需要将它们的头文件复制到/ usr/include中,然后我可以轻松地将它们包含在内/usr/local/lib
.这就是我现在理解的方式.我的问题是 - 如何使用CMAKE将头文件复制到/ usr/include文件夹中的正确方法是什么?我想在/usr/local/include
执行时自动复制它们,比如*.a文件.
对于这两个库,我有一个熟悉的CMakeLists.txt:
project(programming-network)
add_library(programming-network STATIC
send_string.c
recv_line.c
)
INSTALL(TARGETS programming-network
DESTINATION "lib"
)
Run Code Online (Sandbox Code Playgroud)
flm*_*620 41
最新的cmake版本的更好方法是使用目标的PUBLIC_HEADER
属性.
project(myproject)
add_library(mylib some.c another.c)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "some.h;another.h")
INSTALL(TARGETS mylib
LIBRARY DESTINATION some/libpath
PUBLIC_HEADER DESTINATION some/includepath
)
Run Code Online (Sandbox Code Playgroud)
一些参考:
Sor*_*ush 21
几年后,在 CMake 3.23 中,我们可以使用 FILE_SET 作为公共标头:
project(programming-network)
add_library(programming-network STATIC)
target_include_directories(programming-network PRIVATE "${PROJECT_SOURCE_DIR}")
target_sources(programming-network
PRIVATE send_string.c recv_line.c
PUBLIC FILE_SET HEADERS
BASE_DIRS ${PROJECT_SOURCE_DIR}
FILES publicheader1.h publicheader2.h)
install(TARGETS programming-network FILE_SET HEADERS)
Run Code Online (Sandbox Code Playgroud)
现在让我们看看这些命令的作用:
add_library()
:定义目标的名称,STATIC 为静态库,SHARED 为共享库,OBJECT 为对象。
target_include_directories()
:这里的这一行仅适用于当您的子目录和私有标头相对于项目目录相互引用时。但通常,此命令用于在项目中包含外部标头。
target_sources()
:该命令用于添加带PRIVATE
关键字的定义文件和私有头文件。此外,它还用于通过FILE_SET
关键字添加公共标头。BASE_DIRS
就是通过从公共标头的路径中减去基目录,将公共标头的绝对路径转换为相对路径。所以这个公共标头
/home/someuser/programming-network/sub1/publicheader1.h
Run Code Online (Sandbox Code Playgroud)
基目录为
/home/someuser/programming-network/
Run Code Online (Sandbox Code Playgroud)
将安装在
/cmake/install/prefix/include/sub1/publicheader.h
Run Code Online (Sandbox Code Playgroud)
Note也target_sources()
可用于 of子目录。CMakeLists.txt
install()
: 是安装二进制文件、静态/共享库和公共头文件。默认安装子目录是bin
、lib
和include
。你也可以像这样改变它install(TARGETS myTarget
# for executables and dll on Win
RUNTIME DESTINATION bin
# shared libraries
LIBRARY DESTINATION lib
# for static libraries
ARCHIVE DESTINATION lib
# public headers
INCLUDES DESTINATION include)
Run Code Online (Sandbox Code Playgroud)
最后,构建并安装项目(对于多配置生成器:MS Visual C++、Xcode)
project(programming-network)
add_library(programming-network STATIC)
target_include_directories(programming-network PRIVATE "${PROJECT_SOURCE_DIR}")
target_sources(programming-network
PRIVATE send_string.c recv_line.c
PUBLIC FILE_SET HEADERS
BASE_DIRS ${PROJECT_SOURCE_DIR}
FILES publicheader1.h publicheader2.h)
install(TARGETS programming-network FILE_SET HEADERS)
Run Code Online (Sandbox Code Playgroud)
对于单配置生成器(make、Ninja),删除上述--config Release
术语并更改cmake ..
为cmake -DCMAKE_BUILD_TYPE=Release ..
.
J.A*_*ler 13
以更好的方式,将复制与模式匹配的所有文件并保留目录结构.
INSTALL (
DIRECTORY ${CMAKE_SOURCE_DIR}/include/
DESTINATION include
FILES_MATCHING PATTERN "*.h*")
Run Code Online (Sandbox Code Playgroud)
我不认为你的解决方案是正确的./usr/include
应保留供您的供应商放入文件.
做IMO的正确方法是在头文件中安装/usr/local/include
,然后指示用户export CPATH="/usr/local/include:${CPATH}"
.
它似乎/usr/local/lib
是自动搜索,但如果你想使用另一个export LIBRARY_PATH="/usr/local/lib:${LIBRARY_PATH}"
类似于.a二进制文件的dir 工作(但根据你的操作系统,可能会或可能不适用于共享库).
可选地,但更麻烦的是添加-I /usr/local/include
和-L /usr/local/lib
编译时.
这是一个有点主观的答案,但它对我来说效果很好.