gpt4 book ai didi

c++ - 链接静态库时CMake链接路径错误

转载 作者:行者123 更新时间:2023-12-01 14:43:04 24 4
gpt4 key购买 nike

我有一个cmake项目,其中包含我自己的静态库和可执行文件。简化的项目结构为:

顶级cmake:

cmake_minimum_required(VERSION 3.16)

project(mainproject
VERSION 0.0.1
DESCRIPTION ""
LANGUAGES CXX
)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

#include libs
include(LibsPath)

add_subdirectory(teststaticlib)
add_subdirectory(testexe)

cmake / LibsPath.cmake:
        set(CMAKE_PREFIX_PATH
"C:/tesseract41_x64-static/leptonica_x64-windows-static"
"C:/tesseract41_x64-static/tiff_x64-windows-static"
"C:/tesseract41_x64-static/tesseract_x64-windows-static"
"C:/tesseract41_x64-static/libpng_x64-windows-static"
"C:/tesseract41_x64-static/libjpeg-turbo_x64-windows-static"
"C:/tesseract41_x64-static/giflib_x64-windows-static"
"C:/tesseract41_x64-static/libwebp_x64-windows-static"
"C:/opencv4_x64-windows-static"
"C:/protobuf_x64-windows-static"
"C:/hdf5_x64-windows-static"
"C:/szip_x64-windows-static"
)

基本上,是项目直接依赖项的路径- tesseractopencv及其依赖项。

静态库的Cmake文件(teststaticlib / CMakeLists.txt):
cmake_minimum_required(VERSION 3.16)

project(teststaticlib)

set(CMAKE_GENERATOR "Ninja")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

#enable unicode
add_definitions(-DUNICODE -D_UNICODE)

set(SOURCE_FILES
#...source files
)
set(PRIVATE_HEADER_FILES
#... header files
)
set(PUBLIC_HEADER_FILES
#... header files
)
add_library(teststaticlib STATIC ${SOURCE_FILES} ${PRIVATE_HEADER_FILES} ${PUBLIC_HEADER_FILES})
add_library(teststaticlib::teststaticlib ALIAS teststaticlib)
set_target_properties(teststaticlib PROPERTIES OUTPUT_NAME teststaticlib)
target_include_directories(teststaticlib
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)

#precompiled headers
target_precompile_headers(teststaticlib PRIVATE src/pch.h)

#link libs
find_package(tesseract CONFIG REQUIRED)
find_package(opencv CONFIG REQUIRED core imgproc highgui)

include_directories(${Tesseract_INCLUDE_DIRS})
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(teststaticlib
PRIVATE
${Tesseract_LIBRARIES}
${OpenCV_LIBS}
)

到目前为止,一切都很好。 teststaticlib.lib构建良好,没有任何错误。
但是,一旦我将任何可执行文件添加到项目并将 teststaticlib链接到它:

testexe / CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

project(testexe)

set(SOURCE_FILES
main.cpp
)
add_executable(testexe ${SOURCE_FILES})

target_link_libraries(testexe
PRIVATE
teststaticlib::teststaticlib
)

构建时出现此错误:

ninja: error: 'C:/tesseract41_x64-static/leptonica_x64-windows-static/debug/lib/gif.lib', needed by 'debug/mainproject/testexe.exe', missing and no known rule to make it



为什么会出现此错误,以及如何解决?
当cmake的路径不同时,为什么cmake在leptonica文件夹中寻找我直接依赖的子依赖(在这种情况下 giftesseractleptonica的依赖),正如您从 LibsPath.cmake看到的那样,它们的路径不同?
我知道这不是 tessleptonica的特定问题,因为如果我将这些库更改为其他库,则模式仍然存在,但仍然会出现与其他库相同的错误。
因此,我的cmake文件中肯定有问题,但是我无法弄清楚错误在哪里。

编辑:
试图更改我的库链接到 PUBLIC并将相同的依赖项添加到exe。即使尝试将子依赖性 gif链接到exe-仍然会得到相同的错误。

teststaticlib / CMakeLists.txt:
target_link_libraries(teststaticlib 
PUBLIC
${Tesseract_LIBRARIES}
${OpenCV_LIBS}
)

testexe / CMakeLists.txt
    cmake_minimum_required(VERSION 3.16) 
project(testexe)

set(SOURCE_FILES
main.cpp
)
add_executable(testexe ${SOURCE_FILES})

find_package(tesseract CONFIG REQUIRED)
find_package(opencv CONFIG REQUIRED core imgproc highgui)
find_package(gif REQUIRED)
include_directories(${Tesseract_INCLUDE_DIRS})
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${GIF_INCLUDE_DIRS})

target_link_libraries(testexe
PRIVATE
${GIF_LIBRARIES}
${Tesseract_LIBRARIES}
${OpenCV_LIBS}
basicemul::basicemul
)

最佳答案

以下内容可能会有所帮助,请引用“通过kitware掌握cmake”中的内容:

CMAKE_PREFIX_PATH: This specifies a path that will be used by the FIND_XXX() commands. It contains the "base" directories for the FIND_XXX() commands to append appropriate sub-directories to. FIND_PROGRAM() adds /bin to each of the directories in the path; FIND_LIBRARY() appends /lib to each of the directories in the path



因此,我通常只是简单地制作某种类型的库导入脚本,然后使用PATHS / HINTS来find_library()命令指向正确的目录。
据我所知,最有效的导入库目标的方法是不按原样使用find_library(),而是使用cmake INSTALL()命令从该库生成的导入脚本(如果可用)。
参见find_library() docs

同样链接静态库有点奇怪。它们会被编译,但实际上没有任何链接到它们,直到生成最终二进制文件为止。 PRIVATE库的意思是链接的符号被密封在静态库中,并且依赖项不会再继续继承。然后,PUBLIC只需将库添加到LINK_INTERFACE_LIBRARIES / LINK_LIBRARIES目标属性中,并将依赖项保留下来,直到生成最终二进制文件为止。 (共享库或可执行文件)

请注意,我具有* nix背景,如果在Windows上构建,可能会弄错一些细节。

关于c++ - 链接静态库时CMake链接路径错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61207911/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com