【问题标题】:gcc ld: symbol(s) not found for architecture x86_64gcc ld:未找到架构 x86_64 的符号
【发布时间】:2012-02-14 06:18:03
【问题描述】:

好的,所以我正在使用 Ocamlyacc 制作词法分析器和解析器。我已经完成了我的研究,我认为这与我的 makefile 没有为我的编译器或类似的东西选择正确的位版本有关?我对makefile了解不多,这就是我要问的原因。

我已经在另一台计算机上运行我的程序,它可以正常运行,所以它一定与我的计算机有关。

这是 64 位 MacBook Pro。我正在使用 Xcode 4.2.1。

这是生成文件:

SHELL        = /bin/sh

C_C          = gcc 
CPP_C        = g++ 
ifdef GPROF
C_CPP_FLAGS = -pg -O3
else
ifndef DEBUG
C_CPP_FLAGS  = -O3
else
C_CPP_FLAGS  = -g
endif
endif
C_LD         = $(C_C)
CPP_LD       = $(CPP_C)

C_YACC       = bison
C_LEX        = flex

AR           = ar
RANLIB       = ranlib

OCAML_C      = ocamlc
OCAML_OPT_C  = ocamlopt
ifdef GPROF
OCAML_C_FLAGS     = -dtypes 
OCAML_OPT_C_FLAGS = -dtypes
OCAML_LD     = $(OCAML_C) -g
OCAML_OPT_LD = $(OCAML_OPT_C) -p
else
ifndef DEBUG
OCAML_C_FLAGS     = -dtypes 
OCAML_OPT_C_FLAGS = -dtypes
OCAML_LD     = $(OCAML_C) -g
OCAML_OPT_LD = $(OCAML_OPT_C)
else
OCAML_C_FLAGS     = -dtypes
OCAML_OPT_C_FLAGS = -dtypes
OCAML_LD     = $(OCAML_C) -g
OCAML_OPT_LD = $(OCAML_OPT_C)
endif
endif
OCAML_MKTOP  = ocamlmktop
OCAML_CP     = ocamlcp
OCAML_DEP    = ocamldep
OCAML_LEX    = ocamllex
OCAML_YACC   = ocamlyacc

OCAML_C_CPP_INC = -I $(shell $(OCAML_C) -v | tail -1 | sed -e \
                         's/^Standard library directory: //')

我得到的错误是:

ld: symbol(s) not found for architecture x86_64

这是完整的输出:

make
Linking OCAML (top level) program nanoml.top
ocamlmktop    -o nanoml.top -custom   nano.cmo nanoLex.cmo nanoParse.cmo main.cmo \
-cc g++  -cclib ' '
/var/folders/n3/jgblhwmj40lchgq71bmgr8sw0000gn/T/camlprimbd6a63.c:784: warning: deprecated conversion from string constant to ‘char*’
.
. //The same line ALOT of times. Removed due to limit of chars in a single post.
.
/var/folders/n3/jgblhwmj40lchgq71bmgr8sw0000gn/T/camlprimbd6a63.c:784: warning: deprecated conversion from string constant to ‘char*’
ld: warning: ignoring file /usr/local/lib/ocaml/libcamlrun.a, file was built for archive which is not the architecture being linked (x86_64)
Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.6.o
  "_caml_alloc_dummy", referenced from:
      _caml_builtin_cprim in ccZbZ9Mf.o
.
. //And many of these lines
.
  "_caml_get_exception_backtrace", referenced from:
      _caml_builtin_cprim in ccZbZ9Mf.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
File "_none_", line 1, characters 0-1:
Error: Error while building custom runtime system
make: *** [nanoml.top] Error 2

提前谢谢你!

编辑: 我只使用 Ocaml。没有需要与之链接的 C++ 或 C。我以前从未尝试过使用 makefile 运行我的 ocaml 代码,但我可以在这台计算机上运行其他 ocaml 代码。这是第一次失败,但这是我第一次使用 makefile。

同样的 makefile 和代码也可以在其他机器上运行(虽然是旧机器),所以我认为这与使用 64 位的机器有关。

我发现我收到了另一个 makefile,如下所示:

# Generic compilation rules

%.o : %.c
    @echo Compiling C file $<
    $(C_C) $(C_CPP_FLAGS) $(C_CPP_INCLUDES) -c $< -o $@

