链接一个静态加速建设成为VS2012与功放下一个静态库;的Win32 / 64 [英] Linking a static boost build into a static library under VS2012 & Win32/64

查看:221
本文介绍了链接一个静态加速建设成为VS2012与功放下一个静态库;的Win32 / 64的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个静态库被释放,作为网络设备的API。我可以成功地编译和链接库来产生的.lib输出文件,我把他们重新安置到一个目录结构如下:

  EyeLib
 L-包括
 | L-PublicInterface.h
 L-库
 | L-调试
 | | L-MYLIB.LIB
 | | L-MyLib.pdb
 | L-发布
 | L-MYLIB.LIB
 L-MyLibConfig.cmake

凡MyLibConfig.cmake文件是非常简单的,并且包含:

 #头文件是相对于该文件的CMake,所以得到的路径。
GET_FILENAME_COMPONENT(MyLib_TOPLEVEL_DIR $ {} CMAKE_CURRENT_LIST_FILE PATH)
SET(MyLib_INCLUDE_DIR $ {} MyLib_TOPLEVEL_DIR /包括)IF(WIN32)
  FIND_LIBRARY(MyLib_DEBUG_LIBRARY MyLib中$ {} MyLib_TOPLEVEL_DIR / lib中/调试)
  FIND_LIBRARY(MyLib_RELEASE_LIBRARY MyLib中$ {} MyLib_TOPLEVEL_DIR / lib目录/释放)
  SET(MyLib_LIBRARIES优化$ {} MyLib_RELEASE_LIBRARY调试$ {} 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)#处理悄悄必需的参数
包括:(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'。

我可以得到测试程序来建立和成功运行,如果我把它添加到相同的项目库建设。我想这是因为库的构建是寻找刺激库进行链接,所以它通过传播到该项目的可执行文件。

我建提升1.54与B2链接=静态运行时链接=静态线程=多变量=调试,释放--layout =标签和链接这两个库构建和测试应用程序构建静态MSVC运行时(/ MT)

任何人都可以提供一些帮助/咨询/进一步与这个测试?我需要确保所有升压东西被编译,到API库,所以我们的客户不必安装提升自己。

其他信息

在-情况下,它是有帮助的,这里是从图书馆的构建文件的CMakeLists.txt:

 设置(LIBRARY_OUTPUT_PATH$ {} CMAKE_BINARY_DIR / lib目录)集(Boost_USE_STATIC_LIBS ON)
集(Boost_USE_MULTITHREADED ON)
find_package(升压所需的组件系统DATE_TIME正则表达式线程计时)
如果(不WIN32)
  列表(附加Boost_LIBRARIES的pthread)
万一()include_directories($ {} Boost_INCLUDE_DIRS)FILE(GLOB SRCS *的.cpp)
FILE(GLOB头的* .h)
集(LIBNAME MyLib中)集(DEPS $ {} Boost_LIBRARIES)q若要允许编译。 STD =的C ++ 0x是接受访问枚举,这通常只是与Visual Studio接受
IF(NOT WIN32)
  集(CMAKE_CXX_FLAGS-fpermissive -std =的C ++ 0x)
ENDIF(WIN32 NOT)SOURCE_GROUP($ {libname}里FILES $ {} SRCS)
SOURCE_GROUP($ {libname}里\\\\人类发展报告FILES $ {}头)
add_library($ {LIBNAME} $ {索马里红新月} $ {}头)
target_link_libraries($ {LIBNAME} $ {} DEPS)


解决方案

这是由设计。

在构建一个静态库,任何依赖该库将不会被直接链接到库中。而不是建立一个可执行的所有库依赖(直接和间接)将直接链接到可执行文件时。

这也是像大多数编译器手柄静态库。尽管VS确实提供了一个特殊的选项依赖链接到静态库,这是不可能的例如gcc的,而不诉诸脏文件的黑客。由于CMake的只支持可以在所有支持的发电机使用的功能,CMake的将不允许这样做即使在VS的基础之上。

您有几个选择现在:


  • 使用一个dll而不是静态库( add_library($ {libname}里SHARED ...))。而静态库是基本上一堆一起包裹对象文件,一个DLL是作为一个可执行或多或少是相同的。特别是,所有静态库的依赖关系得到直接链接到DLL。这里的缺点是,你必须处理与通常的DLL混乱:你必须指定其作用是出口,并通过跨越东西边界DLL适用通常的问题

  • 让您查找脚本还搜索所有的依赖关系。你应该能够调整你的库的依赖处理的方式,code复制量是最小的。缺点是配置一个第三方应用程序变得更加困难(特别是在Windows上),因为你现在不仅需要找到库本身,而且其所有相关的。

  • 使用出口目标的。这种方式最有意义,如果库是建立在同一台机器上最终的可执行文件。在构建库,CMake的自动生成的配置文件,使用该库。然后,应用程序只需要找到一个包含脚本,你是好去。缺点是出口机制不CMake的最直接的功能,所以你将不得不花一些时间来熟悉它。

  • 拉库源直接进入每个可执行。基本上每个可执行文件确实是 add_subdirectory 在库的源目录。你仍然需要配置的依赖关系为每个可执行文件,不仅如此,你还必须单独构建库为每个可执行顶部。你可能不希望这样做。

I'm trying to build a static library to be released as an API for a network device. I can successfully compile and link the library to produce .lib output files, and I relocate them into a directory structure as follows:

EyeLib
 L-Include
 |  L-PublicInterface.h
 L-Lib
 |  L-debug
 |  |   L-MyLib.lib
 |  |   L-MyLib.pdb
 |  L-release
 |      L-MyLib.lib
 L-MyLibConfig.cmake

Where the MyLibConfig.cmake file is extremely simple, and contains:

# 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 )

This build structure has worked for some test libraries I've built in the past, but I'm getting a link error when I try and use it to build a simple test app saying "error LNK1104: cannot open file 'libboost_thread-vc110-mt-s-1_54.lib'"

I can get the test app to build and run successfully if I add it to the same project as the library build. I assume this is because the library build is finding the boost libs to link against, so it propagates through to the executables in the project.

I built boost 1.54 with b2 link=static runtime-link=static threading=multi variant=debug,release --layout=tagged and linked both the library build and the test app build to the static MSVC runtime (/MT).

Can anyone offer some help/advice/further tests with this one? I need to make sure that all the boost stuff is compiled-in to the API library, so our clients don't have to install boost themselves.

Additional Info

In-case it's helpful, here's the cmakelists.txt file from the library build:

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} )

