【问题标题】:"No such file or directory" when linking shared library with CMake [duplicate]将共享库与 CMake 链接时“没有这样的文件或目录”[重复]
【发布时间】:2021-10-17 16:06:48
【问题描述】:

我正在尝试将预编译的 so 文件链接到我在 cmake 中的可执行文件。我不确定我是否误解了如何使用共享库,但我假设一旦我编译了共享库,任何应用程序都可以链接到它并使用它的功能。编译可执行文件时,我收到此错误:

logger.h: No such file or directory
 #include "logger.h"
          ^~~~~~~~~~
compilation terminated.

这是我的可执行文件的 cmake 文件

cmake_minimum_required(VERSION 2.8)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# set PROJECT home directory 
set(PROJECT_HOME "/opt/PROJECT")

# set the project name
project(ClServer)

# add the executable
add_executable(ClServer server.cpp)

add_library(logger SHARED IMPORTED libClLogger.so)

message ("Here")

set_target_properties(logger
PROPERTIES IMPORTED_LOCATION "#{PROJECT_HOME}/base"
)

target_link_libraries(ClServer
${Logger}
)

我也尝试过使用find_library 并使用target_link_libraries 添加到共享库的绝对路径,但出现了同样的错误。

这是我的记录器共享库的 cmake 文件:

cmake_minimum_required(VERSION 2.8)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# set Clamor home directory 
set(PROJECT_HOME "/opt/PROJECT")

# set the project name
project(ClLogger)

# set boost paths
set(Boost_NO_SYSTEM_PATHS TRUE)
if (Boost_NO_SYSTEM_PATHS)
    set(BOOST_ROOT "${PROJECT_HOME}/ext/Boost/boost_1_76_0")
    set(BOOST_LIBRARYDIR "${PROJECT_HOME}/ext/Boost/boost_1_76_0/stage/lib")
    set(BOOST_INCLUDEDIR "${PROJECT_HOME}/ext/Boost/boost_1_76_0")
endif (Boost_NO_SYSTEM_PATHS)

# provides the linker with the appropriate directories and components
find_package(Boost 1.76.0 COMPONENTS log log_setup thread filesystem system)
if(Boost_FOUND)
  include_directories(${BOOST_INCLUDEDIR})
  link_directories(${BOOST_LIBRARYDIR})
endif()

message (STATUS Boost_LIBRARIES:)
message (STATUS ${Boost_LIBRARIES})
message (STATUS BOOST_INCLUDEDIR:)
message (STATUS ${BOOST_INCLUDEDIR})

# add PROJECT source code libraries
add_library(ClLogger SHARED logger.cpp)

# link the appropriate libraries
target_link_libraries(ClLogger
libpthread.so.0
${Boost_LIBRARIES}
)

# redirect binaries to base folder
set_target_properties(ClLogger
    PROPERTIES
    ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_HOME}/base"
    LIBRARY_OUTPUT_DIRECTORY "${PROJECT_HOME}/base"
    RUNTIME_OUTPUT_DIRECTORY "${PROJECT_HOME}/base"
)

【问题讨论】:

  • 您需要添加 include 目录,其中包含所需的标头 (logger.h)。您可以按照that question 的答案通过“通用方式”来做到这一点。或者你可以通过你拥有的导入库目标来做到这一点,使用属性INTERFACE_INCLUDE_DIRECTORY,类似于that question
  • 另请注意,在 CMake 中 targetsvariables 是不同的东西。表达式 ${Logger} 取消引用您从未定义的 Logger variable。而是使用 target_link_libraries(ClServer Logger) 与 IMPORTED target 链接。

标签: c++ cmake


【解决方案1】:

要使用共享库,您需要做两件事。一是共享库文件,二是公共头文件。编译阶段使用头文件,链接阶段使用共享库文件。您看到的错误是编译失败,表示找不到头文件“logger.h”。在可执行文件的 cmake 中使用 target_include_directories 来告诉 cmake 在哪里查找标头 logger.h。 此外,如果您希望 cmake 监视 logger.h 修改,您可以添加 logger.h 作为可执行文件的源文件。

【讨论】:

    【解决方案2】:

    在我的本地机器上进行了一些研究和测试后,
    我已经用在 WSL2 中的 eclipse CDT 和 cmake 上测试的简单示例更新了我的答案。(应该可以在任何其他环境中正常工作)。
    以下示例应提供问题的答案。

     cmake_test/
     ├── CMakeLists.txt
     ├── build
     ├── cmake_test.cpp
     └── **companyLibrary**
         ├── CMakeLists.txt
         ├── build
         ├── include
         │   └── Company.h
         └── src
             └── Company.cpp  
    

    从上面的项目层次结构中,companyLibrary 是生成 .so(共享库)的那个,它将被项目根级别的 cmake_test.cpp 源文件使用。

    cmake_test/companyLibrary/CMakeLists.txt

     cmake_minimum_required (VERSION 2.6)
    
     project (companyLibrary_test)
     set(CMAKE_BUILD_TYPE Release)
    
     #adding the header <.h> files into the project
     include_directories(include)
    
     file(GLOB SOURCES "src/*.cpp")
    
     add_library(testCompany SHARED ${SOURCES})
    
     install(TARGETS testCompany DESTINATION /usr/lib)  
    

    这会在本例中生成 .so 文件 (libtestCompany.so)

     sudo make install  
    

    这会将 .so 文件放入 /usr/lib 文件夹中

    现在这个共享库将被根项目 cmake_test.cpp 文件使用

    cmake_test/CMakeLists.txt

    cmake_minimum_required (VERSION 2.6)
    
    project (cmake_test)
    
    set ( PROJECT_LINK_LIBS libtestCompany.so )
    link_directories( "/usr/lib" )
    include_directories( "companyLibrary/include" )
    
    add_executable( libtest cmake_test.cpp )
    target_link_libraries( libtest ${PROJECT_LINK_LIBS} )  
    

    add_executabletarget_link_libraries 应该可以解决问题 如上所示。

    GitHub 上的完整源代码 here 可用。

    希望对你有帮助:)

    【讨论】:

    • 这不起作用,它产生了同样的错误。我是否需要在编译记录器共享库的 cmake 文件或记录器头文件中添加一些内容以允许将其导出?我确定我只是缺少一些小东西
    • target_link_libraries(ClServer PRIVATE logger)
    • 能不能把上面的语句加进去再运行一下,告诉我
    • 这个也没有解决。我添加了另一个 cmake 文件以获得更多上下文
    • @milos miladinov 抱歉,花了更多时间来提供正确的工作示例,希望它在我的机器上测试时能正常工作。
    猜你喜欢
    • 2018-04-14
    • 2021-12-22
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多