2016-08-10 58 views
-1

我试图创建一个项目,这将创建一个可执行MyExec.exe,这将依赖于另一个库Niftilib,其本身取决于的zlibVS2015如何将静态库链接到其他库和可执行文件?

我做什么,我用cmake并创造了superbuild,使用ExternalProject_Add下载和编译zlib的

ExternalProject_Add(Zlib 
    SOURCE_DIR "${PROJECT_BINARY_DIR}/deps/zlib" 
    BINARY_DIR "${PROJECT_BINARY_DIR}/deps/zlib-build" 
    INSTALL_DIR "${PROJECT_BINARY_DIR}/deps/zlib-install" 
    GIT_REPOSITORY "${git_protocol}://github.com/madler/zlib.git" 
    GIT_TAG "50893291621658f355bc5b4d450a8d06a563053d" 
    CMAKE_ARGS 
     -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> 
     -DINSTALL_BIN_DIR=<INSTALL_DIR>/bin 
     -DINSTALL_INC_DIR=<INSTALL_DIR>/include 
     -DINSTALL_LIB_DIR=<INSTALL_DIR>/lib 
     -DINSTALL_MAN_DIR=<INSTALL_DIR>/share/man 
     -DINSTALL_PKGCONFIG_DIR=<INSTALL_DIR>/share/pkgconfig) 

我也做了同样的Nifticlib

ExternalProject_Add(Nifticlib 
    SOURCE_DIR "${PROJECT_BINARY_DIR}/deps/nifticlib" 
    BINARY_DIR "${PROJECT_BINARY_DIR}/deps/nifticlib-build" 
    INSTALL_DIR "${PROJECT_BINARY_DIR}/deps/nifticlib-install" 
    GIT_REPOSITORY "${git_protocol}://gitlab.com/slckr/nifticlib.git" 
    GIT_TAG "9f427b39eb6a16822c6ed34454f87eb751b23220" 
    CMAKE_ARGS 
     -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> 
     -DZLIB_INCLUDE_DIR=${ZLIB_INC_DIR} 
     -DZLIB_LIBRARY_DEBUG=${ZLIB_LIB_DIR}/zlibd.lib 
    DEPENDS Zlib) 

然后我做了同样的MyExec

ExternalProject_Add(MyExec 
    SOURCE_DIR "${PROJECT_BINARY_DIR}/MyExec" 
    BINARY_DIR "${PROJECT_BINARY_DIR}/MyExec-build" 
    INSTALL_DIR "${PROJECT_BINARY_DIR}/MyExec-install" 
    GIT_REPOSITORY "${git_protocol}://gitlab.com/slckr/MyExec.git" 
    GIT_TAG "8514aacf5422f1111602e24ea73b229556293b8c" 
    CMAKE_ARGS 
     -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> 
     -DBOOST_INC_DIR=${Boost_INCLUDE_DIRS} 
     -DBOOST_LIB_DIR=${Boost_LIBRARY_DIRS} 
     -DZLIB_INC_DIR=${ZLIB_INC_DIR} 
     -DZLIB_LIB_DIR=${ZLIB_LIB_DIR} 
     -DNIFTI_INC_DIR=${NIFTI_INC_DIR} 
     -DNIFTI_LIB_DIR=${NIFTI_LIB_DIR} 
    DEPENDS Nifticlib) 

在我MyExec项目CMakeLists,我有这样的:

cmake_minimum_required(VERSION 3.6) 

project(MyExec) 

include_directories(${BOOST_INC_DIR} ${ZLIB_INC_DIR} ${NIFTI_INC_DIR}) 
link_directories(${BOOST_LIB_DIR} ${ZLIB_LIB_DIR} ${NIFTI_LIB_DIR}) 

add_subdirectory(DataStructure) 
add_subdirectory(FileHandler) 
add_subdirectory(Parser) 

add_executable(${PROJECT_NAME} MyExec.cc) 
target_link_libraries(${PROJECT_NAME} zlibd znz nifticdf niftiio DataStructure FileHandler Parser) 

install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) 

我的目标是能够无需所有需要的库文件(除升压)分发MyExec.exe。我希望将nifticlib库嵌入到我的exec中。

