# Things to remember when compiling/linking C/C++ software 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 you need. In Windows, `cl.exe` takes include paths with the following syntax: `/I"c:\path\to\includes\` you can also pass as many as you need. Some software uses macro definition variables that should be passed during compile time to decide what code to include. ## Compilation flags These compilation-time variables are passed using `-D`, e.g. `-DMYSOFTWARE_COMPILATION_VARIABLE` `-DDO_SOMETHING=1` `DDISABLE_DEPRECATED_FUNCTIONS=0` These compilation time flags are by convention usually put into a single variable named `CXXFLAGS`, which is then passed to the compiler as a parameter for convenience when you're building your compilation/make script. ## Object files When you compile your .c, or .cpp files, you will end up with object files. These files usually have `.o` extensions in Linux, in Windows they might be under `.obj` extensions. You can create an `.o` file for a single or for many source files. ## Static Library files When you have several `.o` files, you can put them together as a library, a static library. In Linux/Mac these static libraries are simply archive files, or `.a` files. In windows, static library files exist under the `.lib` extension. **They are created like this in Linux/Mac:** `ar -cvq libctest.a ctest1.o ctest2.o ctest3.o` `libctest.a` will contain `ctest1.o`,`ctest2.o` and `ctest2.o` **They are created like this in Windows:** `LIB.EXE /OUT:MYLIB.LIB FILE1.OBJ FILE2.OBJ FILE3.OBJ` 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's easier to distribute, but again, the size of the executable can be bigger than it needs to... why? because, sometimes, many of the `.o` files, or even the entire `.a` file you're linking against might be a standard library that many other programs need. ## Shared Libraries (Dynamic Libraries) So ***shared*** or ***dynamic*** libraries were invented so that programs would be linked against them, but since they're "shared" they don't need to be part of the executable, your executable will look for symbols expected to exist on a library that will be loaded in a single portion of the operating system's memory, thus not just making the size of your executable as small as it needs to be, but you won't need to load the library for every process/program that needs its symbols. On Linux shared files exist under the `.so` (shared object) file extension, on Mac `.dylib` (dynamic library), and in Windows they're called `.dll` (dynamic link libraries) 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. In Linux `.so` files are created like this: ``` gcc -Wall -fPIC -c *.c gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o ``` `-fPIC` means "Position Independent Code", a requirement for shared libraries in Linux. `-shared` makes the object file created shareable by different executables. In Mac `.dylib` files are created like this: `clang -dynamiclib -o libtest.dylib file1.o file2.o -L/some/other/libraries/to/link/live/here -lname_of_library_without_lib_prefix` In Windows `.dll` files are created like this: `LINK.EXE /DLL /OUT:MYLIB.DLL FILE1.OBJ FILE2.OBJ FILE3OBJ` ## Linking to existing libraries