Does the sequence of the args matters when using gcc? - gcc

gcc -o fig fig.c -I./include ./lib/libmylib.a -g
gcc -g fig.c -o fig -I./include ./lib/libmylib.a
gcc -g -o fig fig.c -I./include ./lib/libmylib.a
It seems that the gcc accept different kinds of sequence.
However, what is a not acceptable sequence? Does the sequence of arguments matters?

One sequence that does matter is where you put libraries if you specify -static linkage.
Basically, if you choose to statically link libraries in, the libraries should be specified after your code, as GCC will scan the code first for external library dependencies and then check the libraries to bring in. If you specified the libraries before the code that needs them, GCC would scan and determine no libraries were needed, and you'd end up with linker errors.

Related

Shared objects linking in Fortran from multiple source files into a single library

I'm having problems with linking several Fortran modules/subroutines into a shared library.
The thing is, I first had a standalone Fortran program, with that everything went fine. This consisted of
main.f95
mymodule.f95
myutils.f95
But now I am adapting things so that I can call the Fortran code from R.
So, I discard the main program main.f95 and I have a new file, let's say
callFromR.f95
which contains a subroutine that will be called from R. This routine shall use the module mymodule, and this module has dependencies on myutils.
I compile all three of them as shared objects:
gfortran -shared -fPIC callFromR.f95 -o callFromR.so
gfortran -shared -fPIC mymodule.f95 -o mymodule.so
gfortran -shared -fPIC myutils.f95 -o myutils.so
Now I somehow need to combine all three of them in a shared object file (not a object file). How can I do this?
(Consequently, when I call the callFromR subroutine in R, some subroutines that are located in the mymodule code are not found.)
You can first create object files
gfortran -c -fPIC callFromR.f95 -o callFromR.o
gfortran -c -fPIC mymodule.f95 -o mymodule.o
gfortran -c -fPIC myutils.f95 -o myutils.o
and then pack them into the library
gfortran -shared callFromR.o mymodule.o myutils.o -o callFromR.so

How can a segfault happen at runtime only because of linking unused modules?