如果我这样编译,它不起作用,因为它说zlibd.dll丢失。我发现我必须将可执行文件链接到zlibstaticd而不是zlibd。

但我的问题是,我也应该改变 - DZLIB_LIBRARY_DEBUG=${ZLIB_LIB_DIR}/zlibd.lib到 - DZLIB_LIBRARY_DEBUG=${ZLIB_LIB_DIR}/zlibstaticd.lib在Nifticlib项目?

或者它只在可执行项目中起作用吗?为什么nifticlib要求我提供zlib库的路径,如果它是作为静态库构建的并且不执行任何链接?

谢谢。

编辑:如果我不zlib的链接到我的可执行文件,我得到这些错误:

5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzdopen referenced in function znzdopen 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzread referenced in function znzread 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzwrite referenced in function znzwrite 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzputs referenced in function znzputs 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzgets referenced in function znzgets 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzputc referenced in function znzputc 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzgetc referenced in function znzgetc 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzflush referenced in function znzflush 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzeof referenced in function znzeof 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzclose referenced in function Xznzclose 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzopen referenced in function znzopen 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gzseek referenced in function znzseek 
5>znz.lib(znzlib.obj) : error LNK2019: unresolved external symbol gztell referenced in function znztell 

ZNZ是nifticlib的一部分。它是使用zlib库的部分。

编辑2:,使其更简单,我的问题是它的连接发生像链接1或链接2(明知nifticlib依赖于zlib的,无论是编译为静态库):

Linking 1       Linking 2 
--------------   --------------  --------------- 
| zlib |   | zlib |  | nifticlib | 
--------------   --------------  --------------- 
     |       \     /
--------------     \    /
| nifticlib |     \    /
--------------      \   /
     |       ------------------- 
--------------     | MyExec.exe | 
| MyExec.exe |     ------------------- 
-------------- 
+0

如果我理解正确,_Niftilib_取决于_zlib_并且您想要将您的应用程序与_Niftilib_链接。不,在执行中并不重要。项目,但它在_Niftilib_ lib中很重要。以及。但是,在VS中,我不使用CMake,当您创建一个静态链接(依赖于另一个静态链接)时,可以通过Configuration Properties - > Librarian - > General - > Additional Dependencies将其链接(在Niftilib项目中的zlib)。所以我认为,是的,你应该改变它,并可能跳过执行。项目。希望这有助于;-) – Dom

+0

我想如果我在exec中跳过它,MyExec项目不会编译。它在链接步骤失败,因为它无法找到符号。我的问题是,如果我编译依赖于zlib的niftilib,zlib符号是否会包含在niftilib.lib中?我是否也需要将它链接到MyExec?谢谢。 – whiteShadow

+0

您是否尝试在exec中跳过它?如果你不直接从exec调用zlib函数,它应该只在niftlib中链接,不应该在exec中设置,我想是这样......不幸的是我不确定......: - /试一试。 – Dom

回答

1

的通常的方式是链接只在生成可执行二进制文件时完成。这包括例如正常的可执行文件,但也包括动态库(.dll,.so)。链接不是为静态库(.lib,.a)完成的。

这意味着如果你建立一个“nifticlib”静态库,它不需要链接到“zlib”。

您应该明确地将依赖关系从动态更改为静态,因为CMake会将静态库的依赖关系携带到最终的二进制文件。在这种情况下,它应该没有问题,因为你没有指定一个真正的CMake依赖项,只是库的一些变量。

注意:在Visual Studio中,您可以非常容易地将静态库“链接”到彼此中。它所做的只是将所有函数串联到一个.lib文件中。不过,CMake并没有使用这个特性,而是在静态库目标上执行“TARGET_LINK_LIBRARIES”时,像上面提到的那样依赖于它。

+0

好的,谢谢。所以它更像链接2.它现在很有意义。我检查了nifticlib以及它为什么向我要求zlibd.lib,但我认为这是因为nifticlib正在编译一些单元测试(可执行文件),所以它也需要将它们链接到zlib。所以即使我不使用这些可执行文件,它们也会被编译。 – whiteShadow

+0

@whiteShadow Ups ...对不起,我没有意识到,链接是关于动态库。这个答案必须是正确的。 – Dom

+0

@Dom没有它是关于静态库 – whiteShadow

相关问题