Minimal executable size after linkage - c++

I link with Qt statically, so can linker or some other tool avoid adding unused binary code (from Qt libraries) to the final executable? I don't think i use all the 10 MB of Qt library code.

If you compile the Qt library yourself at some point and you are using the g++ you should try to use the Link Time Optimisation (LTO) options.
You can do this by adding -flto to all your g++ calls. This lets the g++ add so called GIMPLE code to your object files which corresponds to your source (so it is not completly compiled). In the linking step you should add -fwhole-program or -fuse-linker-plugin. The gcc then reads the Gimple code, and optimises your program as a whole, therby it should be able to get rid of any unused code. However I cannot garantee this works for you.

Related

G++ compiler giving "undefined reference" error to functions I have clearly defined

I have referenced several other questions on this site and others addressing this topic and nothing has helped my issue so far.
I have two classes and a main program written in c++. Total 5 files. Everything is written originally in Visual Studio 2013 and compiles and runs there.
All are in a single folder and I use this command to compile them:
g++ myprogram.cpp
I get errors "undefined reference" errors for the contructors and destructors of both classes. Is there something obvious that I am doing wrong? If not I will post my code. Thank you.
When you invoke g++ directly like this, it will do all the steps by default, including linking. Since you haven't listed your other source files, you really just want to do compilation (it would seem) and then link the results of compiling each individual source file. You can use the "-c" option to make it just compile (rather than compile and link). Or, if you do want to build all your source files and link them together, then you should list all of the source files in question. That is:
g++ *.cpp -o yourexecutable # To compile and link all the sources
Or:
g++ -c yourfile.cpp -o yourobjectfile.o # To compile a single source
But really you shouldn't invoke g++ directly at all; there are build systems that provide a layer of abstraction on top of GCC (and other tool chains) that would be a far better, more portable, and simpler approach to building your application. For example, Bazel or Gradle would be better ways to build your program from the commandline. Though not the best or most modern build system, even using Make (and relying on its implicit rules) would be better than direclty invoking the compiler.

How can I statically link standard library to my C++ program?

I'm using Code::Blocks IDE(v13.12) with GNU GCC Compiler.
I want to the linker to link static versions of required runtime libraries for my programs, how may I do this?
I already know that my executable size will increase. Would you please tell me other the downsides?
What about doing this in Visual C++ Express?
Since nobody else has come up with an answer yet, I will give it a try. Unfortunately, I don't know that Code::Blocks IDE so my answer will only be partial.
1 How to Create a Statically Linked Executable with GCC
This is not IDE specific but holds for GCC (and many other compilers) in general. Assume you have a simplistic “hello, world” program in main.cpp (no external dependencies except for the standard library and runtime library). You'd compile and statically link it via:
Compile main.cpp to main.o (the output file name is implicit):
$ g++ -c -Wall main.cpp
The -c tells GCC to stop after the compilation step (not run the linker). The -Wall turns on most diagnostic messages. If novice programmers would use it more often and pay more attention to it, many questions on this site would not have been asked. ;-)
Link main.o (could list more than one object file) statically pulling in the standard and runtime library and put the executable in the file main:
$ g++ -o main main.o -static
Without using the -o main switch, GCC would have put the final executable in the not so well-named file a.out (which once eventually stood for “assembly output”).
Especially at the beginning, I strongly recommend doing such things “by hand” as it will help get a better understanding of the build tool-chain.
As a matter of fact, the above two commands could have been combined into just one:
$ g++ -Wall -o main main.cpp -static
Any reasonable IDE should have options for specifying such compiler / linker flags.
2 Pros and Cons of Static Linking
Reasons for static linking:
You have a single file that can be copied to any machine with a compatible architecture and operating system and it will just work, no matter what version of what library is installed.
You can execute the program in an environment where the shared libraries are not available. For example, putting a statically linked CGI executable into a chroot() jail might help reduce the attack surface on a web server.
Since no dynamic linking is needed, program startup might be faster. (I'm sure there are situations where the opposite is true, especially if the shared library was already loaded for another process.)
Since the linker can hard-code function addresses, function calls might be faster.
On systems that have more than one version of a common library (LAPACK, for example) installed, static linking can help make sure that a specific version is always used without worrying about setting the LD_LIBRARY_PATH correctly. Obviously, this is also a disadvantage since now you cannot select the library any more without recompiling. If you always wanted the same version, why would you have installed more than one in the first place?
Reasons against static linking:
As you have already mentioned, the size of the executable might grow dramatically. This depends of course heavily on what libraries you link in.
The operating system might be smart enough to load the text section of a shared library into the RAM only once if several processes need the library at the same time. By linking statically, you void this advantage and the system might run short of memory more quickly.
Your program no longer profits from library upgrades. Instead of simply replacing one shared library with a (hopefully ABI compatible) newer release, a system administrator will have to recompile and reinstall every program that uses it. This is the most severe drawback in my opinion.
Consider for example the OpenSSL library. When the Heartbleed bug was discovered and fixed earlier this year, system administrators could install a patched version of OpenSSL and restart all services to fix the vulnerability within a day as soon as the patch was out. That is, if their services were linking dynamically against OpenSSL. For those that have been linked statically, it would have taken weeks until the last one was fixed and I'm pretty sure that there is still proprietary “all in one” software out in the wild that did not see a fix up to the present day.
Your users cannot replace a shared library on the fly. For example, the torsocks script (and associated library) allows users to replace (via setting LD_PRELOAD appropriately) the networking system library by one that routes their traffic through the Tor network. And this even works for programs whose developers never even thought of that possibility. (Whether this is secure and a good idea is subject of an unrelated debate.) An other common use-case is debugging or “hardening” applications by replacing malloc and the like with specialized versions.
In my opinion, the disadvantages of static linking outweigh the advantages in all but very special cases. As a rule of thumb: link dynamically if you can and statically if you have to.
A Addendum
As Alf has pointed out (see comments), there is a special GCC option to selectively link in the C++ standard library statically but not link the whole program statically. From the GCC manual:
-static-libstdc++
When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.
In Visual C++, the /MT option does a static link and the /MD option does a dynamic link. (see http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx)
I'd recommend using /MD and redistributing the C++ runtime, which is freely available from Microsoft. Once the C++ runtime is installed, than any program requiring the run time will continue to work. You would need to pass the proper option to tell the compiler which runtime to use. There is a good explanation here, Should I compile with /MD or /MT?
On Linux, I'd recommend redistributing libstdc++ instead of a static link. If their system libstdc++ works, I'd let the user just use that. System libraries, such as libpthread and libgcc should just use the system default. This requires compiling the program on a system with symbols compatible with all linux versions you are distributing for.
On Mac OS X, just redistribute the app with dynamic linking to libstdc++. Anyone using the same OS version should be able to use your program.

Various Makefile Issues

I am trying to compile my project for use of debugging with gprof; however, I am having numerous issues.
Right now, I am trying to create a separate target in my makefile that is 'gprof' which depends upon the executable. This target, beforehand, adds the flags -g -gdwarf-3 and -pg to the compilation flags and -pg to the linker flags.
The unfortunate thing is I cannot get gprof to run successfully, as my compiled binary doesn't produce the required gmon.out. There are also side issues regarding this process.
1.) I am getting an issue regarding a clang warning when trying to introduce gdwarf-3 flags. This issue is clang: warning: argument unused during compilation: '-gdwarf-3'.
2.) The makefiles (3 of them, one main, one more main executable, and one for linked library) were produced by premake. I have edited them to introduce compiler and linker flags.
3.) I don't know how to compile the linked library (vecmath) under gprof (do I even need to?). The ar command doesn't accept the necessary -pg flag needed for gprof.
I am trying to perform this on a macbook air 2011, MAC OSX 10.8. I will try to attempt this later in linux.
My three makefiles are shared here. Makefile calls a5.make and vecmath_makefile (this file title was edited). Any help is appreciated thanks!

