【问题标题】:How do I tell CMake to link in a static library in the source directory?如何告诉 CMake 链接源目录中的静态库?
【发布时间】:2012-12-14 04:43:44
【问题描述】:

我有一个带有 Makefile 的小项目,我正在尝试将其转换为 CMake,主要是为了获得 CMake 的经验。出于本示例的目的,该项目包含一个源文件(C++,尽管我认为该语言不是特别相关)和一个我从其他地方复制的静态库文件。为论证起见,假设库的源代码不可用;我只有 .a 文件和相应的头文件。

我的手工 Makefile 包含这个构建规则:

main: main.o libbingitup.a
    g++ -o main main.o libbingitup.a

效果很好。我如何告诉 CMake 重现这个?当然,不是字面上的这个确切的makefile,而是包含等效链接命令的东西。我尝试了明显但幼稚的方法,例如

add_executable(main main.cpp libbingitup.a)

add_executable(main main.cpp)
target_link_libraries(main libbingitup.a)

以及link_directories(.)add_library(bingitup STATIC IMPORTED) 等的各种东西,但到目前为止还没有任何东西可以成功连接。我该怎么办?


版本详情:Linux 上的 CMake 2.8.7 (Kubuntu 12.04) 和 GCC 4.6.3

【问题讨论】:

    标签: cmake static-libraries


    【解决方案1】:

    CMake 倾向于将完整路径传递给链接库,因此假设 libbingitup.a 在 ${CMAKE_SOURCE_DIR} 中,执行以下操作应该会成功:

    add_executable(main main.cpp)
    target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)
    

    【讨论】:

    • 很好,可以,谢谢!必须在此处明确输入完整路径似乎有点骇人听闻,但我想这只是 CMake 方式...
    • 我同意这似乎有点矫枉过正,但如果您安装了同一个库的多个不同版本,则明确指定完整路径会带来好处。
    • 惊人的,像往常一样!就我而言,解决了依赖于另一个构建的动态库的库问题,该动态库依赖于静态库:依赖库也试图链接到这个静态库。
    • main 如何知道包含目录?
    • 您需要使用target_include_directoriesinclude_directories(前者是首选方式,因为它更具体)。
    【解决方案2】:

    如果你不想包含完整路径,你可以这样做

    add_executable(main main.cpp)
    target_link_libraries(main bingitup)
    

    bingitup 与您在 CMake 项目中创建静态库时为目标指定的名称相同:

    add_library(bingitup STATIC bingitup.cpp)
    

    CMake 自动将lib 添加到前面,在 Linux 上将 .a 添加到末尾,在 Windows 上将 .lib 添加到末尾。

    如果库是外部的,您可能希望使用添加库的路径

    link_directories(/path/to/libraries/)
    

    【讨论】:

    • 如果存在同名的 .a 和 .so 文件,在这种情况下,您如何指定要链接到 .a 或 .so 的方式?
    • @George:你不能。如果您同时存在这两种类型,请包含您要链接的文件的全名。
    【解决方案3】:

    我发现这很有帮助...

    http://www.cmake.org/pipermail/cmake/2011-June/045222.html

    从他们的例子中:

    ADD_LIBRARY(boost_unit_test_framework STATIC IMPORTED)
    SET_TARGET_PROPERTIES(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a)
    TARGET_LINK_LIBRARIES(mytarget A boost_unit_test_framework C)
    

    【讨论】:

    • INCLUDE_DIRECTORIES 怎么样?
    • 这仅在库是 cmake 构建的一部分时才有效,但外国的则不起作用
    • 问题是“该项目包含一个源文件(C++,虽然我认为该语言不是特别相关)和一个我从其他地方复制的静态库文件。”
    【解决方案4】:

    我要添加到其他cmets,项目名称是第一个参数。我有一个叫cmakecompile的项目,想给它加libusb,代码如下,

    add_executable(cmakecompile main.c)
    target_link_libraries(cmakecompile "D:/msys2/mingw64/lib/libusb-1.0.a")
    

    项目只有一个 main.c 文件,target_link_libraries 中的第一个参数是项目名称,第二个参数是库路径

    注意这可能会有所帮助:由于我在 windows 下编译,我必须安装 msys2,因为您必须使用相同的编译器编译库。例如,如果您获得libusb 并尝试在 qt-creator 项目中使用它,它将无法工作并且您可能会获得未引用的功能,因此我必须安装 msys2 并从 msys2 内部安装 libusb,安装 make 并创建 QT Cmake 项目并使用 msys2 make 从 Qt 创建者编译。

    完整的cmakelists.txt如下

    cmake_minimum_required(VERSION 3.5)
    
    project(cmakecompile LANGUAGES C)
    
    add_executable(cmakecompile main.c)
    target_link_libraries(cmakecompile "D:/msys2/mingw64/lib/libusb-1.0.a")
    

    【讨论】:

    • 这似乎与Fraser's answer 基本相同。如果您打算使用其他信息来扩展其他答案,您能否澄清您要添加的内容以及您认为有必要添加的原因?
    • 我正在添加其他细节,这很重要,例如如果这是针对 qt 而不是 Visual Studio,则要遵循的路径。另外,编译它所需的最低 cmake 内容是多少。我记得我花了两天时间才找到这些信息,这就是我为社区提供这些信息的原因。
    • 感谢@DrlSherifOmran 展示了明确的目录形式。
    猜你喜欢
    • 2011-04-14
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多