C++ 使用 CMake 和 GCC 在 Mac 上构建静态库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4929255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:56:13  来源:igfitidea点击:

Building static libraries on Mac using CMake and GCC?

c++macosgcccmakestatic-libraries

提问by Ashika Umanga Umagiliya

Greetings all,

问候大家,

I have a static library which I later link with my application. My development environment is CMake, GCC (Linux, Mac), MinGW (Windows).

我有一个静态库,稍后我将其与我的应用程序链接。我的开发环境是 CMake、GCC(Linux、Mac)、MinGW(Windows)。

I can compile the static library without any problem on Linux and Windows. (I can even build shared libraries in my application on Mac).

我可以在 Linux 和 Windows 上毫无问题地编译静态库。(我什至可以在 Mac 上的应用程序中构建共享库)。

EDIT: I compiled the library as a SHARED library and it worked fine!!

编辑:我将该库编译为共享库,并且运行良好!!

I have configured CMakeFile as follows to build the static library:

我已按如下方式配置 CMakeFile 来构建静态库:

add_library(centi STATIC ${base_srcs} ${crv_srcs} ${node_srcs} ${trnk_srcs} ${defl_srcs} ${infl_srcs} ${track_srcs} ${callback_srcs} ${extract_srcs})

During linking phase, it gives following errors and build the "libcenti.a" somehow.

在链接阶段,它会给出以下错误并以某种方式构建“libcenti.a”。

