Mr Morgan Mr Morgan - 1 year ago 64
Bash Question

gcc in Windows cannot compile C program written for Unix/Linux

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
and call program
and divert the output to

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

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
in NetBeans and

The message :
./search: cannot execute binary file: Exec format error
is most likely to do with the fact there is no executable file for
. 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
refers to the environment I am using. I am using a 64 bit version of
gcc 5.4.0
in a 64 bit version of
Windows 10

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

Answer Source

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