I get a segmentation fault from a memory allocation statement just because I have linked some unrelated procedures to the binary.
I have a very simple Fortran program:
program whatsoever
!USE payload_modules
double precision,allocatable:: Vmat(:,:,:)
allocate(Vmat(2,2,2))
Vmat=1
write(*,*) Vmat
deallocate (Vmat)
! some more lines of code using procedures from payload_module
end program whatsoever
Compiling this using gfortran whatsoever.f95 -o whatsoever leads to a program with the expected behaviour. Of course, this program is not made to print eight times 1.000 but to call the payload_modules, yet hidden in the comments. However, if I compile and link the program with the modules issuing
gfortran -c -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none payload_module1.f90 payload_module2.f90 whatsever.f95
gcc -g -nostdlib -v -Wl,--verbose -std=gnu99 -shared -Wl,-Bsymbolic-functions \
-Wl,-z,relro -o whatsoever whatsoever.o payload_module1.o payload_module2.o
the program whatsoever doesn't run any more. I get a segmentation fault at the allocate statement. I have not yet uncommented the lines related to the modules (however, uncommenting them leads to the same behaviour)!
I know that the payload modules' code is not buggy because I ran it before from R and wrapped this working code into a f90-module. There are no name collisions; nothing in the modules is called Vmat. There is only one other call to allocate in the modules. It never caused any trouble. There is still plenty of memory left. gdb didn't give me any hints expect a memory address.
How can linking routines that are actually not called crash a program?
Compiling your code with
gfortran whatsoever.f95 -o whatsoever
is working because you link against the system libraries, everything is in place. This would correspond to
gfortran whatsoever.f95 payload_module1.f90 payload_module2.f90 -o whatsoever
which would also work. The commands you used instead omit the system libraries, and the code fails at the first time you call a function from there (the allocation). You don't see that you are missing the libraries, because you create a shared object (which is typically linked against the libraries later on).
You chose to separate compiling the objects and linking them into an executable. Doing this for Fortran program using gcc you need to specify the Fortran libraries, so there's a -lgfortran missing.
I'm not sure about that particular choice of compile options... -shared is usually used for libraries, are you sure you want a shared binary (whatever that is)?
With -nostdlib you tell the compiler not to link against the system libraries. You would then need to specify those libraries (which you don't).
For the main program test.F90 and a module payload.F90, I run
gfortran -c -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none payload.F90 test.F90
gcc -g -v -Wl,--verbose -std=gnu99 -Wl,-Bsymbolic-functions \
-Wl,-z,relro -lgfortran -o whatsoever test.o payload.o
This compiles and executes correctly.
It might be easier to use the advance options with gfortran:
gfortran -g -fPIC -ffpe-trap=overflow -pedantic -fbounds-check \
-fimplicit-none -Wl,-Bsymbolic-functions -Wl,-z,relro \
payload.F90 test.F90 -o whatsoever
The result is the same.

What is the signification of LDFLAGS

I'm trying to compile AODV for ARM linux. I use a SabreLite as a board with kernel version 3.0.35_4.1.0. It's worth mention that i'm using openembedded to create my Linux Distribution for my board.
The AODV source code (http://sourceforge.net/projects/aodvuu/) has a README file which give some indications on how to install it on ARM as stated a bit here.
(http://w3.antd.nist.gov/wctg/aodv_kernel/kaodv_arm.html).
I was able to upgrade the makefile in order to be used with post 2.6 kernel version ( as stated above, i have the 3.0.35_4.1.0 kernel version).
So, basically, what i am trying to do is that i have to create a module (let's say file.ko) and then load it into the ARM (with insmod file.ko command).
To do that, i am using a cross compiler which some values are stated below:
echo $CC :
arm-oe-linux-gnueabi-gcc -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/usr/local/oecore-x86_64/sysroots/cortexa9hf-vfp-neon-oe-linux-gnueabi
echo $ARCH=arm
echo $CFLAGS: O2 -pipe -g -feliminate-unused-debug-types
echo $LD :
arm-oe-linux-gnueabi-ld --sysroot=/usr/local/oecore-x86_64/sysroots/cortexa9hf-vfp-neon-oe-linux-gnueabi
echo $LDFLAGS :
-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,--as-needed
when i launch "make command", i get the following errors:
LD [M] /home/scof/script_emulation/AODV/aodv-uu/lnx/kaodv.o
arm-oe-linux-gnueabi-ld: unrecognized option '-Wl,-O1'
arm-oe-linux-gnueabi-ld: use the --help option for usage information
It states that there is something wrong with the linker. This linker comes from the cross compilation tools and i normally shouldn't touch it.
Anyway, to get this above errors fixed, i try to withdraw the LDFLAGS like this:
export LDFLAGS='',
and after this, the make command works and i get the module kaodv.ko. But when i insert it into my ARM to check, it does not work. It actually freeze my terminal
So my question is, do i have to specify the LDFLAGS when compiling ? Does withdrawing LDFLAGS can have impact on the generated kernel module.
Actually, i try to understand where might be the problem and the only thing that come to me is that may be i should not change manually the LDFLAGS. But if i don't change de LDFLAGS, i get the unrecognized option error.
My second question related to that is, what are the possibly value of LDFLAGS
in ARM compilation
Thanks !!
echo $LDFLAGS : -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,--as-needed
There are two common methods of invoking the linker in a GCC-based toolchain. One is to do it directly, but another is to use GCC as a front end to invoke the linker, rather than invoke it directly. When doing this, options intended for the linker are prefixed with -Wl, so that GCC knows to pass them through rather than interpret them itself.
In your case the error message from LD itself
arm-oe-linux-gnueabi-ld: unrecognized option '-Wl,-O1'
Indicates that your build system is passing LDFLAGS directly to the linker, and not by way of GCC.
Therefore, you should remove the -Wl, prefix and your LDFLAGS would instead be
-O1 --hash-style=gnu --as-needed --as-needed
(the duplication of the last argument is probably pointless but benign)
-O1 is an option that tells the linker to optimize. I believe it something new, and your linker may be slightly out of date. Try removing -Wl,-O1, it should still work.

How to use wx-config information in makefile for setting compiler/linker variables?

I have an application base on wxwidgets, using the boost and pcre lib.
Inside the makefile I have normally to put compiler and linker paths by using the CXXFLAGS variable etc.
I wrote this:
CXXFLAGS := -I. -I/path/boost/prod -I/path/pcre/include $(shell path/wxWidgets/bin/wx-config --unicode=yes --static=yes --cxxflags) -DPCRE_STATIC -O3
CPPFLAGS := -I. -I/path/boost/prod -I/path/pcre/include $(shell path/wxWidgets/bin/wx-config --unicode=yes --static=yes --cppflags) -DPCRE_STATIC -O3
LDFLAGS := -L. -L/path/pcre/lib -L/path/wxWidgets/lib $(shell $path/wxWidgets/bin/wx-config --unicode=yes --static=yes --optional-libs html,aui,stc,xml,adv,core,base) -lpcre -O3
EXEC_POST
From what I now, wx-config tells me which libraries I need.
When I try to link my compiled files, the linker puts an error for not finding e.g. the library "gio-2.0", which is one of the libraries wx-config stated. I can now install all of those not found libraries manually and it work, but normally all this demanded libs should be part of wxwidgets.... I think I messed up with the parts in the above written makefile configuration. What do you think?
You should be using --libs instead of --optional-libs.
Also, you don't need the explicit -L/path/wxWidgets/lib, this is already output by wx-config.

gcc compiling linking .a file

in my homework i must use this command to compile my program:
gcc -o mtm_rentals -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG mtm_ex2.c rentals.c list.c -L -lmtm
what i can change in that line are the files im writing after -DNDEBUG. when i do this the gcc says that there are undefined references to specific functions. now those functions are declared in an .h file and are implemented in a given file called libmtm.a
i concluded that it doesnt recognize libmtm.a, but our homework task says that the -lmtm flag(which is not declared anywhere) is supposed to link libmtm.a to the program.
what am i missing here? am i supposed to implement somehow the -lmtm flag?
thank you!
You are missing a . (single dot) behind the -L.
-lmtm will link against a libmtm library, this is correct. It's not an -lmtm flag, it's a -l flag concatenated with mtm, the library you want to link against. This library is searched in some predefined paths (like /usr/lib/) and additionally in the paths given by -L. Assuming libmtm lives in your current directory, you need to add that to -L, which is done with a ..

Resources