%.o : %.cc
    @echo Compiling C++ file $<
    $(CPP_C) $(C_CPP_FLAGS) $(C_CPP_INCLUDES) -c $< -o $@

%.o : %.cpp
    @echo Compiling C++ file $<
    $(CPP_C) $(C_CPP_FLAGS) $(C_CPP_INCLUDES) -c $< -o $@

%.cmi: %.mli
    @echo Compiling OCAML interface $<
    $(OCAML_C) $(OCAML_C_FLAGS) $(OCAML_INCLUDES) -c $< -o $@

%.cmo: %.ml
    @echo Compiling \(to byte code\) OCAML module $<
    $(OCAML_C) $(OCAML_C_FLAGS) $(OCAML_INCLUDES) -c $< -o $@

%.cmx: %.ml
    @echo Compiling \(to native code\) OCAML module $<
    $(OCAML_OPT_C) $(OCAML_OPT_C_FLAGS) $(OCAML_INCLUDES) -c $< -o $@

%.ml: %.mll
    @echo Lexing OCAML file $<
    $(OCAML_LEX) $<

%.ml %.mli: %.mly
    @echo Yaccing OCAML file $<
    $(OCAML_YACC) $<



# Generic cleaning rules

default-clean:
    rm -f *~ *.o *.cmo *.cmx .*.depend *.cmi

.PHONY: default-clean



# Generic link rules and library creation rules
#
# These rules assume that the following variables are set (when necessary):
#
# - C_EXE          : name of the C executable
# - CPP_EXE        : name of the C++ executable
# - OCAML_EXE      : name of the OCaml executable (without suffix)
# - OCAML_TPL_EXE  : name of the OCaml custom toplevel (without suffix)
# - C_CPP_LIB      : name of the C/C++ library
# - OCAML_LIB      : name of the OCaml library (without suffix)
# - C_CPP_EXE_OBJ  : list of C/C++ objects (without suffix) to build exe
# - OCAML_EXE_OBJ  : list of OCaml modules (without suffix) to build exe
# - C_CPP_LIB_OBJ  : list of C/C++ objects (without suffix) to build lib
# - OCAML_LIB_OBJ  : list of OCaml modules (without suffix) to build lib
# - C_CPP_LD_FLAGS : C and C++ linker flags
# - OCAML_LD_FLAGS : OCaml linker (both native and bytecode) flags
# - C_CPP_LD_LIBS  : C and C++ linker libraries
# - OCAML_LD_LIBS  : OCaml linker (both native and bytecode) libraries

ifdef C_EXE
$(C_EXE): $(C_CPP_EXE_OBJ:%=%.o)
    @echo Linking C program $@
    $(C_LD) $(C_CPP_LD_FLAGS) -o $@ $(C_CPP_EXE_OBJ:%=%.o) $(C_CPP_LD_LIBS)
endif

ifdef CPP_EXE
$(CPP_EXE): $(C_CPP_EXE_OBJ:%=%.o)
    @echo Linking C++ program $@
    $(CPP_LD) $(C_CPP_LD_FLAGS) -o $@ $(C_CPP_EXE_OBJ:%=%.o) $(C_CPP_LD_LIBS)
endif

ifdef C_CPP_LIB
$(C_CPP_LIB).a: $(C_CPP_LIB_OBJ:%=%.o)
    @echo Creating C/C++ library $@
    $(AR) r $@ $?
    $(RANLIB) $@
endif

ifdef OCAML_EXE
$(OCAML_EXE).byte: $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmo)
    @echo Linking OCAML \(byte code\) program $@
    $(OCAML_LD) $(OCAML_LD_FLAGS) -o $@ -custom $(OCAML_LD_LIBS:%=%.cma) $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmo) \
    -cc $(CPP_C) -cclib '$(C_CPP_LD_FLAGS) $(C_CPP_LD_LIBS)'

$(OCAML_EXE).opt: $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmx)
    @echo Linking OCAML \(native code\) program $@
    $(OCAML_OPT_LD) $(OCAML_LD_FLAGS) -o $@ $(OCAML_LD_LIBS:%=%.cmxa) $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmx) \
    -cc $(CPP_C) -cclib '$(C_CPP_LD_FLAGS) $(C_CPP_LD_LIBS)'