解决方案

This is by design.

When building a static library, any dependencies to that library will not get linked into the library directly. Instead when building an executable all library dependencies (direct and indirect) will be linked directly to that executable.

This is also the way most compiler handle static libraries. While VS does offer a special option to link dependencies into static libs, this is not possible on e.g. gcc without resorting to dirty file hacks. Since CMake only supports features that can be used on all supported generators, CMake will not allow to do this even on VS builds.

You have a couple of options now:

  • Use a dll instead of a static library (add_library(${libname} SHARED ...)). While a static library is basically a bunch of object files wrapped together, a dll is more or less the same as an executable. In particular, all static library dependencies get linked directly into the dll. The disadvantage here is that you have to deal with the usual dll mess: You have to specify which functions to export and the usual issues with passing stuff across dll boundaries apply.
  • Have your find script also search for all the dependencies. You should be able to restructure your library's dependency handling in a way that the amount of code duplication is minimal. The disadvantage is that configuring a third-party application becomes more difficult (especially on Windows) since you now not only need to find the library itself, but also all of its dependencies.
  • Use exported targets. This approach makes most sense if the library is built on the same machine as the final executable. Upon building the library, CMake auto-generates the config files for using that library. Your application then just needs to find an include that script and you're good to go. Disadvantage is that the export mechanism is not the most straight-forward feature of CMake, so you will have to spend some time to familiarize yourself with it.
  • Pull in the library sources directly into each executable. Basically each executable does an add_subdirectory on the library source dir. You still have to configure the dependencies for each executable and on top of that you also have to build the library seperately for each executable. You probably don't want to do this.

这篇关于链接一个静态加速建设成为VS2012与功放下一个静态库;的Win32 / 64的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