Is g++ both a c++ compiler and a linker?

I was looking at the output from my build in Eclipse. I'm cross compiling for a ColdFire processor. The compilation line looks like this:
m68k-elf-g++ -O2 -falign-functions=4 -IC:\nburn\include -IC:\nburn\MOD52...
followed by more include file, obvious "compiler" flags and finally the one source file I changed. The next line invokes the same tool again:
m68k-elf-g++ src\main.o src\TouchPanelMediator.o src\Startup.o....
followed by more .o files some .ld files and some .a files. This appears to be linking all the various types of object files together.
In the Gnu family is g++ some uber application that can determine based on arguments whether it needs to compile or link? Does it have both capabilities built-in or is it just dispatching compiling to gcc and linking to ld and my log just doesn't show that?
g++ and gcc are drivers. Usually, they run the preprocessor (cpp), compiler proper (cc1plus for C++ and cc1 for C) and the linker (gold or GNU ld) and all other things necessary. The difference between gcc and g++ is that the latter includes one additional library to link against (libstdc++).
Depending on what type of file they are invoked on, they may omit some steps or do things differently. For .o files, it doesn't need to run the compiler proper or the preprocessor, for example.
If you pass -### to them, you can see it print the tools it invokes in each step of its execution.
Taken from this little GCC guide:
Based on the file extension that you gave your program, it selects the appropriate commands it needs to run to turn the source you gave it into the output file you specified.
With a nice little flowchart of what GCC exactly does, depending on the file extensions:
input extensions runs if output
It dispatches linking to ld.
Also see here:
How to get GCC linker command?

Tips on reducing c++ linking time

I have a project that takes about 8 seconds to link with g++ and ld.
It uses a bunch of static libraries, most of the code is c++.
I'm interested in a general list of tips on how to reduce link time.
Anything from "dont include debug symbols" to "make your code less spagetti"
I dealt with this for years at a previous job. The GNU linker simply has serious performance problems when linking large numbers of static libraries. At one point, link time was on par with compile time, which we found so strange we actually investigated this and figured it out.
You can try to merge your static libraries into a "super-object" before linking. Instead of linking like this:
$ g++ -o program program.o $STATIC_LIBS
You could try this:
$ ld -r -o libraries.o --whole-archive $STATIC_LIBS
$ g++ -o program program.o libraries.o
Note that this method gives the linker less opportunity to exclude unused object code, so your binaries may increase in size somewhat.
create a ramdisk ,compile to that and link to harddisk.
since you're using a lot of static libraries ,you can create a giant library containing all thos libraries so you end up with one libray. remove all libraries from your lib-list and add th giant one. This reduces openings of file to 1 for the libraries and may speed up reading actions.
Turn off whole program optimization (at least during development). Use p-impl to reduce dependencies.
8 seconds is pretty fast, unless you're really sure that it shouldn't take that long. I've got projects that take 5-8 minutes for a full relink since we don't do incremental linking on our release builds. Have you tried using incremental linking (if you're not using -shared, you can use -i or -r)?
How about compiling debug builds as shared libraries? That will solve the debug symbol bloat, as the import libraries are tiny with or without debug info. Maybe not the best solution, but I think this will cut down link time substantially...
You could try using clang and lld. From godot docs
You can also use Clang and LLD to build Godot. This has two upsides
compared to the default GCC + GNU ld setup:
LLD links Godot significantly faster compared to GNU ld or gold. This leads to faster iteration times.