 <?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://Robo.Fish/wiki/index.php?action=history&amp;feed=atom&amp;title=GCC</id>
	<title>GCC - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://Robo.Fish/wiki/index.php?action=history&amp;feed=atom&amp;title=GCC"/>
	<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GCC&amp;action=history"/>
	<updated>2026-04-22T16:04:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GCC&amp;diff=2854&amp;oldid=prev</id>
		<title>Kai: /* Hiding internal implementation details */</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GCC&amp;diff=2854&amp;oldid=prev"/>
		<updated>2018-05-21T11:22:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Hiding internal implementation details&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=== &amp;lt;br /&amp;gt;Introduction ===&lt;br /&gt;
The GNU Compiler Collection (https://gcc.gnu.org/) is the default compiler on GNU/Linux operating systems like Ubuntu and Raspbian. It evolved from the GNU C Compiler project and kept its acronym while adding support for programming languages like C++, Objective-C, and Go.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Switching between GCC versions in Ubuntu ====&lt;br /&gt;
The versions of GCC in the Ubuntu main repositories are&lt;br /&gt;
* Ubuntu 16.04: GCC 5.5&lt;br /&gt;
* Ubuntu 18.04: GCC 7.3&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Sometimes, however, you need to use a different version of GCC, and you want to easily switch between versions. For example, between GCC 6 and GCC 7 in Ubuntu 18.04. To do so, you can use the &amp;#039;&amp;#039;update-alternatives&amp;#039;&amp;#039; tool. Here is how to configure &amp;#039;&amp;#039;update-alternatives&amp;#039;&amp;#039; for GCC.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
First, make sure that no alternatives group for GCC exists by typing&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
sudo update-alternatives --remove-all gcc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
which should result in the error message&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
update-alternatives: error: no alternatives for gcc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now enter&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 10&lt;br /&gt;
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 20&lt;br /&gt;
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 10&lt;br /&gt;
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the last number in each line is the priority of the corresponding alternative.&lt;br /&gt;
You can check that the alternatives groups are configured by entering&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
update-alternatives --list gcc&lt;br /&gt;
update-alternatives --list g++&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
You can now select the desired GCC version via the interactive chooser&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
sudo update-alternatives --config gcc&lt;br /&gt;
sudo update-alternatives --config g++&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or directly via&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
sudo update-alternatives --set gcc [/usr/bin/gcc-6 | /usr/bin/gcc-7]&lt;br /&gt;
sudo update-alternatives --set g++ [/usr/bin/g++-6 | /usr/bin/g++-7]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where only one of the options inside the square brackets must be entered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;  &lt;br /&gt;
=== Usage ===&lt;br /&gt;
==== Some Useful Command-Line Options ====&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| -g || generate debug output&lt;br /&gt;
|-&lt;br /&gt;
| -c || compile only (do not link)&lt;br /&gt;
|-&lt;br /&gt;
| -O2 || optimize for size and speed&lt;br /&gt;
|-&lt;br /&gt;
| -std=c++14 || enable C++14 features&lt;br /&gt;
|-&lt;br /&gt;
| -x || process for the given programming language&lt;br /&gt;
|-&lt;br /&gt;
| -c -x c++-header -o m.gch m.h || turn m.h into a precompiled header (m.gch)&lt;br /&gt;
|-&lt;br /&gt;
| -Wl,-rpath,&amp;lt;path&amp;gt; -L&amp;lt;path&amp;gt; -lmylib || make the linker embed the given relative path to the given library&lt;br /&gt;
|}&lt;br /&gt;
The full list of command-line options can be viewed [https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html here].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Gotchas ===&lt;br /&gt;
Here are some of the fine points of using GCC:&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
===== Linker flags come last =====&lt;br /&gt;
When compiling source files into object files or linking object files into an executable or library file, the placement of the linker flags relative to the input file within the GCC command matters! External libraries that are being linked to need to be specified AFTER THE OBJECT FILE that refers to the symbols in the library. The linker does not know it needs to link to the external library before it sees the references in the object file. You will see error messages that complain about &amp;quot;undefined reference to&amp;quot; some external symbol if the library is not specified, or specified too early.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
From the [https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html GNU documentation]: &amp;quot;It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, &amp;#039;&amp;#039;foo.o -lz bar.o&amp;#039;&amp;#039; searches library &amp;#039;&amp;#039;z&amp;#039;&amp;#039; after file &amp;#039;&amp;#039;foo.o&amp;#039;&amp;#039; but before &amp;#039;&amp;#039;bar.o&amp;#039;&amp;#039;. If &amp;#039;&amp;#039;bar.o&amp;#039;&amp;#039; refers to functions in &amp;#039;&amp;#039;z&amp;#039;&amp;#039;, those functions may not be loaded.&amp;quot;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
By the way, you can use the &amp;#039;&amp;#039;ldd&amp;#039;&amp;#039; command line tool to check if all the linked libraries can be located by the dynamic loader.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== C++ ABI change in GCC 5.1 =====&lt;br /&gt;
The ABI for C++11 changed in GCC 5.1. This requires that libraries that were built with an older version of GCC need to be linked against after compiling with the environment variable set to &amp;quot;0&amp;quot;. That is,&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
g++ -D_GLIBCXX_USE_CXX11_ABI=0 my_code.cpp -o my_code.o&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
See https://gcc.gnu.org/gcc-5/changes.html#libstdcxx for more information.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Hiding internal implementation details =====&lt;br /&gt;
When creating a library you may want to remove internal implementation details to reduce the size of the library or to protect your intellectual property. Use the compiler flag &amp;#039;&amp;#039;-fvisibility=hidden&amp;#039;&amp;#039; in order to mark generated symbols as local (= not to be exported) by default. In your code mark selected functions, methods, or variables as global (= to be exported) by placing the GCC visibility attribute&lt;br /&gt;
&amp;lt;pre class=&amp;quot;code&amp;quot;&amp;gt;&lt;br /&gt;
__attribute__ (( visibility(&amp;quot;default&amp;quot;) ))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
in front of the declaration. See this [https://gcc.gnu.org/wiki/Visibility GCC Wiki entry] for more information on the visibility attribute.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
We&amp;#039;re not done yet. The library created by the linker still contains all the symbols that were marked as local. You can check whether symbols inside the binary are local or global (exported) by inspecting the library with the command-line tool &amp;#039;&amp;#039;nm&amp;#039;&amp;#039;: &lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
nm --demangle my_library.so&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the option &amp;#039;&amp;#039;--demangle&amp;#039;&amp;#039; is for displaying C++ symbols with the familiar double-semicolon scope separators instead of cryptic alphanumeric sequences. Symbols are listed with a letter next to it, like &amp;#039;A&amp;#039;, &amp;#039;C&amp;#039; or &amp;#039;R&amp;#039;. The letter indicates the type of the symbol. If the letter is in upper case, the symbol is global, otherwise it is usually local. Refer to the [http://man7.org/linux/man-pages/man1/nm.1.html nm manual] for details. In order to purge our local symbols from the library file, we use the command line tool &amp;quot;strip&amp;quot;:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
strip -x my_library.so&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the option &amp;#039;&amp;#039;-x&amp;#039;&amp;#039; specifies that all non-global symbols should be removed.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Specifying the path to your library =====&lt;br /&gt;
If you don&amp;#039;t want to place your shared libraries into one of the default folders where the library loader of the operating system can find them (on Linux systems these folders are specified in &amp;#039;&amp;#039;/etc/ld.so.conf&amp;#039;&amp;#039; and in additional &amp;#039;&amp;#039;.conf&amp;#039;&amp;#039; files lying in &amp;#039;&amp;#039;/etc/ld.so.conf.d/&amp;#039;&amp;#039;) then you need to specify the paths to your libraries either by [http://wiredrevolution.com/system-administration/how-to-correctly-use-ld_library_path setting the &amp;#039;&amp;#039;LD_LIBRARY_PATH&amp;#039;&amp;#039; environment variable] before launching the executable that links to the library, or by baking the (relative) path to the library into the executable itself. &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use the &amp;#039;&amp;#039;rpath&amp;#039;&amp;#039; option in the linking step of your executable to specify the relative path from your executable to the library. For example, &lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
g++ class1.o class2.o -Wl,-rpath,../../my_libs -L../../my_libs -lMyLib -o my_app&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
creates the executable &amp;#039;&amp;#039;my_app&amp;#039;&amp;#039; that links to the dynamic library &amp;#039;&amp;#039;libMyLib.so&amp;#039;&amp;#039; located in the folder &amp;#039;&amp;#039;../../my_libs&amp;#039;&amp;#039;, relative to the executable. If you are not familiar with &amp;#039;&amp;#039;-Wl&amp;#039;&amp;#039;; it denotes the beginning of a comma-separated sequence of options to be passed to the GCC linker (as a whitespace-separated sequence).&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
On Linux, you can use the &amp;#039;&amp;#039;readelf&amp;#039;&amp;#039; command-line tool to verify that the correct library search paths are baked into the generated [https://en.wikipedia.org/wiki/Executable_and_Linkable_Format ELF binary]: &lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
readelf -d &amp;lt;path to library or executable&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
On macOS, look for the keyword &amp;#039;&amp;#039;LC_RPATH&amp;#039;&amp;#039; in the output of&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
otool -l &amp;lt;path to library or executable&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Sanitizers ===&lt;br /&gt;
On Ubuntu 18.04, you can install Address Sanitizer and Undefined Behavior Sanitizer for GCC 7.x via &lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install libubsan0 libasan4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Address Sanitizer ====&lt;br /&gt;
This sanitizer catches certain problems related to memory management. It is instrumented into the executable with the following GCC flag&lt;br /&gt;
&amp;lt;pre class=&amp;quot;code&amp;quot;&amp;gt;&lt;br /&gt;
-fsanitize=address&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
which needs to be specified separately for the compiler and the linker.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
A number of [https://github.com/google/sanitizers/wiki/AddressSanitizerFlags options] can be passed to the address sanitizer either via the &amp;#039;&amp;#039;ASAN_OPTIONS&amp;#039;&amp;#039; environment variable or by embedding the following function:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;code&amp;quot;&amp;gt;&lt;br /&gt;
extern &amp;quot;C&amp;quot; {&lt;br /&gt;
const char* __asan_default_options() {&lt;br /&gt;
  return &amp;quot;verbosity=1:help=1&amp;quot;; // add options here&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For more information visit https://github.com/google/sanitizers/wiki/AddressSanitizer&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Undefined Behavior Sanitizer ====&lt;br /&gt;
This sanitizer is for catching undefined behavior in C/C++ code. It is instrumented into the executable by passing&lt;br /&gt;
&amp;lt;pre class=&amp;quot;code&amp;quot;&amp;gt;&lt;br /&gt;
-fsanitize=undefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to both the compiler and the linker.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
For more information see the GCC documentation page on [https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html instrumentation options].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
</feed>