$(OCAML_EXE).top: $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmo)
    @echo Linking OCAML \(top level\) program $@
    $(OCAML_MKTOP)   $(OCAML_LD_FLAGS) -o $@ -custom $(OCAML_LD_LIBS:%=%.cma) $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmo) \
    -cc $(CPP_C) -cclib '$(C_CPP_LD_FLAGS) $(C_CPP_LD_LIBS)'


endif

ifdef OCAML_TPL_EXE
$(OCAML_TPL_EXE).byte: $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmo)
    @echo Linking OCAML \(byte code\) toplevel $@
    $(OCAML_MKTOP) $(OCAML_LD_FLAGS) -o $@ -custom $(OCAML_LD_LIBS:%=%.cma) $(C_CPP_EXE_OBJ:%=%.o) $(OCAML_EXE_OBJ:%=%.cmo) \
    -cc $(CPP_C) -cclib '$(C_CPP_LD_FLAGS) $(C_CPP_LD_LIBS)'
endif

ifdef OCAML_LIB
$(OCAML_LIB).cma: $(OCAML_LIB_OBJ:%=%.cmo)
    @echo Creating OCAML \(byte code\) library $@
    $(OCAML_LD) $(OCAML_LD_FLAGS) -a -o $@ $(OCAML_LIB_OBJ:%=%.cmo)

$(OCAML_LIB).cmxa $(OCAML_LIB).a: $(OCAML_LIB_OBJ:%=%.cmx)
    @echo Creating OCAML \(native code\) library $@
    $(OCAML_OPT_LD) $(OCAML_LD_FLAGS) -a -o $@ $(OCAML_LIB_OBJ:%=%.cmx)
endif

ifdef OCAML_CINTF
ifdef OCAML_BYTECODE_CINTF
$(OCAML_CINTF).o: $(OCAML_CINTF_OBJ:%=%.cmo)
    @echo Creating OCAML \(native code\) C interface library $@
    $(OCAML_LD) $(OCAML_LD_FLAGS) -output-obj -o $@ $(OCAML_LD_LIBS:%=%.cma) $(OCAML_CINTF_OBJ:%=%.cmo)

$(OCAML_CINTF_LIB).a: $(OCAML_CINTF).o $(C_CPP_CINTF_OBJ:%=%.o)
    @echo Creating C/C++ interface library $@
    $(AR) r $@ $?
    $(RANLIB) $@
else
$(OCAML_CINTF).o: $(OCAML_CINTF_OBJ:%=%.cmx)
    @echo Creating OCAML \(native code\) C interface library $@
    $(OCAML_OPT_LD) $(OCAML_LD_FLAGS) -output-obj -o $@ $(OCAML_LD_LIBS:%=%.cmxa) $(OCAML_CINTF_OBJ:%=%.cmx)

$(OCAML_CINTF_LIB).a: $(OCAML_CINTF).o $(C_CPP_CINTF_OBJ:%=%.o)
    @echo Creating C/C++ interface library $@
    $(AR) r $@ $?
    $(RANLIB) $@
endif
endif



# Generic dependencies creation rules

.%.mli.depend: %.mli
    @echo Generating dependencies for OCAML interface $<
    $(OCAML_DEP) $< > $@

.%.ml.depend: %.ml
    @echo Generating dependencies for OCAML module $<
    $(OCAML_DEP) $< > $@

