Can I tell gcc/ld to exclude unused modules? - gcc

I would like to know if I can tell gcc/ld to omit unused modules from being put into the output file.
Suppose I have modules a.c, b.c and c.c. a.c and b.c depend on each other, one of them contains a main(), and due to whatever reasons, no parts of c.c are referenced.
gcc -c a.c
gcc -c b.c
gcc -c c.c
If I bundle the stuff together into a library, no code from c.c won't be in the output:
ar rcs abc.a a.o b.o c.o
gcc abc.a
But if I give the .o files directly to gcc, the code from c.c resp. c.o is included.
gcc a.o b.o c.o
Can I, by any way, tell gcc to leave out unused modules without putting them into a library?
I am programming an AVR µC and use AVR Studio, which doesn't allow the creation of libraries, but would like to omit the source files which are not used, depending on the build configuration.

I don't know if it's possible on AVR, but you could ask GCC to put each symbols in its own section using -ffunction-sections -fdata-sections at compile time. Then at link step, you could use -Wl,--gc-sections to ask ld to remove unused sections.

Related

What are use cases for GCC's `-fuse-linker-plugin`?

I am trying to better understand link-time optimization in GCC and -fuse-linker-plugin seems to matter in that context. However, I do not exactly understand how.
Suppose my compilation with link-time optimization looks like this:
gcc a.c -c -o a.o -flto -fno-fat-lto-objects
gcc b.c -c -o b.o -flto -fno-fat-lto-objects
gcc main.c -o main.out a.o b.o
What would be a good use case for enabling -fuse-linker-plugin?
I found the official GCC documentation somewhat confusing on that point. They suggest that -fuse-linker-plugin matters only for archive files (.a) but most conversation I have seen mentions that option without discussing archive files.

What is the difference between ar/nm and gcc-ar/gcc-nm?

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.

make is calling g++ is always re-compiles even when I do not change the source code

I am using make which calls g++ always re-compiles the code, even when I do not change the source code. That happens for all my projects, even for simple ones such as:
[code]
all: main.cpp
g++ -std=c++11 -c main.cpp
[/code]
I believe it should compare the date/time on source and object code. Could some help me with this, I am running using GNU toolchain on Ubuntu 12.04
THX
Edit: sorry guys, I do use Makefile, I edited my question accordingly.
Simplest Makefile
It was already pointed out that your Makefile is probably wrong. The 'all' target is indeed always built (although it may result in a no-op if it has no commands and all dependencies are already satisfied). All you need in your makefile is this:
all: main
Object files
If you expect to have more source file in your build, you should consider creating intermediate object files:
all: main
main: main.o
Tweak the build
Make will automatically find the main.ccp file and turn it into main which is required per the directive above. You can use special make variables to further tweak the compilation, e.g. for debug information inclusion and for warning configuration:
CXXFLAGS = -g -Wall -Werror
all: main
main: main.o
Nitpicking
If you insist on building up the compile rule yourself, you can do it like this:
%.o: %.hpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
CXX: C++ compiler
CPPFLAGS: C preprocessor flags
CXXFLAGS: C++ compiler flags
$#: Target
$<: First dependency
If you don't want to use the standard variables nor pattern matching, you can build up the whole makefile explicitly:
all: main
main: main.o
gcc -o $# $^
main.o: main.c
gcc -g -Wall -Werror -o $# -c $<
$^: Use that one if you want to include all dependencies, for example if you have multiple *.o files to build one binary.
Note: It is a bad idea to write the file names directly into the command as you might forget to update them later.
all: main.cpp
g++ -std=c++11 -c main.cpp
This seems wrong. Why does the rule for all has main.cpp as its target? Shouldn't it be something.exe or something.o? Say
all: main.exe
main.exe: main.cpp
g++ -std=c++11 main.cpp -o main.exe
clean:
del main.exe
Targets are output files and cpp files are source code which should be input to the make system.
g++ would have to "recompile" in general (what happens if you change the header but not main.cpp?)
If you are concerned about long build times, you should use something like Make (which is designed specifically to avoid recompiling when the source hasn't changed)
The compiler will always compile the code. If you want to do conditional compilation (based on file times etc) you will need to use a make system such as Make, CMake, Ant, etc. For the simplest you can set up a small "Makefile" in the directory and use the command "make" to build.
Simple Makefile for compiling "myapp.exe" from "main.cpp", "file1.cpp" and "file2.cpp"
myapp.exe: main.o file1.o file2.o
g++ -o myapp.exe main.o file1.o file2.o
(make knows to use .cpp files to build .o files)
But if you also have header files, then you will need to build dependency chains, for which you may want to look into something more sophisticated like automake, cmake, ant, etc.
---- EDIT ----
Based on your updated post, the problem is that you aren't specifying a target, so Make has to assume it needs to recompile. See my example in the above answer.

Combining multiple .o files into an executable

I'm trying to combine object files created from C++ files into an executable using gcc. Unfortunately, gcc is giving me thousands of undefined reference errors to strings, arrays, etc.
I am doing this on a Windows machine, so no terminal commands; only cmd commands.
I'm simply doing:
gcc a.o b.o c.o -o prgm.exe
What am I missing/doing wrong?
EDIT:
I recreated the .o files with g++ doing:
g++ a.cpp -g -c -Wall -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -IC:\SDL-1.2.14\include -o a.o, where a.cpp and a.o are the directories where i keep the files, not the g++ directory
Then, I did g++ a.o b.o c.o -o prgm.exe. This gave dozens (I guess that's an improvement?) errors like
undefined reference to `_SDL_SetColorKey'
but I included SDL didnt I?
The final error from this is:
c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../li
bmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `_WinMain
#16'
collect2.exe: error: ld returned 1 exit status
int main(int argc, char * argv[]) is in the code
You are trying to link a C++ program with the C linker. You need to use g++ instead of gcc.
Generally speaking gcc is for compiling/linking C, while g++ is for C++. IIRC compiling C++-code with gcc works by virtue of dispatching according to the file extension. Linking C++ code with gcc however does not work, since it won't link the C++ standard libraries, resulting in your undefined reference errors.
If this does not solve your problem, you might want to give us a more concrete description of your errors and your system.
Based upon your updates then I think you'd need to do the following:
g++ a.cpp b.cpp c.cpp -g -Wall -IC:\SDL-1.2.14\include -LC:\SDL-1.2.14\lib -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -o prgm.exe
I'm guessing C:\SDL-1.2.14\lib exists based upon where the headers are located.
GCC is the C compiler. Your code is C++ so you need to use G++ to do the linking:
g++ a.o b.o c.o -o prgm.exe
This automatically adds the C++ libraries to the link line, resolving many if not all of your missing references.

is it possible to create an object file from other object files in gcc?

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

Resources