![](/img/trans.png)
[英]stop cmake target_link_libraries linking both object files of static lib in addtion to the static lib itself
[英]Cmake link path error when linking static lib
我有一个 cmake 项目,其中包含我自己的 static 库和可执行文件。 简化的项目结构为:
顶级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"
)
基本上是项目直接依赖项的路径 - tesseract
和opencv
及其依赖项。
static 库的 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
)
构建时出现此错误:
忍者:错误:'C:/tesseract41_x64-static/leptonica_x64-windows-static/debug/lib/gif.lib','debug/mainproject/testexe.exe'需要,缺少并且没有已知的规则来制作它
为什么我会收到此错误,我该如何解决? 为什么leptonica
会在 leptonica 文件夹中寻找我的直接依赖项的子依赖项(在这种情况下gif
是tesseract
正方体的依赖项),而它们的路径不同,如您从LibsPath.cmake
中看到的那样? 我知道这不是tess
或leptonica
特定的问题,因为如果我将这些库更改为任何其他库,模式仍然存在,但我仍然会遇到相同的错误,但使用其他库。 所以我的 cmake 文件中一定有问题,但我不知道错误在哪里。
编辑:尝试更改链接到PUBLIC
的库并将相同的依赖项添加到 exe。 甚至尝试将子依赖项gif
链接到 exe - 仍然得到相同的错误。
测试静态库/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
)
以下可能会有所帮助,引用“通过套件掌握 cmake”:
CMAKE_PREFIX_PATH:这指定了 FIND_XXX() 命令将使用的路径。 它包含 FIND_XXX() 命令到 append 相应子目录的“基本”目录。 FIND_PROGRAM() 将 /bin 添加到路径中的每个目录; FIND_LIBRARY() 将 /lib 附加到路径中的每个目录
因此,我通常只是简单地制作某种库导入脚本并使用 PATHS/HINTS to find_library() 命令指向正确的目录。 据我所知,导入库目标的最可靠方法是不按原样使用 find_library(),而是使用 cmake INSTALL() 命令从该库生成导入脚本(如果可用)。 请参阅 find_library() 文档。
还链接 static 库有点奇怪。 它们被编译,但在生成最终的二进制文件之前,实际上没有任何东西链接到它们。 PRIVATE 库意味着链接的符号被密封在 static 库中,并且不会进一步继承依赖关系。 然后,PUBLIC 只需将 lib 添加到 LINK_INTERFACE_LIBRARIES/LINK_LIBRARIES 目标属性,并且依赖关系会一直延续到生成最终二进制文件。 (共享库或可执行文件)
请注意,我有 *nix 背景,如果在 windows 上构建,我可能会弄错一些细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.