Library Creation and Linking Basics
Consider a C++ project with the following structure:
add.h
int compute_sum(int x, int y);
add.cpp
#include "add.h"
int compute_sum(int x, int y)
{
return x + y;
}
main.cpp
#include <iostream>
#include "add.h"
int main()
{
std::cout << compute_sum(1, 2) << std::endl;
return 0;
}
Static Library Creation and Linking
Makefile for static library generation:
compiler_flags := -g -O3 -std=c++11 -I ./
linker_flags := -l mathlib -L ./
add.o : add.cpp
@g++ -c $^ -o $@ $(compiler_flags)
libmathlib.a : add.o
@ar -rcs $@ $^
static_target : libmathlib.a
main.o : main.cpp
@g++ -c $^ -o $@ $(compiler_flags)
app_static : main.o
@g++ $^ -o $@ $(linker_flags)
all_static : static_target app_static
clean :
@rm -rf *.o *.a *.so app_static
Execute make all_static to generate libmathlib.a and app_static. Verify dependencies with ldd app_static:
linux-vdso.so.1 (0x00007ffe567f1000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8d3a8c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8d3a6ce000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8d3a57f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8d3aadc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8d3a564000)
Shared Library Creation and Linking
Makefile for shared library generation:
compiler_flags := -g -O3 -w -fPIC -I ./
linker_flags := -l mathlib -L ./ -Wl,-rpath=./
add.o : add.cpp
@g++ -c $^ -o $@ $(compiler_flags)
libmathlib.so : add.o
@g++ -shared $^ -o $@
dynamic_target : libmathlib.so
main.o : main.cpp
@g++ -c $^ -o $@ $(compiler_flags)
app_dynamic : main.o
@g++ $^ -o $@ $(linker_flags)
all_dynamic : dynamic_target app_dynamic
clean :
@rm -rf *.o *.a *.so app_dynamic
Execute make all_dynamic to generate libmathlib.so and app_dynamic. Check dependencies with ldd app_dynamic:
linux-vdso.so.1 (0x00007ffc25df8000)
libmathlib.so => ./libmathlib.so (0x00007f4b2a42e000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4b2a219000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4b2a027000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4b29ed8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4b2a432000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4b29ebd000)
Multi-Directory Project Structure
Extended project structure with subdirectories:
subtract.h
int compute_difference(int x, int y);
subtract.cpp
#include "subtract.h"
int compute_difference(int x, int y)
{
return x - y;
}
main.cpp
#include <iostream>
#include "add.h"
#include "subtract.h"
int main()
{
std::cout << compute_sum(1, 2) << std::endl;
std::cout << compute_difference(1, 2) << std::endl;
return 0;
}
Static Library with Subdirectories
Makefile using object files directly:
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -std=c++11 -I ./include
linker_flags := -l corelib -L ./
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.a : $(lib_objects)
ar -rcs $@ $^
static_lib : libcorelib.a
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o $(lib_objects)
g++ $^ -o $@
all_static : static_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Alternative Makefile linking against static library:
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -std=c++11 -I ./include
linker_flags := -l corelib -L ./
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.a : $(lib_objects)
ar -rcs $@ $^
static_lib : libcorelib.a
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o
g++ $^ -o $@ $(linker_flags)
all_static : static_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Shared Library with Subdirectories
Makefile using object files directly:
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -w -fPIC -I ./include
linker_flags := -l corelib -L ./ -Wl,-rpath=./
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.so : $(lib_objects)
g++ -shared $^ -o $@
dynamic_lib : libcorelib.so
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o $(lib_objects)
g++ $^ -o $@
all_dynamic : dynamic_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Alternative Makefile linking against shared library:
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -w -fPIC -I ./include
linker_flags := -l corelib -L ./ -Wl,-rpath=./
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.so : $(lib_objects)
g++ -shared $^ -o $@
dynamic_lib : libcorelib.so
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o
g++ $^ -o $@ $(linker_flags)
all_dynamic : dynamic_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Advanced Library Combinations
Building Static Library and Linking External Static Library
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -std=c++11 -I ./include
linker_flags := -l corelib -L ./ -l mathlib -L ./lib
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.a : $(lib_objects)
ar -rcs $@ $^
static_lib : libcorelib.a
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o
g++ $^ -o $@ $(linker_flags)
all_static : static_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Building Shared Library and Linking External Static Library
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -w -fPIC -I ./include
linker_flags := -l mathlib -L lib -l corelib -L ./ -Wl,-rpath=./
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.so : $(lib_objects)
g++ -shared $^ -o $@
dynamic_lib : libcorelib.so
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o
g++ $^ -o $@ $(linker_flags)
all_dynamic : dynamic_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Building Shared Library and Linking External Shared Library
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -std=c++11 -I ./include
linker_flags := -l corelib -L ./ -l mathlib -L ./lib
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
libcorelib.so : $(lib_objects)
g++ -shared $^ -o $@
dynamic_lib : libcorelib.so
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o
g++ $^ -o $@ $(linker_flags)
all_dynamic : dynamic_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Dependency check with ldd app_main shows:
linux-vdso.so.1 (0x00007ffd8a3f2000)
libcorelib.so => ./libcorelib.so (0x00007f1b4c839000)
libmathlib.so => ./libmathlib.so (0x00007f1b4c834000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1b4c61f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1b4c42d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1b4c2de000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1b4c845000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1b4c2c3000)
Merging Static Libraries
Extract objects from existing static library and combine:
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -std=c++11 -I ./include
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
ar -x lib/libmathlib.a
libcorelib.a : $(lib_objects) add.o
ar -rcs $@ $^
static_lib : libcorelib.a
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o libcorelib.a
g++ $^ -o $@
all_static : static_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Creating Shared Library from Static Library Components
lib_sources := $(shell find ./src -name "*.cpp")
lib_objects := $(lib_sources:.cpp=.o)
compiler_flags := -g -O3 -w -fPIC -I ./include
linker_flags := -l corelib -L ./ -Wl,-rpath=./
src/%.o : src/%.cpp
g++ -c $^ -o $@ $(compiler_flags)
ar -x lib/libmathlib.a
libcorelib.so : $(lib_objects) add.o
g++ -shared $^ -o $@
dynamic_lib : libcorelib.so
main.o : main.cpp
g++ -c $^ -o $@ $(compiler_flags)
app_main : main.o
g++ $^ -o $@ $(linker_flags)
all_dynamic : dynamic_lib app_main
clean :
rm -rf *.o src/*.o *.a *.so app_main
Note: Linux systems do not support embedding shared libraries within other shared or static libraries.