ar, nm, and ranlib are provided by the binutils package. gcc-ar, gcc-nm, and gcc-ranlib are provided by the GCC package. I read somewhere that the gcc-ar, gcc-nm, and gcc-ranlib are "effectively wrappers" around the ar, nm, and ranlib binaries respectively.
What is the technical difference between the gcc-ar, gcc-nm, and gcc-ranlib vs. ar, nm, and ranlib? There must be a reason why GCC provides these binaries in its builds.
When should a build system of a userland package use one vs. the other? If the toolchain being used to build a userland package is GCC based, does it matter which one you use (e.g., ar vs gcc-ar, nm vs gcc-nm)?
gcc-ar is a wrapper for GNU ar such that a command:
gcc-ar ...
is equivalent to:
ar --plugin=/path/to/liblto_plugin.so ...
On my present system, Ubuntu 17.10, GCC 7.2, that would be e.g:
ar --plugin=/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so
There is just the same relationship between nm and gcc-nm.
The --plugin option of the binutils ar and nm enables them to dynamically
load a recognizer/analyser for some non-default format of object file that
they have to deal with.
The shared library liblto_plugin.so is one that enables them to deal with the
IR (intermediate representation) object files produced and consumed in link-time-optimized
builds.
So, if you would do your plain old build like this:
$ gcc -c main.c foo.c bar.c
$ ar cr libfoobar.a foo.o bar.o
$ gcc -o prog main.o -L. -lfoobar
then you'd do your link-time-optimized build like:
$ gcc -flto -c main.c foo.c bar.c
$ gcc-ar cr libfoobar.a foo.o bar.o
$ gcc -flto -o prog main.o -L. -lfoobar
In recent releases of binutils - I don't know which was the first; within the
last 3 or 4 years - liblto_plugin.so has been loaded by default by ar
and nm; so in fact:
$ gcc -flto -c main.c foo.c bar.c
$ ar cr libfoobar.a foo.o bar.o
$ gcc -flto -o prog main.o -L. -lfoobar
will work fine; and nm foo.o will work fine. But the gcc-* versions still serve a purpose in being
independently shipped with GCC, since your regular ar and nm might not
support that default, and if not then that last build, for instance,
would fail in the linkage with undefined references, since ar would fail
to insert in the archive a true symbol table for foo.o and bar.o.
Related
I'm trying to link multiple .o files using gfortran. I've compiled the files like so (in a makefile):
gfortran -c -fopenmp file1.f
gfortran -c -fopenmp file2.f
Now I'd like to link the files with an option for OpenMP. I know with the Intel compiler the linking flag is -liomp5, so to link the files with the Intel compiler one would call:
ifort -o a.out file1.o file2.o -liomp5
This is obviously not the correct flag for the GNU compiler. What is the correct OpenMP linking flag for gfortran?
It is -fopenmp as well:
gfortran -fopenmp -o a.out file1.o file2.o
I use the following LLVM tools to convert a cpp project which is written in multiple files into "ONE" single assembly file.
clang *.cpp -S -emit-llvm
llvm-link *.s -S -o all.s
llc all.s -march=mips
Is there any way of doing this in GCC? In particular, is there any way of linking GCC generated assembly files into one assembly file? i.e., what is the equivalent of LLVM-LINK?
Perhaps LTO (Link Time Optimization) is what you want.
Then, compile each compilation unit with gcc -flto e.g.
gcc -flto -O -Wall -c src1.c
g++ -flto -O -Wall -c src2.cc
and use also -flto (and the same optimizations) to link them:
g++ -flto -O src1.o src2.o -lsomething
LTO works in GCC by putting, in each generated assembly file and object file, some representation of the internal GCC representations (like Gimple). See its documentation
You might want to use MELT to customize GCC (or simply use its probe to understand the Gimple, or try just gcc -fdump-tree-all).
i have a makefile for some code library i'm using and now i've added to that code some code that uses gsl. i'm not so sure how and what to add to the makefile (which i wat to keep since it's invoking boost as well) that would invoke gsl.
This is my makefile:
CXX = g++
ARCH = -mtune=generic
# ARCH = -march=core2
# ARCH = -march=native
COFLAGS = $(ARCH) -O3 -pipe
CXXFLAGS = -Wall $(COFLAGS)
PROGRAMS = getData analyzeData
BOOSTFLAGS = -I .
OPENMP = -fopenmp -DSUPPORT_OPENMP
all: $(PROGRAMS)
getData: getData.cpp common.o parse.o common.h
$(CXX) $(CXXFLAGS) getData.cpp common.o parse.o -o getData
analyzeData: analyzeData.cpp common.o parse.o parameters.o
$(CXX) $(CXXFLAGS) $(BOOSTFLAGS) $(OPENMP) estimateCrossReplicatesExpression.cpp common.o parse.o parameters.o -o analyzeData
parameters.o: parameters.cpp parameters.h
parse.o: parse.cpp parse.h
common.o: common.cpp common.h
clean:
rm *.o $(PROGRAMS)
In case GSL is installed on the default path (/usr/local/include/gsl) on your system, the compilation command for a source file "example.c" would be
gcc -Wall -I/usr/local/include -c example.c
The library is installed as a single file, libgsl.a. A shared version of the library libgsl.so is also installed on systems that support shared libraries. The default location of these files is /usr/local/lib. If this directory is not on the standard search path of your linker you will also need to provide its location as a command line flag.
To link against the library you need to specify both the main library and a supporting cblas library, which provides standard basic linear algebra subroutines. A suitable cblas implementation is provided in the library libgslcblas.a if your system does not provide one. The following example shows how to link an application with the library,
$ gcc -L/usr/local/lib example.o -lgsl -lgslcblas -lm
The option -lm links with the system math library. On some systems it is not needed.
Thus, you need to specify the gsl specific flags in your compile command. Update the Makefile accordingly.
How does one combine two GCC compiled .o object files into a third .o file?
$ gcc -c a.c -o a.o
$ gcc -c b.c -o b.o
$ ??? a.o b.o -o c.o
$ gcc c.o other.o -o executable
If you have access to the source files the -combine GCC flag will merge the source files before compilation:
$ gcc -c -combine a.c b.c -o c.o
However this only works for source files, and GCC does not accept .o files as input for this command.
Normally, linking .o files does not work properly, as you cannot use the output of the linker as input for it. The result is a shared library and is not linked statically into the resulting executable.
$ gcc -shared a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
./executable: error while loading shared libraries: c.o: cannot open shared object file: No such file or directory
$ file c.o
c.o: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Passing -relocatable or -r to ld will create an object that is suitable as input of ld.
$ ld -relocatable a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
The generated file is of the same type as the original .o files.
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
$ file c.o
c.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
For an in-depth explanation see MaskRay's Relocatable linking article.
If you want to create an archive of two or more .o files (i.e.. a static library) use the ar command:
ar rvs mylib.a file1.o file2.o
I was trying to do something like this in a makefile:
program.exe: ui.o main.o
gcc ......etc
ui.o: window1.o window2.o
gcc -c window1.o window2.o -o ui.o #this doesn't want to work
window1.o: window1.c window1.h window1_events.c window1_controls.c ...
gcc -c window1.c window1_events.c window1_controls.c... -o window1.o
window2.o: ...
gcc ...
main.o: ...
gcc ...
but when I compile like this, it gives the error "input file unused because linking not done," and then I get a bunch of unresolved externs, etc--problems which are resolved by changing
program.exe: ui.o main.o
gcc ...
to
program.exe: window1.o window2.o main.o
gcc ...
so is it possible to just link object files together, to avoid having mile-long lines in a makefile and break down the build process a little more?
Yes: to merge several object files into one, use ld -r or ld -Ur:
From "man ld" on Linux:
-r
--relocatable
Generate relocatable output---i.e., generate an output file that can
in turn serve as input to ld. This is often called partial linking.
As a side effect, in environments that support standard Unix magic
numbers, this option also sets the output file’s magic number to
"OMAGIC".
If this option is not specified, an absolute file is produced.
When linking C++ programs, this option will not resolve references to
constructors; to do that, use -Ur.
You could also do this with gcc:
gcc -Wl,-r foo.o bar.o -o foobar.o -nostdlib
Merging object files like this has some advantages over using an archive library: if merged files change very infrequently (compared to say main.c), your final executable links will be faster.
OTOH, with archived library, the linker will only use what it needs, so your executable may end up being smaller if e.g. window2.c ends up not being necessary.
I bunch of object files is a library. You can create a library with the ar
utility. The following example creates a library called mylib.a containing the files foo.o and bar.o
ar rvs mylib.a foo.o bar.o
You can then link with it by using it on the compiler command line:
gcc -o myexe main.c mylib.a
To create a library:
ar rvs somelib.a file1.o file2.o file3.o
To link it:
gcc -o program.exe file4.o somelib.a