1. ホーム
  2. macos

[解決済み] ファイルがリンク先のアーキテクチャではない、サポートされていないファイル形式でビルドされた (x86_64)

2022-02-28 04:34:48

質問

OSX Lionでビルドファイルがあります。

VPATH = src include
CFLAGS ="-I include -std=gnu99"

hello: hello.o
    gcc $^ -o $@

hello.o: hello.h hello.c
    gcc $(CFLAGS) -c $< -o $@

しかし、このmakeファイルを実行しようとすると、次のようなエラーが発生します。

    ld: warning: ignoring file hello.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

フラグを使用してみました。 -arch x86_64 が、やはり同じエラーが発生します。

を実行すると arch コマンドで得られます。 i386 .

uname -a が教えてくれる。 Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41 PST 2012; root:xnu-1699.24.23~1/RELEASE_X86_64 x86_64

また、スイッチを追加してみました。 -march=x86-64 この回答で説明されているように Mac OSX 10.6 上で iOS 4.2 用の OpenCV2.2 をコンパイルする際、ファイルが i386 用にビルドされましたが、リンクされているアーキテクチャ (x86_64) ではありません。 が、私の場合はうまくいきませんでした。

コマンドラインからの出力は

gcc -I include -std=gnu99 -m64  -c include/hello.h -o hello.o  
gcc -I include -std=gnu99 -m64  hello.o -o hello
ld: warning: ignoring file hello.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [hello] Error 1

解決方法は?

  1. オブジェクトファイルをすべて削除してください。
  2. makefileをもっと好きに修正する。

    VPATH   = src include
    CFLAGS  = -I include -std=gnu99 -m64
    CC      = gcc
    LDLIBS  =
    LDFLAGS =
    
    hello: hello.o
        $(CC) $(CFLAGS) $^ -o $@
    
    hello.o: hello.c hello.h
        $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) $(LDLIBS)
    
    

なお、コマンドラインはすべてマクロ化しました。 CFLAGSはすべてのコンパイルで使用されます。 これらは二重引用符で囲まれていません。 そのため -m64 オプションは64ビットビルドを要求するものです。 LDFLAGSやLDLIBSマクロはまだ必要ありませんが(つまり、問題を起こさずに省略することができます)、リンク時にいくつかのライブラリが必要な場合にどのように処理するかを示しています。

私自身のメイクファイルでは、次のようなことをしています。

IFLAGS = -Iinclude
WFLAG1 = -Wall
WFLAG2 = -Werror
WFLAG3 = -Wextra
WFLAGS = $(WFLAG1) $(WFLAG2) $(WFLAG3)
OFLAGS = -g -O3
SFLAG1 = -std=c99
SFLAG2 = -m64
SFLAGS = $(SFLAG1) $(SFLAG2)
DFLAGS = # -Doptions
UFLAGS = # Set on make command line only
CFLAGS = $(SFLAGS) $(DFLAGS) $(IFLAGS) $(OFLAGS) $(WFLAGS) $(UFLAGS)

そうすれば、Cコンパイラの引数ひとつをとっても、コマンドラインで調整することができるんだ。 たとえば、32ビットのビルドを行うには、次のように実行します。

make SFLAG2=-m32

などなど。 欠点は、どの xFLAGn オプションはどれに影響するのでしょうか。 しかし、makefileをざっと見れば、この問題は解決しますし、makefileを全く修正せずにコンパイルを変更することができます。

(また、私はよく CC="gcc -m64" を使えば、他の人のソフトウェアに64ビットコンパイルを強制することができます)。