{"id":3383,"date":"2015-03-18T03:12:57","date_gmt":"2015-03-18T03:12:57","guid":{"rendered":"http:\/\/www.gubatron.com\/blog\/?p=3383"},"modified":"2015-12-21T00:07:39","modified_gmt":"2015-12-21T00:07:39","slug":"things-to-remember-when-compilinglinking-cc-software","status":"publish","type":"post","link":"https:\/\/www.gubatron.com\/blog\/things-to-remember-when-compilinglinking-cc-software\/","title":{"rendered":"# Things to remember when compiling\/linking C\/C++ software"},"content":{"rendered":"<p>by <a href=\"http:\/\/onename.io\/gubatron\">Angel Leon<\/a>. March 17, 2015.<\/p>\n<h2>Include Paths<\/h2>\n<p>On the compilation phase, you will usually need to specify the different include paths so that the interfaces (.h, .hpp) which define structs, classes, constans, and functions can be found.<\/p>\n<p>With <code>gcc<\/code> and <code>llvm<\/code> include paths are passed with <code>-I\/path\/to\/includes<\/code>, you can pass as many <code>-I<\/code> as you need.<\/p>\n<p>In Windows, <code>cl.exe<\/code> takes include paths with the following syntax:<br \/>\n<code>\/I\"c:\\path\\to\\includes\\<\/code> you can also pass as many as you need.<\/p>\n<p>Some software uses macro definition variables that should be passed during compile time to decide what code to include.<\/p>\n<h2>Compilation flags<\/h2>\n<p>These compilation-time variables are passed using <code>-D<\/code>,<br \/>\ne.g. <code>-DMYSOFTWARE_COMPILATION_VARIABLE<\/code> <code>-DDO_SOMETHING=1<\/code> <code>DDISABLE_DEPRECATED_FUNCTIONS=0<\/code><\/p>\n<p>These compilation time flags are by convention usually put into a single variable named <code>CXXFLAGS<\/code>, which is then passed to the compiler as a parameter for convenience when you&#8217;re building your compilation\/make script.<\/p>\n<h2>Object files<\/h2>\n<p>When you compile your .c, or .cpp files, you will end up with object files.<br \/>\nThese files usually have <code>.o<\/code> extensions in Linux, in Windows they might be under <code>.obj<\/code> extensions.<\/p>\n<p>You can create an <code>.o<\/code> file for a single or for many source files.<\/p>\n<h2>Static Library files<\/h2>\n<p>When you have several <code>.o<\/code> files, you can put them together as a library, a static library. In Linux\/Mac these static libraries are simply archive files, or <code>.a<\/code> files. In windows, static library files exist under the <code>.lib<\/code> extension.<\/p>\n<p><strong>They are created like this in Linux\/Mac:<\/strong><\/p>\n<p><code>ar -cvq libctest.a ctest1.o ctest2.o ctest3.o<\/code><\/p>\n<p><code>libctest.a<\/code> will contain <code>ctest1.o<\/code>,<code>ctest2.o<\/code> and <code>ctest2.o<\/code><\/p>\n<p><strong>They are created like this in Windows:<\/strong><\/p>\n<p><code>LIB.EXE \/OUT:MYLIB.LIB FILE1.OBJ FILE2.OBJ FILE3.OBJ<\/code><\/p>\n<p>When you are creating an executable that needs to make use of a library, if you use these static libraries, the size of your executable will be the sum of all the object files statically linked by the executable. The code is right there along the executable, it&#8217;s easier to distribute, but again, the size of the executable can be bigger than it needs to&#8230; why? because, sometimes, many of the <code>.o<\/code> files, or even the entire <code>.a<\/code> file you&#8217;re linking against might be a standard library that many other programs need.<\/p>\n<h2>Shared Libraries (Dynamic Libraries)<\/h2>\n<p>So <strong><em>shared<\/em><\/strong> or <strong><em>dynamic<\/em><\/strong> libraries were invented so that different programs or libraries would make external (shared) references to them, since they&#8217;re &#8220;shared&#8221; the symbols defined in them don&#8217;t need to be part of your executable or library, your executable contain symbols whose entry points or offset addresses might point to somewhere within themselves, but they will also have symbols whose entry points are expected to exist on shared libraries which need only be loaded once in a single portion of the operating shared memory, thus not just making the size of your executable as small as it needs to be, but you won&#8217;t need to load the library for every process\/program that needs its symbols.<\/p>\n<p>On Linux shared files exist under the <code>.so<\/code> (shared object) file extension, on Mac <code>.dylib<\/code> (dynamic library), and in Windows they&#8217;re called <code>.dll<\/code> (dynamic link libraries)<\/p>\n<p>Another cool thing about dynamic libraries, is that they can be linked during runtime, not just compile time. An example of runtime dynamic libraries are browser plugins.<\/p>\n<p>In Linux <code>.so<\/code> files are created like this:<\/p>\n<pre><code>gcc -Wall -fPIC -c *.c\ngcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0   *.o\n<\/code><\/pre>\n<ul>\n<li><code>-Wall<\/code> enables all warnings.<\/li>\n<li><code>-c<\/code> means don&#8217;t run the linker.<\/li>\n<li><code>-fPIC<\/code> means &#8220;Position Independent Code&#8221;, a requirement for shared libraries in Linux.<\/li>\n<li><code>-shared<\/code> makes the object file created shareable by different executables.<\/li>\n<li><code>-Wl<\/code> passes a comma separated list of arguments to the linker.<\/li>\n<li><code>-soname<\/code> means &#8220;shared object name&#8221; to use.<\/li>\n<\/ul>\n<p>In Mac <code>.dylib<\/code> files are created like this:<\/p>\n<p><code>clang -dynamiclib -o libtest.dylib file1.o file2.o -L\/some\/library\/path -lname_of_library_without_lib_prefix<\/code><\/p>\n<p>In Windows <code>.dll<\/code> files are created like this:<\/p>\n<p><code>LINK.EXE \/DLL \/OUT:MYLIB.DLL FILE1.OBJ FILE2.OBJ FILE3OBJ<\/code><\/p>\n<h2>Linking to existing libraries<\/h2>\n<p>When linking your software you may be faced with a situation on which you want to link against several standard shared libraries.<br \/>\nIf all the libraries you need exist in a single folder, you can set the <code>LD_LIBRARY_PATH<\/code> to that folder. <strong><em>By common standard all shared libraries are prefixed with the word <code>lib<\/code><\/em><\/strong>. If a library exists in <code>LD_LIBRARY_PATH<\/code> and you want to link against it, you don&#8217;t need to pass the entire path to the library, you simply pass <code>-lname<\/code> and you will link your executable to the symbols of <code>libname.so<\/code> which should be somewhere inside <code>LD_LIBRARY_PATH<\/code>.<\/p>\n<p>Tip: You should probably stay away from altering your <code>LD_LIBRARY_PATH<\/code>, if you do, make sure you keep its original value, and when you&#8217;re done restore it, as you might screw the build processes of other software in the system which might depend on what&#8217;s on the <code>LD_LIBRARY_PATH<\/code>.<\/p>\n<p>If you have some other <code>libbar.so<\/code> library on another folder outside <code>LD_LIBRARY_PATH<\/code> you can explictly pass the full path to that library <code>\/path\/to\/that\/other\/library\/libbar.so<\/code>, or you can specify the folder that contains it <code>-L\/path\/to\/that\/other\/library<\/code> and then the short hand form <code>-lbar<\/code>. This latter option makes more sense if the second folder contains several other libraries.<\/p>\n<h2>Useful tools<\/h2>\n<p>Sometimes you may be dealing with issues like <code>undefined symbol<\/code> errors, and you may want to inspect what symbols (functions) are defined in your library.<\/p>\n<p>On Mac there&#8217;s <code>otool<\/code>, on Linux\/Mac there&#8217;s <code>nm<\/code>, on Windows there&#8217;s <code>depends.exe<\/code> (a GUI tool that can be used to see both dependencies and the symbol&#8217;s tables. Taking a look at the &#8220;Entry Point&#8221; column will help you understand clearly the difference between symbols linking to a shared library vs symbols linking statically to the same library)<\/p>\n<h3>Useful command options<\/h3>\n<p><strong><em>See shared library dependencies on Mac with <code>otool<\/code><\/em><\/strong><\/p>\n<pre><code>otool -L libjlibtorrent.dylib \nlibjlibtorrent.dylib:\n    libjlibtorrent.dylib (compatibility version 0.0.0, current version 0.0.0)\n    \/usr\/lib\/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)\n    \/usr\/lib\/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)\n<\/code><\/pre>\n<p><strong><em>See shared symbols with <code>nm<\/code> (Linux\/Mac)<\/em><\/strong><br \/>\nWith nm, you can see the symbol&#8217;s name list.<br \/>\nFamiliarize yourself with the meaning of the symbol types:<br \/>\n * <code>T<\/code> (text section symbol)<br \/>\n * <code>U<\/code> (undefined &#8211; useful for those <code>undefined symbol<\/code> error),<br \/>\n * <code>I<\/code> (indirect symbol).<br \/>\n *<br \/>\nIf the symbol is local (non-external) the symbol type is presented in lowercase letters, for example a lowercase <code>u<\/code> represents an undefined reference to a private external in another module in the same library.<\/p>\n<p><code>nm<\/code>&#8216;s documentation says that if you&#8217;re working on Mac and you see that the symbol is preceeded by <code>+<\/code> or <code>-<\/code> it means it&#8217;s an ObjectiveC method, if you&#8217;re familiar with ObjectiveC you will know that <code>+<\/code> is for class methods and <code>-<\/code> is for instance methods, but in practice it seems to be a bit more explicit and you will often see <code>objc<\/code> or <code>OBJC<\/code> prefixed to those methods.<\/p>\n<p><code>nm<\/code> is best used along with <code>grep<\/code> \ud83d\ude09<\/p>\n<p><strong><em>Find all Undefined symbols<\/em><\/strong><\/p>\n<pre><code>nm -u libMacOSXUtilsLeopard.jnilib\n_CFRelease\n_LSSharedFileListCopySnapshot\n_LSSharedFileListCreate\n_LSSharedFileListInsertItemURL\n_LSSharedFileListItemRemove\n_LSSharedFileListItemResolve\n_NSFullUserName\n_OBJC_CLASS_$_NSArray\n_OBJC_CLASS_$_NSAutoreleasePool\n_OBJC_CLASS_$_NSDictionary\n_OBJC_CLASS_$_NSMutableArray\n_OBJC_CLASS_$_NSMutableDictionary\n_OBJC_CLASS_$_NSString\n_OBJC_CLASS_$_NSURL\n__Block_copy\n__NSConcreteGlobalBlock\n__dyld_register_func_for_add_image\n__objc_empty_cache\n__objc_empty_vtable\n_calloc\n_class_addMethod\n_class_getInstanceMethod\n_class_getInstanceSize\n_class_getInstanceVariable\n_class_getIvarLayout\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>by Angel Leon. March 17, 2015. Include Paths On the compilation phase, you will usually need to specify the different include paths so that the interfaces (.h, .hpp) which define structs, classes, constans, and functions can be found. With gcc and llvm include paths are passed with -I\/path\/to\/includes, you can pass as many -I as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3409,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[15],"tags":[232,239,1371,1427,1428],"class_list":["post-3383","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code","tag-building","tag-c","tag-compiling","tag-cplusplus","tag-software-development"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2015\/03\/make-all-executables.png?fit=680%2C510&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5Unzf-Sz","jetpack-related-posts":[{"id":3949,"url":"https:\/\/www.gubatron.com\/blog\/things-to-remember-when-compiling-linking-c-c-software\/","url_meta":{"origin":3383,"position":0},"title":"Things to remember when compiling\/linking C\/C++ software","author":"gubatron","date":"May 7, 2021","format":false,"excerpt":"https:\/\/gist.github.com\/gubatron\/32f82053596c24b6bec6","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3215,"url":"https:\/\/www.gubatron.com\/blog\/building-cgminer-from-source-on-osx\/","url_meta":{"origin":3383,"position":1},"title":"building cgminer from source on OSX","author":"gubatron","date":"January 19, 2014","format":false,"excerpt":"so you cloned the cgminer repo from github to build on your OSX machine and you get this bullshit error $ .\/autogen.sh readlink: illegal option -- f usage: readlink [-n] [file ...] usage: dirname path touch: \/ltmain.sh: Permission denied Use of chdir('') or chdir(undef) as chdir() is deprecated at \/usr\/local\/bin\/autoreconf\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":470,"url":"https:\/\/www.gubatron.com\/blog\/how-to-build-pyqt4-for-windows\/","url_meta":{"origin":3383,"position":2},"title":"How to build PyQt4 for Windows","author":"gubatron","date":"February 23, 2007","format":false,"excerpt":"- Make sure you don't have cygwin or C:devkitPromsysbin in your path, or else your make files can end up trying to run the Makefile using 'sh' and all the makefile we're about to use are meant to run from the windows command line. If for some odd reason you\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3241,"url":"https:\/\/www.gubatron.com\/blog\/setting-up-eclipse-as-your-ide-for-bitcoin-c-development-on-macosx\/","url_meta":{"origin":3383,"position":3},"title":"Setting up Eclipse as your IDE for Bitcoin C++ development on MacOSX.","author":"gubatron","date":"February 9, 2014","format":false,"excerpt":"If you are a Java developer used to the productivity levels achieved by working with eclipse's code navigation, code completion and refactoring tools, it's worth your time staying in eclipse for any sort of C++ development. This post refers specifically to getting your eclipse environment to work with a particular\u2026","rel":"","context":"In &quot;BitCoin&quot;","block_context":{"text":"BitCoin","link":"https:\/\/www.gubatron.com\/blog\/category\/bitcoin-2\/"},"img":{"alt_text":"Screen Shot 2014-02-09 at 1.09.39 PM","src":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2014\/02\/Screen-Shot-2014-02-09-at-1.09.39-PM.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2014\/02\/Screen-Shot-2014-02-09-at-1.09.39-PM.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2014\/02\/Screen-Shot-2014-02-09-at-1.09.39-PM.png?resize=525%2C300 1.5x"},"classes":[]},{"id":3236,"url":"https:\/\/www.gubatron.com\/blog\/how-to-actually-build-bitcoin-on-mac-osx-10-9-1\/","url_meta":{"origin":3383,"position":4},"title":"How to actually build bitcoin on Mac OSX 10.9.1","author":"gubatron","date":"February 3, 2014","format":false,"excerpt":"First of all, if you have Macports, do yourself a favor and get rid of it. Then make sure you have Homebrew installed and all the packages installed by it up to date. 1. Let's install all the dependencies for Bitcoin hacking. brew install autoconf automake berkeley-db4 boost miniupnpc openssl\u2026","rel":"","context":"In &quot;BitCoin&quot;","block_context":{"text":"BitCoin","link":"https:\/\/www.gubatron.com\/blog\/category\/bitcoin-2\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4135,"url":"https:\/\/www.gubatron.com\/blog\/the-curious-case-of-inconsistent-cargo-fmt-formatting-and-how-to-fix-it\/","url_meta":{"origin":3383,"position":5},"title":"The Curious Case of Inconsistent cargo fmt Formatting (and How to Fix It)","author":"gubatron","date":"February 17, 2025","format":false,"excerpt":"Have you ever run into a situation where\u00a0cargo fmt, Rust's code formatter, produces different output on different machines, even though you're working on the same project? This can be incredibly frustrating, especially when you're trying to maintain consistent code style across a team or between your own development environments. I\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2025\/02\/gubatron_Abstract_digital_art_fragmented_code_snippets_floati_e3f2c486-78ad-4b2a-b86a-e792a1970064_2.png?fit=1024%2C1024&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2025\/02\/gubatron_Abstract_digital_art_fragmented_code_snippets_floati_e3f2c486-78ad-4b2a-b86a-e792a1970064_2.png?fit=1024%2C1024&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2025\/02\/gubatron_Abstract_digital_art_fragmented_code_snippets_floati_e3f2c486-78ad-4b2a-b86a-e792a1970064_2.png?fit=1024%2C1024&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2025\/02\/gubatron_Abstract_digital_art_fragmented_code_snippets_floati_e3f2c486-78ad-4b2a-b86a-e792a1970064_2.png?fit=1024%2C1024&ssl=1&resize=700%2C400 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/3383","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/comments?post=3383"}],"version-history":[{"count":2,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/3383\/revisions"}],"predecessor-version":[{"id":3410,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/3383\/revisions\/3410"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/media\/3409"}],"wp:attachment":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/media?parent=3383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/categories?post=3383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/tags?post=3383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}