【问题标题】:gcc in Windows cannot compile C program written for Unix/LinuxWindows 中的 gcc 无法编译为 Unix/Linux 编写的 C 程序
【发布时间】:2016-12-20 12:25:43
【问题描述】:

我是一个 Unix/Linux 新手,他正在尝试运行一个由一个没有留下任何文档并且已经消亡的人编写的 shell 脚本。该脚本包含以下行:

./search $opt1 $arg1 < $poly 2>&1 | tee $output

它试图获取文件$poly 并调用程序./search 并将输出转移到$output

当我到达这条线时,我收到消息:./search: cannot execute binary file: Exec format error

search 是一个从脚本调用的 C 程序,与与该项目有关的各种其他 C 程序位于同一文件夹中。脚本和 C 程序是在不再可用的 Unix/Linux 机器上开发和执行的,因此我被要求尝试在 Windows 下使用 NetBeans 中的 gcccygwin 来恢复这个项目。

消息:./search: cannot execute binary file: Exec format error 很可能与search 没有可执行文件这一事实有关。当我尝试构建 C 程序时,我得到以下输出:

C:\cygwin64\bin\make.exe -f Makefile
gcc -ansi -g -c cbuild.c
gcc -ansi -g -c complex.c
gcc -ansi -g -c mylib.c
gcc -ansi -g -c poly.c
gcc -ansi -g -c real.c
gcc -ansi -g -c zero.c
gcc -lgmp -lm -lrt -o cbuild cbuild.o complex.o mylib.o poly.o real.o zero.o
real.o: In function `rabs':
/cygdrive/c/../progs/real.c:9: undefined reference to `__imp___gmpf_abs'
/cygdrive/c/../progs/real.c:9:(.text+0x1e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `__imp___gmpf_abs'
real.o: In function `radd':

我假设R_X86_64_PC32 指的是我正在使用的环境。我在Windows 10cygwin 的64 位版本中使用Netbeans 的64 位版本和gcc 5.4.0

谁能建议我必须如何解决这个问题,以便我可以构建 C 程序?

【问题讨论】:

标签: c windows shell gcc cygwin


【解决方案1】:

问题是这样的:

gcc -lgmp -lm -lrt -o cbuild cbuild.o complex.o mylib.o poly.o real.o zero.o

默认情况下,链接器将按照命令行中指定的顺序链接库和对象,并且在链接库时,只会在命令行中包含 before 事物所需的符号。由于-lgmp 是第一个,因此(到目前为止)没有突出的符号(main 除外),因此库中不包含任何内容。当以后的对象需要其中的符号时,它们将看不到它们。

将顺序改为

gcc -o cbuild cbuild.o complex.o mylib.o poly.o real.o zero.o -lgmp -lm -lrt

它应该可以工作。或者,使用-Wl,--as_needed 链接器选项让链接器记住早期的​​库,并在以后的目标文件引用来自它们的更多符号时重新链接它们(需要最新版本的 GNU 链接器——我不知道它是否适用于cygwin)。


这种排序错误通常是 Makefile 损坏的症状。正常的 Makefile 结构具有一组变量,这些变量设置为控制知道如何编译源文件和链接目标文件的默认规则。与链接相关的两个变量是LDFLAGSLDLIBS,区别在于LDFLAGS 出现在 命令行的所有目标文件之前,LDLIBS 出现在之后 所有目标文件。

因此,为了使事情正常进行,您需要确保所有-l 选项和其他库都在LDLIBS 中:

LDLIBS = -lgmp -lrt -lm

NOTLDFLAGS

【讨论】:

  • 我的makefile有LIBS = -lgmp -lm -lrt但没有LDLIBSLDFLAGS
  • @MrMorgan:所以您的 Makefile 非常不标准——您需要查看 $(LIBS) 的使用方式,并修复它以确保它们位于命令行上的目标文件之后。
猜你喜欢
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 2011-09-22
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
相关资源
最近更新 更多