当我试图编译两个不同的程序时,我遇到了似乎相同的问题。它们中的每一个都首先创建一个静态库,然后创建链接该库的主应用程序。我正在使用gcc 4.7.2开发Mac OS Mavericks。
程序1
这就是我运行make
:时发生的情况
首先,创建了库libfeat.a
,但我得到了一个警告:
ar rc ../lib/libfeat.a imgfeatures.o utils.o sift.o kdtree.o minpq.o xform.o
ranlib ../lib/libfeat.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: warning for library: ../lib/libfeat.a the table of contents is empty (no object file members in the library define global symbols)
然后,在编译应用程序时,它说它不能使用库,因为它不是为相同的体系结构(x86_64)构建的:
gcc -O3 -I../include `pkg-config --cflags opencv` `pkg-config --cflags gtk+-3.0` `pkg-config --cflags gsl` siftfeat.c -o ../bin/siftfeat -L../lib -lfeat `pkg-config --libs opencv` `pkg-config --libs gtk+-3.0` `pkg-config --libs gsl`
ld: warning: ignoring file ../lib/libfeat.a, file was built for archive which is not the architecture being linked (x86_64): ../lib/libfeat.a
如果我运行lipo
,我得到的是:
$ lipo -info ../lib/libfeat.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: archive with no architecture specification: ../lib/libfeat.a (can't determine architecture for it)
程序2
我在另一个程序中遇到了同样的问题:先创建一个库,然后再使用它。
这是创建lib:时的输出
ar crv libsba.v1.5.a sba_levmar.o sba_levmar_wrap.o sba_lapack.o sba_crsm.o sba_chkjac.o
r - sba_levmar.o
r - sba_levmar_wrap.o
r - sba_lapack.o
r - sba_crsm.o
r - sba_chkjac.o
ranlib libsba.v1.5.a
这就是应用程序:
c++ -o bundler -O3 -Wall -fpermissive -I../lib/imagelib -I../lib/sfm-driver -I../lib/matrix -I../lib/5point -I../lib/sba-1.5 -I../lib/ann_1.1_char/include -L../lib -L../lib/ann_1.1_char/lib
-D__NO_UI__ -D__BUNDLER__ -D__BUNDLER_DISTR__ BaseApp.o BundlerApp.o keys.o Register.o Epipolar.o Bundle.o BundleFast.o MatchTracks.o Camera.o Geometry.o ImageData.o SifterUtil.o BaseGeometry.o BundlerGeometry.o BoundingBox.o BundleAdd.o ComputeTracks.o BruteForceSearch.o BundleIO.o ProcessBundle.o BundleTwo.o Decompose.o RelativePose.o Distortion.o TwoFrameModel.o LoadJPEG.o -limage -lsfmdrv -lsba.v1.5 -lmatrix -lz -llapack -lblas -lcblas -lminpack -lm -l5point -ljpeg -lANN_char -lgfortran
ld: warning: ld: warning: ignoring file ../lib/libsba.v1.5.a, file was built for archive which is not the architecture being linked (x86_64)
在这种情况下,lipo
确实告诉我库的体系结构是x86_64:
$ lipo -info lib/libsba.v1.5.a
input file lib/libsba.v1.5.a is not a fat file
Non-fat file: lib/libsba.v1.5.a is architecture: x86_64
怎么回事?
一个可能的原因是使用GNUar(1)
/ranlib(1)
,而不是Xcode工具链提供的。运行which -a ar
和which -a ranlib
以查看$PATH
中的内容。
例如:
$ which -a ranlib
/usr/local/bin/ranlib
/usr/bin/ranlib
$ /usr/local/bin/ranlib --version
GNU ranlib (GNU Binutils) 2.28.51.20170105
Copyright (C) 2017 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.
$ /usr/bin/ralib --version
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: unknown option character `-' in: --version
Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib [-sactfqLT] [-] archive [...]
与ar
相同。如果你和我一样,在$PATH
中/usr/local/bin
先于/usr/bin
,使用/usr/local/bin
中的GNU工具和/usr/bin
中的Xcode工具,你可以用修复它
cd /usr/local/bin
mv ar gar
ln -s /usr/bin/ar ar
mv ranlib granlib
ln -s /usr/bin/ranlib ranlib
由于这个问题有同样的问题,我可以研究这个问题。我对静态库没有太多经验,但我会尽力解释这个问题。
出于某种原因,Mac OSXar
实用程序在静态库中创建"子目录"。例如,构建sba
库,make
从对象文件构建静态库的步骤是:
ar crv libsba.v1.5.a sba_levmar.o sba_levmar_wrap.o sba_lapack.o sba_crsm.o sba_chkjac.o
之后,如果我查看静态库的内容,我会发现除了文件之外,还有一些奇怪的目录:
$ ar -t libsba.v1.5.a
__.SYMDEF
/
//
sba_levmar.o/
/0
sba_lapack.o/
sba_crsm.o/
sba_chkjac.o/
sba_levmar.o
sba_levmar_wrap.o
sba_lapack.o
sba_crsm.o
sba_chkjac.o
sba_levmar.o
sba_levmar_wrap.o
sba_lapack.o
sba_crsm.o
sba_chkjac.o
如果我们试图提取这些文件,我们会得到一些关于子目录的错误:
$ ar -x libsba.v1.5.a
ar: /: Is a directory
ar: //: Is a directory
ar: sba_levmar.o/: Not a directory
ar: /0: Permission denied
ar: sba_lapack.o/: Not a directory
ar: sba_crsm.o/: Not a directory
ar: sba_chkjac.o/: Not a directory
现在,如果我们用提取的对象文件再次创建lib,它将起作用:
$ ar crv libsba.v1.5.a lib_o/*.o
a - lib_o/sba_chkjac.o
a - lib_o/sba_crsm.o
a - lib_o/sba_lapack.o
a - lib_o/sba_levmar.o
a - lib_o/sba_levmar_wrap.o
$ ar -t libsba.v1.5.a
__.SYMDEF SORTED
sba_chkjac.o
sba_crsm.o
sba_lapack.o
sba_levmar.o
sba_levmar_wrap.o
我根本不明白原因,但它对我有效。
如果您安装了binutils
,只需取消链接或卸载它
brew unlink binutils
使用libtool -static -a
可能更容易获得工作的静态库。
Mac OS X的静态库链接问题:找不到体系结构x86_64 的符号
我遇到了获取错误体系结构错误消息的问题。上面写着:
ld: warning: ignoring file blah/lib/blahblah.a, file was built for archive which is not the architecture being linked (i386)
lipo给出:非脂肪文件:/lib/bullah.a是体系结构:x86_64
在makefile中,它说:ARCH_FLAG=-拱形x86_64-拱形i386
我评论掉了i386部分,错误消失了。ARCH_FLAG=-ARCH x86_64#-ARCH i386
所以,我认为你有可能因为同样的原因而出错。也许你只需要设置架构类来匹配你的库。
顺便说一下,我的makefile是由swig生成的,我没有为编译器设置任何开关。