我至少有三种方法可以做到这一点,我想知道哪种方式是惯用的.这几乎普遍适用于任何静态库.我很惊讶CMake中的Makefile生成器不会自动将其添加到静态库中.(除非我错过了什么?)
target_compile_options(myLib PRIVATE -fPIC)
add_compile_options(-fPIC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic")
Run Code Online (Sandbox Code Playgroud)
我相信可能还有其他变化.(如果你找到一个,请编辑我的问题)
如果您碰巧知道这个问题的答案,您是否也知道是否有办法使用此标志编译第三方CMake项目而不修改其CMakeLists.txt文件?我遇到了缺少该标志的静态库.将静态库编译为动态库时会导致问题.
你得到:
relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
Run Code Online (Sandbox Code Playgroud) 我有以下布局:
top_project
+ subproject1
+ subproject2
Run Code Online (Sandbox Code Playgroud)
每个subproject1并subproject2创建一个静态库.我想在这个top_project级别的单个共享库中链接这些静态库.
我到目前为止收集的信息是:
-fPic(除了Windows之外的所有内容)进行编译以创建与位置无关的代码,这将允许将静态库链接到单个共享库或解压缩所有静态库(例如使用ar)并将它们重新链接到共享库(其中我认为这是一个不优雅和不便携的解决方案)add_library命令:由于某些我无法理解的原因,简单地写入add_library(${PROJECT_NAME} SHARED subproject1 subproject2)不能按预期工作(它实际上创建了一个空库并且没有正确地注册依赖项)有什么想法吗?
我正在使用Visual Studio 2008 SP1(专业版,适用于32位和64位版本).我正在寻找一种解决方法,我认为这是Visual Studio中一个非常无益的" 限制 ".
我觉得很奇怪,在Visual Studio连接器和编译器不以DLL文件的创建时间这一权利,自动扫描所有导出的符号所有指定的静态库中所示的相同的方式构建一个导入库和导出文件,并在一StackOverflow评论.我确认仅仅在组成静态库的文件中应用__declspec(dllexport)和__declspec(dllimport)属性类,函数和数据声明是不够的
.
链接器不扫描导出符号的所有静态库,因此不会将它们拉入DLL文件(符号必须由.objDLL链接命令行上的文件或我在下面显示的其他方式引用).如果没有对每个导出符号的显式引用,仍可能会创建DLL文件,但不会创建其关联的导入库文件.
根据我的收集,Microsoft建议使用LIB.EXE 来创建DEF文件,但不幸的是,LIB.EXE页面应用了一个约束:
请注意,如果您在创建导入库之前创建导入库,则在构建导入库时,必须在构建导入库时
.dll传递相同的目标文件集.dll.
鉴于我在新的构建环境中也使用了CMake,这是一个不幸的约束.CMake隐藏了实际传递给链接器的细节(我认为这在99%的时间里都是好事),但在这种情况下我需要在CMake执行时访问一些信息,而不是然后使用手工制作的脚本或其他脆弱的skulduggery.
如何强制DLL链接器解析构成DLL文件的所有静态库中的所有导出符号,这不会导致脆弱性和额外的构建逻辑维护工作?在这里考虑全自动化,并记住我需要多次为多个不同的DLL执行此操作.
我的问题是:
如何仅使用CMake语法获取最终DLL链接命令行上使用的目标文件和静态库集?
有没有更好的方法来解决这个问题,在调用最终链接之前不需要调用单独的实用程序,例如LIB.EXE ?我担心LIB.EXE链接本身之外的额外构建开销会再次重新扫描所有静态库 ,即使它只是在单独的执行中写出来.
以下是我现在无法考虑的解决方案:
在原始文件.h或.cpp文件之外的任何地方手动指定未引用的符号,因为每次开发人员忘记更新列出(很可能是名称错位的)符号名称的文件时,这样做会中断.并且它将打破关于未解析符号的非用户友好链接器错误,这对于开发人员来说将是昂贵的调试.这个非答案包括以下方法:
明确地将.obj文件添加到DLL链接命令行中(其中的变体包括添加"假" .obj文件,这些文件具有对未引用但导出的符号的虚拟引用(并注意这是我的旧构建环境今天所做的,并且它很臭) ),和,
手工制作DEF文件以包含未引用但导出的符号,以及 …