我正在尝试构建一个静态库,作为网络设备的API发布。我可以成功编译和链接库以生成.lib输出文件,并将它们重新定位到目录结构中,如下所示:
EyeLib
L-Include
| L-PublicInterface.h
L-Lib
| L-debug
| | L-MyLib.lib
| | L-MyLib.pdb
| L-release
| L-MyLib.lib
L-MyLibConfig.cmake
MyLibConfig.cmake文件非常简单,包含:
# the header file is relative to this cmake file, so get the path.
GET_FILENAME_COMPONENT( MyLib_TOPLEVEL_DIR ${CMAKE_CURRENT_LIST_FILE} PATH )
SET( MyLib_INCLUDE_DIR ${MyLib_TOPLEVEL_DIR}/include )
IF( WIN32 )
FIND_LIBRARY( MyLib_DEBUG_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib/debug )
FIND_LIBRARY( MyLib_RELEASE_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib/release )
SET( MyLib_LIBRARIES optimized ${MyLib_RELEASE_LIBRARY} debug ${MyLib_DEBUG_LIBRARY} )
ENDIF( WIN32 )
IF( UNIX )
FIND_LIBRARY( MyLib_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib )
SET( MyLib_LIBRARIES "${MyLib_LIBRARY}" )
MARK_AS_ADVANCED( MyLib_LIBRARY )
ENDIF( UNIX )
# handle the QUIETLY and REQUIRED arguments
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MyLib DEFAULT_MSG MyLib_LIBRARIES MyLib_INCLUDE_DIR)
MARK_AS_ADVANCED( MyLib_INCLUDE_DIR )
这个构建结构适用于我过去构建的一些测试库,但是当我尝试使用它来构建一个简单的测试应用程序“错误LNK1104:无法打开文件”libboost_thread时,我收到链接错误-vc110-MT-S-1_54.lib'“
如果我将测试应用程序添加到与库构建相同的项目中,我可以成功构建并运行测试应用程序。我假设这是因为库构建正在查找要链接的boost库,因此它会传播到项目中的可执行文件。
我使用b2建立了boost 1.54 = static runtime-link = static threading = multi variant = debug,release --layout = tagged并将库构建和测试应用程序构建链接到静态MSVC运行时(/ MT)
有人可以提供一些帮助/建议/进一步测试吗?我需要确保将所有增强内容编译到API库中,这样我们的客户就不必自己安装boost。
其他信息
以防它有用,这是来自库构建的cmakelists.txt文件:
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost REQUIRED COMPONENTS system date_time regex thread chrono)
if(NOT WIN32)
list(APPEND Boost_LIBRARIES pthread)
endif()
include_directories(${Boost_INCLUDE_DIRS})
FILE(GLOB srcs *.cpp)
FILE(GLOB headers *.h)
set(libname MyLib)
set(deps ${Boost_LIBRARIES})
#To allow compilation. std=c++0x is for accepting the access to enums, which usually is just accepted with Visual Studio
IF( NOT WIN32 )
set (CMAKE_CXX_FLAGS "-fpermissive -std=c++0x")
ENDIF( NOT WIN32 )
SOURCE_GROUP( ${libname} FILES ${srcs} )
SOURCE_GROUP( "${libname}\\Hdr" FILES ${headers} )
add_library(${libname} ${srcs} ${headers})
target_link_libraries( ${libname} ${deps} )
答案 0 :(得分:8)
这是设计的。
构建静态库时,该库的任何依赖项都不会直接链接到库中。相反,在构建可执行文件时,所有库依赖项(直接和间接)都将直接链接到该可执行文件。
这也是大多数编译器处理静态库的方式。虽然VS确实提供了将依赖关系链接到静态库的特殊选项,但是在例如gcc没有诉诸脏文件黑客。由于CMake仅支持可在所有支持的生成器上使用的功能,因此即使在VS版本上,CMake也不允许这样做。
您现在有几个选择:
add_library(${libname} SHARED ...)
)。虽然静态库基本上是一堆包装在一起的目标文件,但是dll与可执行文件大致相同。特别是,所有静态库依赖项都直接链接到dll。这里的缺点是你必须处理通常的dll混乱:你必须指定要导出的函数以及跨越dll边界传递东西的常见问题。add_subdirectory
。您仍然必须为每个可执行文件配置依赖项,并且还必须为每个可执行文件单独构建库。你可能不想这样做。