Cmake 将嵌套静态库安装target_link_library未定义的引用

Cmake install nested static library target_link_library undefined reference

提问人:CWKSC 提问时间:8/10/2022 最后编辑:CWKSC 更新时间:8/10/2022 访问量:296

问:

安装嵌套的静态库,target_link_library不起作用

文件结构:

HelloLib
    WorldLib
        CMakeLists.txt
        WorldLib.cpp
        WorldLib.h

    CMakeLists.txt
    HelloLib.cpp
    HelloLib.h

CMakeLists.txt
main.cpp

main.cpp

#include <iostream>
#include "HelloLib/HelloLib.h"
int main() {
  std::cout << hello() << std::endl;
  return 0;
}

CMakeLists.txt(根)

cmake_minimum_required(VERSION 3.16.3)
project(HelloWorld)

add_executable(${PROJECT_NAME} main.cpp)

add_subdirectory(HelloLib)
target_link_libraries(
    ${PROJECT_NAME}
    HelloLib
)

HelloLib.cpp

#include <string>
#include "WorldLib/WorldLib.h"
std::string hello() { return "Hello " + world(); }

你好库.h

#pragma once
#include <string>
std::string hello();

CMakeLists.txt (HelloLib)

add_library(HelloLib HelloLib.cpp)

add_subdirectory(WorldLib)
target_link_libraries(
    HelloLib
    WorldLib
)

WorldLib.cpp

#include <string>
std::string world() { return "World!"; }

WorldLib.h

#pragma once
#include <string>
std::string world();

CMakeLists.txt (WorldLib)

add_library(WorldLib WorldLib.cpp)

构建并运行,成功打印出来Hello World!

现在我想把 HelloLib 做成静态库

更改 CMakeLists.txt (HelloLib),安装到 和/usr/lib/usr/include

add_library(HelloLib HelloLib.cpp)

add_subdirectory(WorldLib)
target_link_libraries(
    HelloLib
    WorldLib
)

install(
    TARGETS HelloLib
    ARCHIVE DESTINATION lib
)
install(
    DIRECTORY "${CMAKE_SOURCE_DIR}/" # source directory
    DESTINATION "include" # target directory
    FILES_MATCHING # install only matched files
    PATTERN "*.h" # select header files
)

运行 () (CMAKE_INSTALL_PREFIX=make install/usr)

mkdir -p out/build
cmake -S src -B out/build -DCMAKE_INSTALL_PREFIX=/usr
cd out/build
make
make install
[ 33%] Built target WorldLib
[ 66%] Built target HelloLib
[100%] Built target HelloWorld
Install the project...
-- Install configuration: ""
-- Installing: /usr/lib/libHelloLib.a
-- Up-to-date: /usr/include
-- Installing: /usr/include/HelloLib
-- Installing: /usr/include/HelloLib/HelloLib.h
-- Installing: /usr/include/HelloLib/WorldLib
-- Installing: /usr/include/HelloLib/WorldLib/WorldLib.h

静态库 (.a) 应生成/usr/lib/libHelloLib.a

让我们测试一下,更改CMakeLists.txt(根)

cmake_minimum_required(VERSION 3.16.3)
project(HelloWorld)

add_executable(${PROJECT_NAME} main.cpp)

add_subdirectory(HelloLib)
target_link_libraries(
    ${PROJECT_NAME}

    /usr/lib/libHelloLib.a
)

然后构建,它给出了未定义的引用错误

/bin/ld: /usr/lib/libHelloLib.a(HelloLib.cpp.o): in function `hello[abi:cxx11]()':
HelloLib.cpp:(.text+0x20): undefined reference to `world[abi:cxx11]()'

我怎么了?这可以在没有嵌套库的情况下成功

安装嵌套静态库的正确方法是什么?

c++ linux cmake 静态库 undefined-reference

评论


答:

1赞 Stiven 8/10/2022 #1

这里的问题不在于安装过程,而在于您仅链接到 .libHelloLib.a

您需要 中的符号,因为 是一个静态库,因此只包含它自己的符号。它不包含 中定义的符号。libHelloLib.alibWorldLib.alibHelloLib.aworldlibWorldLib.a

要使你的项目正常工作,你需要安装和链接这两个库。WorldLibHelloLib

target_link_libraries(
    ${PROJECT_NAME}
    HelloLib
    WorldLib
)

或者,您可以更改为共享库。这样,遗嘱还包含符号 。HelloLiblibHelloLib.soWorldLib

您还可以查看此导出的目标。 这是一个安装命令,它将创建一些文件,您将能够与该命令一起使用。您还可以定义库的依赖关系。但是,如果您想要保留静态库,则必须安装FindXX.cmakefind_packageHelloLibWorldLib