Building static libraries on Mac using CMake and G

2019-01-24 04:53发布

问题:

Greetings all,

I have a static library which I later link with my application. My development environment is 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).

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

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

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.

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?

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

回答1:

The similar problem with static libraries on MacOSX is discussed here: 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 guide recommends 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"



回答2:

Unfortunately, setting -no_warning_for_no_symbols may not be enough. The ar command on the Mac will run ranlib for 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:

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 ar from running ranlib for you. The ARCHIVE_FINISH setting will gag ranlib from complaining about missing symbols.

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 ar and ranlib commands 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.



回答3:

The warnings from ranlib indicate 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.

It isn't a 'slam dunk' diagnosis; the missing symbols are clearly in two groups - those related to trnk and those related to crv - and the files are likewise in two groups (prefixed trnk and 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.

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.