61

我开始使用 C 来使用 CMAKE,实际上我正在创建两个非常小的静态库。

我的目标是:

  1. 这些库被编译并链接到 *.a 文件中。[这有效]
  2. 然后我希望将 *.a 文件复制到 /usr/local/lib [这也有效]
  3. 据我对库的了解(很少),它们是使用 链接的-lnameoflib,这是一个编译器标志。好的。我已经准备好我的 CMakeLists.txt,它实际上将 *.a 文件复制到/usr/local/lib. 但是,为了能够在程序中使用它们,我还需要将它们的头文件复制到/usr/local/include中,然后我可以简单地包含它们#include <mylibheader.h>。我现在就是这样理解的。

我的问题是 - 使用 CMAKE 将头文件复制到 /usr/include 文件夹的正确方法是什么?我希望它在make install执行时自动复制它们,就像 *.a 文件一样。

对于这两个库,我都有一个类似的 CMakeLists.txt:

project(programming-network)

add_library(programming-network STATIC
    send_string.c
    recv_line.c
    )

INSTALL(TARGETS programming-network
        DESTINATION "lib"
        )
4

4 回答 4

81

最新 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
)

一些参考:

PUBLIC_HEADER

CMake 安装命令

于 2016-10-27T12:59:01.200 回答
21

以更好的方式,将复制与模式匹配的所有文件并保留目录结构。

INSTALL (
    DIRECTORY ${CMAKE_SOURCE_DIR}/include/
    DESTINATION include
    FILES_MATCHING PATTERN "*.h*")
于 2016-11-18T20:41:28.973 回答
6

我不认为你的解决方案是正确的。/usr/include应该保留给您的供应商放入文件。

做 IMO 的正确做法是在其中安装标头/usr/local/include,然后指示用户export CPATH="/usr/local/include:${CPATH}".

似乎/usr/local/lib是自动搜索,但如果您希望对export LIBRARY_PATH="/usr/local/lib:${LIBRARY_PATH}".a 二进制文件使用类似的另一个目录(但取决于您的操作系统,对于共享库可能适用也可能不好)。

可选,但更麻烦的是在编译时添加-I /usr/local/include和。-L /usr/local/lib

这是一个有点主观的答案,但对我来说效果很好。

于 2012-05-07T19:46:11.767 回答
3

除了接受的答案之外,如果您正在创建大量库并且set_property语法会让您失望。您可以将其包装在一个非常简单的宏中,例如:

# File: target_public_headers.cmake
macro(target_public_headers TARGET)
  set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER "${ARGN}")
endmacro()

然后你可以像这样使用它:

project(myproject)

include(target_public_headers)

add_library(mylib some.c another.c)
target_public_headers(mylib some.h another.h) # <<<<<

# If you're exporting this library then you need to tell
# CMake how to include the "installed" version of the headers.
target_include_directories(mylib
  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
  PUBLIC $<INSTALL_INTERFACE:some/includepath>
)

INSTALL(TARGETS mylib 
        LIBRARY DESTINATION some/libpath
        PUBLIC_HEADER DESTINATION some/includepath
)
于 2020-04-24T04:38:06.883 回答