45

我想控制在CMake中找到/链接到我的二进制文件的库的类型。最终目标是生成“尽可能静态”的二进制文件“”,即静态链接到每个具有可用静态版本的库。这一点非常重要,因为在测试过程中可以使不同系统的二进制文件可移植。CMake:如何生成尽可能静态的二进制文件“

ATM,这似乎是非常难以实现的FindXXX.cmake包,或者更准确地说是find_library命令总是拿起每当静态和动态两种可用的动态库。

有关如何实现此功能的提示 - 最好以优雅的方式 - 非常欢迎!

+0

不是很愚蠢:http://stackoverflow.com/questions/2113231/making-cmake-choose-static当可能时,这是GCC特定的。 – 2010-09-21 23:51:31

+0

事实上,它不仅仅是gcc特有的,它也是一个不方便的解决方案。在另一个问题上看到我的评论。 – pszilard 2010-09-22 11:06:05

+0

@pszilard你最终找到了解决方案吗?我正在尝试用g ++来做同样的事情。 – augustin 2010-10-28 10:02:04

回答

14

一个制作精良的FindXXX.cmake文件将包含这方面的内容。如果您查看FindBoost.cmake,则可以设置Boost_USE_STATIC_LIBS变量来控制它是否找到静态库或共享库。不幸的是,大多数软件包都没有实现这一点。

如果一个模块使用find_library命令(大多数人),那么你可以通过CMAKE_FIND_LIBRARY_SUFFIXES变量改变CMake的行为。下面是从FindBoost.cmake相关CMake的代码使用:

IF(WIN32) 
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
ELSE(WIN32) 
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
ENDIF(WIN32) 

您可以调用find_package前把这个,或者更好的,你可以修改.cmake文件本身,并回馈给社会做出贡献。

因为我在我的项目中使用.cmake文件,我把所有的人都在自己的文件夹源控制范围内。我这样做是因为我发现为某些库准备正确的.cmake文件是不一致的,保留我自己的副本允许我进行修改,并确保签出代码的每个人都具有相同的生成系统文件。

+0

感谢您的评论,我实际上在同时得出结论,上述是唯一可行的解​​决方案来获取静态版本的外部库检测。但是,这是一种非常肮脏的方式,我宁愿不必指定后缀。不幸的是,基于对CMake邮件列表的讨论,似乎Windows有一个相当混乱的库命名,因此没有计划正确实施它。不过,这应该适用于大多数* NIX系统。 – pszilard 2010-11-08 18:47:51

+0

请注意,如果您只想*检测静态库(因此可能会导致配置失败,那么上述命令不应将静态库文件名预先添加到CMAKE_FIND_LIBRARY_SUFFIXES中,而应将该变量设置为这些文件名,这会抑制find_ *()函数使用通常的后缀 – mabraham 2014-11-20 00:36:59

+1

来获取共享库请注意,如果在隐式链接目录(例如系统路径)中找到库,FindXXXX.cmake包的“制作精良”并不重要。在这种情况下,还原为-XXXXX以允许链接器使用其正常分辨率 - 请参阅http://public.kitware.com/pipermail/cmake/2015-January/059702.html – mabraham 2015-02-19 23:37:09

26

我做了一些调查,虽然找不到令人满意的解决方案,但我确实找到了一个解决方案。

静态的问题建立归结为三件事情:

  1. 建设和链接项目的内部库。

    很简单,一个只是有翻转BUILD_SHARED_LIBS开关OFF

  2. 查找静态版本的外部库。

    的唯一方法似乎是设置CMAKE_FIND_LIBRARY_SUFFIXES包含所需的文件后缀(ES)(这是一个优先级列表)。

    该解决方案是一个相当“脏”的一个非常反对的CMake的跨平台的愿望。恕我直言,这应该由CMake在幕后处理,但据我了解,由于Windows上的“.lib”混淆,似乎CMake开发人员更喜欢当前的实现。

  3. 静态链接系统库。

CMake提供了一个选项LINK_SEARCH_END_STATIC,该选项基于以下文档:“结束使用静态系统库的链接行。“ 有人会认为,就是这样,问题就解决了。但是,似乎目前的实现不能胜任任务。如果选项打开,CMake会生成一个带有参数列表的隐式链接器调用,参数列表以传递给链接器的选项包括-Wl,-Bstatic但是,这还不够,只是指示链接器静态链接导致错误,在我的情况下:/usr/bin/ld: cannot find -lgcc_s。缺少的是告诉gcc以及我们需要静态链接-static参数,它是产生由C进行连接电话。我认为这是一个错误,但我没有设法从开发商的确认。

最后,我认为这一切可以而且应该由CMake在幕后完成,毕竟它不是那么复杂,除了它在Windows上是不可能的 - 如果这个数字很复杂... ...

+1

不应将“BUILD_SHARED_LIBS”设置为关闭(所以它*不会*建立共享库)? – Nooble 2015-06-30 13:50:00

+0

哈哈,在将近五年你是第一个注意到这个错误的人。谢谢。 – pszilard 2015-07-02 10:54:29

相关问题