Linking C static library
lib/libcenti.a /usr/bin/ranlib: file:
lib/libcenti.a(crv_in_rgn_to_bnry_img.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_initialize_by_circle.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_initialize_flgs.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_nodal_interval_min_and_max.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_remove_all_nodes.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_reset_nodal_forces.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_set_center_coords.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_set_left_ptch_rgn_pixs.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_set_out_rgn_mean_and_var.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_set_para.c.o) has
no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_set_right_ptch_rgn_pixs.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_to_in_rgn_hist.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(crv_to_out_rgn_pixs.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(trnk_initialize_by_circle.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(trnk_initialize_by_image_frame.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(trnk_stk_paint_nodes_and_pixs.c.o)
has no symbols /usr/bin/ranlib: file:
lib/libcenti.a(trnk_stk_to_inner_defl_ordn.c.o)
has no symbols

But when I link above library with my application, it gives "Undefined symbols" errors:

但是当我将上面的库与我的应用程序链接时,它给出了“未定义的符号”错误:

Undefined symbols:  
"_setActiveDrawingTrunk", referenced
from:
      RzPluginAlgoCnty::initCallBacks()     
in RzPluginAlgoCnty.cpp.o
      RzPluginAlgoCnty::clearCallBacks()    
in RzPluginAlgoCnty.cpp.o
      _trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _bg_trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _bg_trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _extract_contour_update_tracking in
libcenti.a(extract_contour_update_tracking.c.o)
      _extract_contour_update_tracking in
libcenti.a(extract_contour_update_tracking.c.o)
"_updateCurveUICallBack", referenced
from:
      RzPluginAlgoCnty::initCallBacks()     
in RzPluginAlgoCnty.cpp.o
      RzPluginAlgoCnty::initBulkCallBacks() 
in RzPluginAlgoCnty.cpp.o
      RzPluginAlgoCnty::clearCallBacks()    
in RzPluginAlgoCnty.cpp.o
      _bg_trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _bg_trnk_trck_ordn in libcenti.a(trnk_trck_ordn.c.o)
      _crv_update_1time in libcenti.a(crv_update_ordn.c.o)
      _crv_update_1time in libcenti.a(crv_update_ordn.c.o) ld:
symbol(s) not found

Any tips ? Should I add any special parameters when building static libraries on Mac?

有小费吗 ?在 Mac 上构建静态库时是否应该添加任何特殊参数?

EDIT: I compiled the library as a SHARED library and it worked fine!!

编辑:我将该库编译为共享库,并且运行良好!!

采纳答案by osgx

The similar problem with static libraries on MacOSX is discussed here: http://lists.macosforge.org/pipermail/macports-tickets/2008-June/010680.html

MacOSX 上的静态库的类似问题在这里讨论:http: //lists.macosforge.org/pipermail/macports-tickets/2008-June/010680.html

Try to do a full clean and run a not-parallel build.

尝试进行完全清理并运行非并行构建。

And this guiderecommends to install macports, then "sudo port install autogen autoconf automake nano libtool libsdl patchutils subversion wget gmake", and then export PATH="/usr/local/bin:/usr/local/sbin:$PATH"

而且本指南推荐安装macports,然后“sudo port install autogen autoconf automake nano libtool libsdl patchutils subversion wget gmake”,然后export PATH="/usr/local/bin:/usr/local/sbin:$PATH"

回答by russes

Unfortunately, setting -no_warning_for_no_symbolsmay not be enough. The arcommand on the Mac will run ranlibfor you, which causes the "has no symbols /usr/bin/ranlib" message to be displayed. You can stop this message on the Mac by using the following CMake rules:

不幸的是,设置-no_warning_for_no_symbols可能还不够。该AR在Mac上的命令将运行ranlib的你,这会导致“已经没有符号的/ usr / bin中/ ranlib的”要显示的消息。您可以使用以下 CMake 规则在 Mac 上停止此消息:

SET(CMAKE_C_ARCHIVE_CREATE   "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_FINISH   "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")

The ARCHIVE_CREATE "Scr" setting will keep arfrom running ranlib for you. The ARCHIVE_FINISH setting will gag ranlibfrom complaining about missing symbols.

ARCHIVE_CREATE "Scr" 设置将阻止ar为您运行 ranlib。ARCHIVE_FINISH 设置将使ranlib不再抱怨缺少符号。

You need to use both sets of rules to gag "no symbols" message.

您需要使用两组规则来屏蔽“无符号”消息。

One more thing for CMake newbies: The commands CMake generates for the arand ranlibcommands are dumped into a link.txt file. If you're having problems generating archives, you may want to look at link.txt to see what CMake is doing for you.

CMake 新手的另一件事:CMake 为arranlib命令生成的命令被转储到 link.txt 文件中。如果您在生成档案时遇到问题,您可能需要查看 link.txt 以了解 CMake 为您做什么。

回答by Jonathan Leffler

The warnings from ranlibindicate that those object files contained no operational code. You need to review each corresponding source file to see whether the code it contains should be compiled on Mac. It may be that the code was ported elsewhere but the conditional compilation doesn't recognize Mac correctly.

来自的警告ranlib表明这些目标文件不包含操作代码。您需要查看每个对应的源文件,看看它包含的代码是否应该在 Mac 上编译。可能是代码被移植到别处,但条件编译不能正确识别 Mac。

It isn't a 'slam dunk' diagnosis; the missing symbols are clearly in two groups - those related to trnkand those related to crv- and the files are likewise in two groups (prefixed trnkand crv), but it could be that the files define different functions. So, I would go looking at the source files corresponding to the empty object files and see if you can see the missing functions (probably ignore the leading underscore on the reported missing symbol names). If those functions are defined in those files, then you have to look at the complaints from ranlib.

这不是“灌篮”的诊断;丢失的符号显然分为两组 - 相关的trnk和相关的crv- 并且文件同样分为两组(前缀trnkcrv),但可能是文件定义了不同的功能。因此,我会查看与空目标文件相对应的源文件,看看您是否可以看到丢失的函数(可能忽略报告的丢失符号名称上的前导下划线)。如果这些函数是在这些文件中定义的,那么您必须查看ranlib.

Occasionally, if you ran out of disk space at an inconvenient moment, you could have zero-size object files (which contain no symbols, therefore). In that case, simply remove the empty object files (and free up some space, but you must already have done that) and build again.

有时,如果您在不方便的时候用完了磁盘空间,您可能会拥有零大小的目标文件(因此不包含任何符号)。在这种情况下,只需删除空的目标文件(并释放一些空间,但您必须已经这样做了)并再次构建。