Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CMake:在静态库中包含库依赖项_C++_Cmake - Fatal编程技术网

C++ CMake:在静态库中包含库依赖项

C++ CMake:在静态库中包含库依赖项,c++,cmake,C++,Cmake,我正在CMake中构建一个静态库,它依赖于许多其他静态库。我希望它们都包含在output.lib/.a文件中,这样我就可以向客户发送一个大的lib文件。在VisualStudio2010中,有一个选项“链接库依赖项”,它正是这样做的 但是我在CMake里找不到怎么做。您可以通过CMake设置此标志,或者通过其他方式获得相同的结果吗?我尝试了目标链接库(…)和添加依赖项(…),但CMake似乎只是忽略了静态库的这一行。好的,所以我有一个解决方案。首先,必须认识到静态库不会将其他静态库链接到代码中。

我正在CMake中构建一个静态库,它依赖于许多其他静态库。我希望它们都包含在output.lib/.a文件中,这样我就可以向客户发送一个大的lib文件。在VisualStudio2010中,有一个选项“链接库依赖项”,它正是这样做的


但是我在CMake里找不到怎么做。您可以通过CMake设置此标志,或者通过其他方式获得相同的结果吗?我尝试了目标链接库(…)和添加依赖项(…),但CMake似乎只是忽略了静态库的这一行。

好的,所以我有一个解决方案。首先,必须认识到静态库不会将其他静态库链接到代码中。必须创建一个组合库,这在Linux上可以通过
ar
完成。有关更多信息,请参阅

考虑两个源文件:

测试1.c: 测试2.c:
CMakeLists.txt
文件用于创建两个库,然后创建一个组合库,如下所示:

project(test)

    add_library(lib1 STATIC test1.c)
    add_library(lib2 STATIC test2.c)

    add_custom_target(combined ALL
      COMMAND ${CMAKE_AR} rc libcombined.a $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>)

这应该是独立于平台的,因为这是CMake用于在内部创建存档的命令结构。当然,您希望传递给存档命令的唯一选项是
rc
,因为这些选项已硬连接到
ar
命令的CMake中。

我想通过提供我的
CMakeLists.txt
文件来增强其他解决方案,该文件实际上在构建依赖项方面也起作用

解决误用CMake的问题

cmake_minimum_required(VERSION 2.8)

add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)
target_link_libraries(mainexec combinedLib)  # Important to place before add_custom_target

set(LIBNAME "combinedLib.lib")

add_custom_command(
    OUTPUT ${LIBNAME}
    COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
    DEPENDS lib1 lib2
    COMMENT "Combining libs..."
)

add_custom_target(combinedLib
    DEPENDS ${LIBNAME}
)
在我的例子中,这并不完全令人满意,因为
mainexec
必须了解
combinedLib
,尽管它希望所有依赖项都由
target\u link\u libraries
调用处理

耦合较少的替代解决方案

通过进一步查看导入的目标,我最终找到了解决我最后一个问题的解决方案:

cmake_minimum_required(VERSION 2.8)

add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)

set(LIBNAME "combinedLib.lib")

add_custom_command(
    OUTPUT ${LIBNAME}
    COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
    DEPENDS lib1 lib2
    COMMENT "Combining libs..."
)

add_custom_target(combinedLibGenerator
    DEPENDS ${LIBNAME}
)

add_library(combinedLib STATIC IMPORTED)
set_property(TARGET combinedLib PROPERTY IMPORTED_LOCATION ${LIBNAME})
add_dependencies(combinedLib combinedLibGenerator)

target_link_libraries(mainexec combinedLib)

就这样

您是否有需要链接的库的静态版本?或者你只有共享版本?那么当你说它没有在你的静态库中包含它们时,它是在试图将你的静态库与其他共享库相链接吗?我只有静态库,我只尝试构建一个静态库,所以没有链接发生。当第三方想要使用我的libs并且必须链接到很多其他东西时,问题就来了。谢谢,在Windows上这样做的相应方法是添加一个自定义命令“lib.exe/OUT:combined.lib 1.lib 2.lib”。在使用了一段时间后,我注意到了“ar”该命令非常粗略,生成的组合lib至少在某些gcc版本中不起作用。我认为我们最好不要尝试以这种方式进行静态链接。对我来说,只有第一次描述的add_custom_target命令起作用。为了使它真正独立于平台,文件名需要如下:
${CMAKE_STATIC_LIBRARY_PREFIX}组合${CMAKE_STATIC_LIBRARY_SUFFIX}
add_custom_target(combined ALL
   COMMAND ${CMAKE_CXX_ARCHIVE_CREATE} libcombined.a $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>)
cmake_minimum_required(VERSION 2.8)

add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)
target_link_libraries(mainexec combinedLib)  # Important to place before add_custom_target

set(LIBNAME "combinedLib.lib")

add_custom_command(
    OUTPUT ${LIBNAME}
    COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
    DEPENDS lib1 lib2
    COMMENT "Combining libs..."
)

add_custom_target(combinedLib
    DEPENDS ${LIBNAME}
)
set(LIBNAME "libCombinedLib.a")

add_custom_command(
    OUTPUT ${LIBNAME}
    COMMAND ar -rcT ${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
    DEPENDS lib1 lib2
    COMMENT "Combining libs..."
)
target_link_libraries(mainexec ${LIBNAME})
add_dependencies(mainexec combinedLib)
cmake_minimum_required(VERSION 2.8)

add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)

set(LIBNAME "combinedLib.lib")

add_custom_command(
    OUTPUT ${LIBNAME}
    COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
    DEPENDS lib1 lib2
    COMMENT "Combining libs..."
)

add_custom_target(combinedLibGenerator
    DEPENDS ${LIBNAME}
)

add_library(combinedLib STATIC IMPORTED)
set_property(TARGET combinedLib PROPERTY IMPORTED_LOCATION ${LIBNAME})
add_dependencies(combinedLib combinedLibGenerator)

target_link_libraries(mainexec combinedLib)
add_library(combinedLib INTERFACE)
target_link_libraries(combinedLib INTERFACE lib1 lib2)

target_link_libraries(mainexec combinedLib)