【问题讨论】:

    标签: gcc makefile ocaml


    【解决方案1】:

    有趣的是

    ld:警告:忽略文件 /usr/local/lib/ocaml/libcamlrun.a,文件是 为不是被链接架构的存档而构建 (x86_64)

    它告诉您,您的 ocaml 运行时可能是一个 32 位库,而不是 你需要的 64 位。

    您可能想尝试使用 g++ 的“-m32”标志以 32 位编译所有内容,或者安装 64 位版本的 ocaml。

    【讨论】:

    • 如何将该标志应用到我的makefile?我对 makefile 和我尝试的失败一无所知
    • 你不需要太懂,试着找到文本“-cc g++”所在的位置(或者只是-cc),把“g++”改成“'g++ -m32'” .
    • 我刚刚做了这个(与 ocaml 无关,但与 OP 的错误相同)并得到了这个 ld: symbol(s) not found for architecture i386 :D :D :D
    【解决方案2】:

    看起来您的 OCaml 编译器可能正在生成 32 位可执行文件。一种说法是:

    $ ocamlopt -config
    

    如果您看到architecture i386,它是一个 32 位编译器。如果您看到architecture amd64,它是一个 64 位编译器。无论如何,这是我在 Macbook Pro 上看到的两个不同的值。

    编辑

    您提供的Makefile 并没有真正描述您想要做什么。它只是为某些语言处理器定义名称。真正的Makefile 可能在别处。

    由于Makefile 实际上并没有说明您在做什么,我意识到我没有看到任何证据表明您将 OCaml 和 C++(或 C)链接在一起。除了看起来像 OCaml 文件的内容外,第一行输出不显示任何内容。此外,他们是 命名为xyz.cmo,它们是字节码 OCaml 文件。也就是说,它们不是 32 位 64 位(本机)文件。

    您是否有一些 C++ 和一些 OCaml 组件需要链接在一起,或者您的项目是纯 OCaml?如果它是纯 OCaml,我会说问题都出在 Makefile 上。如果您只想运行 OCaml 代码,则不必担心架构。

    如果有一些 C++ 或 C,那么您需要使用 -arch i386 编译它(以获取 32 位对象),然后使用知道它正在生成 32 位目标的链接器 (ld) 将所有内容链接在一起. (或者,正如 Fabrice Le Fessant 所说,您可以安装 64 位 OCaml 编译器。)

    一个可能的建议是创建一个小的 OCaml 文件,然后看看是否可以编译和运行它。

    使用字节码编译器,它看起来像这样:

    $ uname -rs
    Darwin 10.8.0
    $ cat tiny.ml
    Printf.printf "hello world\n"
    $ ocamlc -o tiny tiny.ml
    $ file tiny.cmo
    tiny.cmo: Objective caml object file (.cmo) (Version 006).
    $ file tiny
    tiny: a /sw/bin/ocamlrun script text executable
    $ tiny
    hello world
    

    使用原生 32 位编译器,它看起来像这样:

    $ ocamlopt -o tiny tiny.ml
    $ file tiny.cmx
    tiny.cmx: Objective caml native object file (.cmx) (Version 011).
    $ file tiny.o
    tiny.o: Mach-O object i386
    $ file tiny
    tiny: Mach-O executable i386
    $ tiny
    hello world
    

    编辑 2

    您的第二个 makefile 仍然没有显示您正在尝试做什么,特别是。它只是定义了一些用于编译和链接不同类型的可执行文件的 make 规则。但是,既然你说你的项目都是 OCaml,那么我会说整个问题都在这个 Makefile 中。

    问题似乎是这个 Makefile 使用 -cc-cclib 选项指定 OCaml 编译器应该使用哪些 C 编译器和库作为其后端。在大多数系统上,只需将标准 C 编译器指定为 OCaml 的后端即可。在 Mac OS X 上,存在 32 位/64 位架构复杂性。由于您可以在没有此 Makefile 的情况下成功编译 OCaml,我建议 OCaml 编译器已经知道如何编译和链接 OCaml 程序。因此,您可以尝试从 Makefile 中删除 -cc-cclib 选项。

    为此:在OCAML_EXE 下的所有三个部分中,完全删除第三行(带有-cc-cclib 的行),并删除前一行的尾部反斜杠

    【讨论】:

    • 是的,我看到了 i386,所以它是一个 32 位编译器。如何让我的 g++/gcc 编译器以 32 位而不是 64 位运行?
    • 我已经尝试过“gcc -arch i386”和“gcc -arch amd64”。两者都导致:“ld:警告:忽略文件 /usr/local/lib/ocaml/libcamlrun.a,文件是为存档而构建的,它不是被链接的架构 (x86_64)”。
    • 可能这意味着您还需要在链接步骤中说-arch i386(或同等名称)。
    • 你对额外的 makefile 的看法是正确的。我已经相应地编辑了我的帖子。对它可能有什么问题有什么建议吗?
    • 这个新的 makefile 更加丰富,但它仍然没有显示您,特别是,正在尝试做什么。它显示了编译和链接各种类型的可执行文件的规则。我不得不问,你为什么使用这个makefile?
    【解决方案3】:

    过去两天我在尝试编译 gphoto2 时遇到了这个问题。我刚刚从 OS X 10.8 升级到 OS X 10.9。一开始我以为是新的 XCode 版本和命令行工具的问题。

    我确保更新所有内容,但 ocaml 的架构不一致仍然存在,所以我决定安装 ocaml 的自制版本:

    $ brew install ocaml
    

    等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-18
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 2016-12-09
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多