Jellicle
Jellicle

Reputation: 30276

Will my linker link objects from unneeded source files?

When compiling a project, if my source files include a file with no used functions, will the unneeded object file be included in the compiler's output?

e.g.

foo.c

int main() {return 0;}

bar.c

void unusedFunction {;}

compiler execution:

gcc foo.c bar.c -o output

Would the output file be any smaller if I had omitted bar.c from the compiler command?

Upvotes: 2

Views: 473

Answers (3)

Ed Heal
Ed Heal

Reputation: 60037

Use something like Scons (http://www.scons.org/) or Gradle (http://www.gradle.org/) to figure out the dependencies and will then just link the appropriate bits (assuming you are using static linking)

Dynamic linking is another matter — you get the lot as other programs may need the additional stuff.

But as to the command line given it will link it in. Why add it in the first place if it is not required?

Upvotes: 0

Dietrich Epp
Dietrich Epp

Reputation: 213767

Most linkers will link unneeded files unless you tell them not to. There are flags for this.

Suppose you link with two unnneeded files: an object file and a library:

gcc main.o unneeded.o -lunneeded

With GNU Binutils or Gold, the flags are --gc-sections for unneeded symbols / object files, and --as-needed for libraries. These are linker flags, however, so they must be prefixed with -Wl,. Note that the order of these flags is important—flags only apply to libraries and object files which appear after the flags on the command line, so the flags must be specified first.

gcc -Wl,--as-needed -Wl,--gc-sections main.o unneeded.o -lunneeded

On OS X, there is a different linker so the flags are different. The -dead_strip flag removes unneeded symbols / object files, and the -dead_strip_dylibs flag removes unneeded libraries.

gcc -Wl,-dead_strip -Wl,-dead_strip_dylibs main.o unneeded.o -luneeded

Example

$ cat main.c
int main() { }
$ cat unneeded.c
void unneeded() { }
$ gcc -c main.c
$ gcc -c unneeded.c

If we link normally, we get everything...

$ gcc main.o unneeded.o -lz
$ nm a.out | grep unneeded
0000000000400574 T unneeded
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libz.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

With the right flags, we get just what we need...

$ gcc -Wl,--as-needed -Wl,--gc-sections main.o unneeded.o -lz
$ nm a.out | grep unneeded
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Upvotes: 4

n. m. could be an AI
n. m. could be an AI

Reputation: 120079

Every source or object file referenced in the compilation command will be included in the final executable.

To include only what's needed, build a static library from your objects, and refer to it when linking, rather than to individual objects. Static libraries were invented just for this purpose.

Upvotes: 1

Related Questions