0

I am a Unix/Linux newbie who is trying to run a shell script written by a person who left no documentation and has since demised. This script contains line:

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

Which is trying to get the file $poly and call program ./search and divert the output to $output.

When I get to this line, I am given message: ./search: cannot execute binary file: Exec format error

search is a C program called from the script and is in the same folder as various other C programs to do with this project. Script and C programs were developed and originally executed on a Unix/Linux box which is no longer available, so I have been asked to try to resurrect this project but under Windows using gcc in NetBeans and cygwin.

The message : ./search: cannot execute binary file: Exec format error is most likely to do with the fact there is no executable file for search. When I try to build the C programs I get the following output:

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':

I assume that R_X86_64_PC32 refers to the environment I am using. I am using a 64 bit version of Netbeans with gcc 5.4.0 in a 64 bit version of cygwin on Windows 10.

Can anyone advise what I must to to resolve this so that I can build the C programs?

Mr Morgan
  • 2,215
  • 15
  • 48
  • 78

1 Answers1

3

The problem is this:

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

By default, the linker will link libraries and objects in the order specified on the command line, and, when linking a library, will only include symbols needed by things before it on the command line. Since -lgmp is first, there are (as yet) no outstanding symbols (except main), so nothing is included from the library. When later objects need the symbols from it, they won't see them.

Change the order to

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

and it should work. Alternately, use the -Wl,--as_needed linker option to get the linker to remember earlier libraries and relink them if more symbols from them are referenced by later object files (requires a recent version of the GNU linker -- I have no idea if it works with cygwin).


This kind of misordering is usually a symptom of a broken Makefile. The normal Makefile structure has a bunch of variables that are set to control the default rules that know how to compile source files and link object files. The two variables relevant for linking are LDFLAGS and LDLIBS, and the difference is that LDFLAGS comes before all the object files on the command line and LDLIBS comes after all the object files.

So in order to make things work, you need to ensure that all of the -l options and other libraries are in LDLIBS:

LDLIBS = -lgmp -lrt -lm

and NOT in LDFLAGS

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • My makefile has `LIBS = -lgmp -lm -lrt` but there is no `LDLIBS` or `LDFLAGS`. – Mr Morgan Aug 13 '16 at 19:23
  • @MrMorgan: so your Makefile is very non-standard -- you need to look at how `$(LIBS)` is used, and fix that to make sure they are after the object files on the command line. – Chris Dodd Aug 13 '16 at 19:51