Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
477 views
in Technique[技术] by (71.8m points)

c++ - cmake - Header files of shared library not found

I am making a custom library that I want to be installable for users. However, when I try to use my own library in a cmake executable, I get a build error saying that the library headers were not found.

The library CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(mylibrary)

include(GNUInstallDirs)

set(CMAKE_CXX_STANDARD 14)

# Register a library - This will created lib[xxx].so
add_library(mylibrary SHARED src/library.cpp)

configure_file(mylibrary.pc.in mylibrary.pc @ONLY)

# List the /include directory
target_include_directories(mylibrary PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>  
        $<INSTALL_INTERFACE:include>)

install(TARGETS mylibrary
        EXPORT mylibraryConfig
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

export(TARGETS mylibrary
        FILE "${CMAKE_CURRENT_BINARY_DIR}/mylibraryConfig.cmake")

install(EXPORT mylibraryConfig
        DESTINATION "${CMAKE_INSTALL_LIBDIR}/mylibrary/cmake"
        NAMESPACE mylibraryConfig::)

install(
        DIRECTORY include
        DESTINATION ${CMAKE_INSTALL_PREFIX})

install(FILES ${CMAKE_BINARY_DIR}/mylibrary.pc
    DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)

Which I successfully build and install with:

$ cmake .. -DCMAKE_INSTALL_PREFIX=~/libraries/local  # Use non-standard destination
$ make && make install

The executableCMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(myexecutable)

set(CMAKE_CXX_STANDARD 14)

find_package(mylibrary REQUIRED)

add_executable(myexecutable src/main.cpp)

target_link_libraries(myexecutable PUBLIC mylibrary)

target_include_directories(myexecutable PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

I can prepare cmake for this project:

$ cmake .. -DCMAKE_PREFIX_PATH=~/libraries/local # Use non-standard location

However, building it fails:

$ make
fatal error: mylibrary/library.h: No such file or directory
    2 | #include <mylibrary/library.h>

To my understanding the location of the library (binaries and headers) is embedded in the installed package. And through find_package() that information retrieved, so why isn't it working here?

Similar questions:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When a shared library target is namespaced in the config file you need to reference it with the full name in the downstream packages when using find_package, i.e. you need to use

target_link_libraries(myexecutable PUBLIC mylibraryConfig::mylibrary)

Alternatively, remove the namespace from the install by replacing

install(EXPORT mylibraryConfig
        DESTINATION "${CMAKE_INSTALL_LIBDIR}/mylibrary/cmake"
        NAMESPACE mylibraryConfig::)

...with:

install(EXPORT mylibraryConfig
        DESTINATION "${CMAKE_INSTALL_LIBDIR}/mylibrary/cmake")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...