Статическая библиотека, созданная для архива, которая не связана с архитектурой (x86_64)

Я испытываю то, что, похоже, та же проблема, когда я пытаюсь скомпилировать две разные программы. Каждый из них создает сначала статическую библиотеку, а затем основное приложение, связывающее эту библиотеку. Я работаю над Mac OS Mavericks с gcc 4.7.2.

Программа 1

Это то, что происходит, когда я запускаю make:

Сначала libfeat.a библиотека 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

Что происходит?

Ответ 1

Благодаря этому вопросу с той же проблемой я мог бы изучить эту проблему. У меня нет большого опыта работы со статическими библиотеками, но я попытаюсь объяснить проблему.

По какой-то причине утилита Mac OSX ar создает "подкаталоги" в статической библиотеке. Например, построив библиотеку 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

Я совсем не понимаю причину, но это сработало для меня.

Ответ 2

Возможной причиной является использование GNU ar(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. Если вы похожи на меня и у вас /usr/local/bin превзойден /usr/bin в $PATH, с инструментами GNU в /usr/local/bin и Xcode в /usr/bin, вы можете исправить это с помощью:

cd /usr/local/bin
mv ar gar
ln -s /usr/bin/ar ar
mv ranlib granlib
ln -s /usr/bin/ranlib ranlib

Ответ 4

У меня возникла проблема получения неправильного сообщения об ошибке архитектуры. В нем говорилось следующее:

 ld: warning: ignoring file blah/lib/blahblah.a, file was built for archive which is not the architecture being linked (i386)

lipo дает: Нежирный файл:../lib/blahblah.a - это архитектура: x86_64

в файле makefile сказано следующее: ARCH_FLAG = -arch x86_64 -arch i386

Я прокомментировал часть i386, и ошибка исчезла. ARCH_FLAG = -arch x86_64 # -arch i386

Итак, я думаю, вы можете получить ошибку по той же причине. Возможно, вам просто нужно установить класс архитектуры в соответствии с вашей библиотекой.

Кстати, мой make файл был сгенерирован swig, и я не установил никаких переключателей для компилятора.

Ответ 5

Если у вас установлен пакет binutils просто удалите или удалите его

brew unlink binutils