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

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?

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

Related

Why gcc compiler giving the complied file a new name?

I have reinstalled mingw in my system and downloaded the gcc compiler.
I was shocked after compiling the first file which was "subject.c" but the name of the compiled file which gcc returned was "a.exe". It should be "subject.exe" but do not know why this happened.
Can anyone please explain the reason behind this ?
expected:
gcc subject.c
ls
subject.c subject.exe
tried:
gcc subject.c
ls
subject.c a.exe
-o can be used to give the name of the output file.
For example,
gcc -Wall -Wextra -pedantic subject.c -o subject.exe
(Do enable your compiler's warnings!)
gcc names its output files, in the absence of other instructions, a.out or a.exe depending on system environment because that is what it's supposed to do.
To override this default behavior, you can use the -o flag which tells gcc that the next argument is the desired name for the output file. For instance:
gcc -o subject.exe subject.c
There is no automatic functionality built into gcc to strip a source file of its file extension and add .exe to the end but this can be done manually with Makefiles or other similar scripts, for instance you can write a Makefile with the following contents:
%.exe: %.c
gcc -o $# $<
Then a command like make subject.exe would be translated to gcc -o subject.exe subject.c, which may be what you're looking for.
There is functionality built into gcc to strip source files of their extensions during different parts of the compilation process, which may have been what confused you. For instance a call like gcc -c subject.c can be expected to produce an object file called subject.o, likewise gcc -S subject.c can be expected to produce an assembly language file called subject.s, however this does not apply to executable files not only for historical reasons, but because programs can be compiled from multiple source files and there is not always a clear way to choose a name for the executable output.

Linking with shared libraries

I'm trying to compile and link some .c file. I have been using Eclipse IDE for C/C++ developers, and in my local machine i can compile without problems. However, when i try to compile and link the same file in a RedHat OS (gcc version is 4.9.2-6 in this OS) i'm having problems. I get some warnings at compile time, but those are fine, i think, i just ignored and the application still runs fine. Here are the commands i executed and the associated output:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -MMD -MP -MF"example.d" -MT"example.d" -o "example.o" "example.c"
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
warning: implicit declaration of function ‘wait’ [-Wimplicit-function-declaration]
This generates two files, example.d and example.o. Then, i try to link them, without luck, with the following command:
gcc -Xlinker -L/usr/lib -lrt -static -pthread example.o -o example
/usr/bin/ld: cannot find -lrt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
The commands are taken directly from the ones that Eclipse generates, and work just fine in my local computer (Ubuntu OS) but not in the RedHat environment. The last command didn't work, with and without the -L option. I suppose the directory in -L is fine, as i run, for example,
locate libpthread.so
And one of the locations i get is /usr/lib (also /usr/lib64, but neither work).
Any help will be greatly appreciated!! :)
If you try to link a static executable, it will look for the *.a versions of the libraries, not what you usually want. Remove the -static flag. Or you can install the static libraries if you really want to. It also should not be necessary to add -L/usr/lib explicitly.

Error "undefined reference" while linking in MinGW

I have got the object-file from source code using MinGW.
But on linking:
ld -o test.exe test.o
I get errors, for example the following:
undefined reference to printf
First, why are you using ld directly?
The following is an excerpt from the "GCC and Make" tutorial found at http://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html.
Compile and Link Separately
The above command compile the source file into object file and link with other object files (system library) into executable in one step. You may separate compile and link in two steps as follows:
// Compile-only with -c option
> g++ -c -Wall -g Hello.cpp
// Link object file(s) into an executable
> g++ -g -o Hello.exe Hello.o
Note g++ (you can substitute gcc if you are using C and not C++) is used both for compiling and linking. ld is not used at all.
The benefit of using g++ or gcc to link is that it will link with default libraries, such as the one you need to link with for printf, automatically.
To link with other libraries, you specify the library name with the -l parameter, as in -lmylib.
We can view commands ran by compiler via command
c99 -v test.o
We'll get some text. All after string which contains "COLLECT_CGG_OPTIONS" will be arguments of ld.
But size of executable file is much more then size of file got by previous way.

Cannot compile using ALSA

I am trying to create an C application on Debian GNU/Linux which uses the PortAudio interface. To do this I must compile my program with gcc -lrt -lasound -ljack -lpthread -o YOUR_BINARY main.c libportaudio.a from this docs.
For this I installed libasound2-dev, and I checked where the files are using apt-file search libasound.so, this is the output:
lib32asound2: /usr/lib32/libasound.so.2
lib32asound2: /usr/lib32/libasound.so.2.0.0
lib32asound2-dev: /usr/lib32/libasound.so
libasound2: /usr/lib/x86_64-linux-gnu/libasound.so.2
libasound2: /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
libasound2-dev: /usr/lib/x86_64-linux-gnu/libasound.so
So the libasound should be installed correctly, but when I compile my program with this makefile:
DMXTest: main.c libdmx.a
gcc -static -Wall main.c -L. -ldmx -lusb -lrt -lasound -ljack -lfftw3 -g -o main libportaudio.a
I get the following error: /usr/bin/ld: cannot find -lasound.
How can I link this library correctly?
You don't have libasound.a for -static, you will need that, or you can almost certainly just remove -static from the Makefile (likely in LDFLAGS or CFLAGS).
There's is a related Debian bug 522544, and a related Ubuntu bug #993959.
You may be able to build your own libasound from source, though as it also uses other libraries (notably libpthread.so, librt.so and libdl.so) I suspect it may remove some functionality when you build it statically, though it's supported with ./configure --enable-static at build time
(or try --enable-shared=no --enable-static=yes).
FWIW, the use of static binaries is "discouraged" by the glibc maintainers, though I don't agree...
To compile my code i used the following command
gcc -o rec_mic rec_mic.c -lasound
and it works perfectly, without create my own static library.

Linux Novice Question: GCC Compiler output

I am a complete novice with Linux. I have Mint on a laptop and have recently been playing around with it.
I wrote a simple C program and saved the file.
Then in the command line I typed
gcc -c myfile
and out popped a file called a.out. I naively (after years of Windows usage) expected a nice .exe file to appear. I have no idea what to do with this a.out file.
Name it with -o and skip the -c:
gcc -Wall -o somefile myfile
You should name your sourcefiles with a .c extension though.
The typical way of compiling e.g. two source files into an executable:
#Compile (the -c) a file, this produces an object file (file1.o and file2.o)
gcc -Wall -c file1.c
gcc -Wall -c file2.c
#Link the object files, and specify the output name as `myapp` instead of the default `a.out`
gcc -o myapp file1.o file2.o
You can make this into a single step:
gcc -Wall -o myapp file1.c file2.c
Or, for your case with a single source file:
gcc -Wall -o myapp file.c
The -Wall part means "enable (almost) all warnings" - this is a habit you should pick up from the start, it'll save you a lot of headaches debugging weird problems later.
The a.out name is a leftover from older unixes where it was an executable format. Linkers still name files a.out by default, event though they tend to produce ELF and not a.out format executables now.
a.out is the executable file.
run it:
./a.out

Resources