我有一个使用cmake定义的共享库。该库的一部分调用一个需要由库用户实现的函数。
当我在Linux上编译它时,一切正常。当我在Cygwin下使用MingW交叉编译时,我得到了上述函数的链接错误,以及依赖库中的任何函数。
我的CMakeLists.txt指定" add_library"和" target_include_directories"库的关键字,例如:
add_library(my_library SHARED my_lib_1.c my_lib_2.c)
target_include_directories(my_library PUBLIC /usr/local/include PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)
为什么它在Linux上编译好,而不是Cygwin / MingW?
如何在Cygwin / MingW下编译?
非常感谢。
答案 0 :(得分:0)
http://edll.sourceforge.net/说:
许多人可能知道,DLL有一个限制:它们不能拥有 甚至一个未定义的符号。这意味着在您创建DLL时, 你必须将它与其他DLL链接,以获得所有未定义的 来自目标文件的符号以某种方式解析。
...
...对于DLL,这不能很好地工作,因为它不能有未定义的符号和 默认情况下,DLL不会链接回您的应用程序(EXE)。
或者用另一种方式说,“Windows不够用,设计不合理,而且通常都是垃圾,因此完全无法完成* nixes做的事情的一半而没有任何明显的努力”。
回答上面我自己的问题:
1)共享库编译在Linux上运行,因为Linux可以容忍未定义的符号。如果Linux / GCC在链接时不需要符号(因为它正在创建共享库)或者实际上没有链接(你需要链接以显示创建DLL,而不是创建共享库)它不需要一个。因为Windows的设计和体系结构不好,所以在创建DLL时需要链接所有符号,而不是在最后链接时满足所有符号(即链接可执行文件时),因此共享库编译失败。
2a)解决方案是在cmake中检测MingW编译,并为共享库用户生成导入库,并将共享库链接到该库以及所有其他依赖项。缺点是,如果我想将库作为一个独立的实体进行分发,这将需要大量的文档。
2b)第二个解决方案是重新构建我的共享库以解决此问题。就个人而言,我不愿意破坏我现有的整洁和细长的设计来解决操作系统的不足之处,我厌恶它的法西斯暴利和一般的无能。