Video summary
Learn to program with c - Part 18 - Libraries
Main summary
Key takeaways
Main ideas / concepts covered
-
What a library is (C context)
- A library is a packaged collection of functions, structures, and other code intended to be reused.
- You create libraries to:
- Maintain shared code separately (e.g., math utilities).
- Avoid recompiling the same code for every program build.
- Potentially improve portability (static) or reduce duplication/bloat (dynamic).
-
Two primary library types
-
Static library (archive)
- File type: typically
*.a(ends with a for “archive”). - Built using the
artool. - Behavior when linked:
- The referenced functions are copied into the final executable.
- The executable becomes larger.
- Portability advantage:
- The program can run without requiring that external shared library at runtime (as long as architecture matches).
- Re: performance:
- Any speedup is said to be negligible; the main benefit emphasized is portability and bundling.
- File type: typically
-
Dynamic/shared library
- File type: typically
*.so(shared object). - Not copied into the executable.
- Behavior when linked/running:
- The executable contains references and at runtime loads the library code into memory.
- Advantages:
- Many programs can share one copy of the library on disk and in memory.
- Library updates may avoid recompiling every dependent program if function prototypes don’t change.
- Tradeoff:
- Can create dependency/version problems (“dependency hell”).
- Key requirement:
- To build a shared library, objects typically must be relocatable (commonly compiled with
-fPIC).
- To build a shared library, objects typically must be relocatable (commonly compiled with
- File type: typically
-
Methodology / instruction-like steps (as shown in the video)
A) Creating and using a static library (libwacky.a)
-
Create header file
wacky math.h- Declare a function (example):
wacky_add(int a, int b)(named with a uniquewackyprefix to avoid symbol name clashes at link time)
-
Create implementation file
wacky math.c- Implement:
wacky_add(int a, int b)returninga + b + (rand() % 10)
- Include needed headers:
stdlib.hforrand()(and mentionrand()is pseudo-random, dependent on a seed)
-
Create a program that uses the library
wacky do.c(program name used in the video)- Include:
stdlib.h(for seeding the RNG)wacky math.h
- Use:
srand(0)to make output deterministic across runs/builds- Call
wacky_add(3, 4)multiple times and print results
-
Makefile targets / build rules
- Build the object and archive:
- Compile
wacky math.ofromwacky math.c - Create the archive using
ar:ar rcsv libwacky.a wacky math.or: insert/replace objectsc: create archives: (implicitly discussed) maintain symbol tablev: verbose
- Compile
- Link the executable:
- Example dependency: executable depends on
libwacky.a - Link step uses:
-L <dir>to tell the compiler/linker where to search libraries-l wackyto linklibwacky.a(prefixliband suffix.aare assumed)
- Example dependency: executable depends on
- Build the object and archive:
-
Verify archive contents
- Use
arto list what’s inside the archive - Use
nmto inspect symbols inside:- Shows
wacky_add(and notes undefined/defined symbol markers)
- Shows
- Use
nmon the executable to confirm:- For static linking,
wacky_addappears as defined inside the executable.
- For static linking,
- Use
B) Creating and using a dynamic/shared library (libwacky.so)
- Reuse the same library source (
wacky math.c, header) -
Change the build to produce a shared object
- Create a target for
libwacky.so(namedlib wacky dooin the subtitles) - Important fix when building shared libraries:
- The build may fail with a relocation error unless code is position-independent
- Recompile the object with:
-fPIC
- Build shared library from PIC object(s)
- Create a target for
-
Key steps emphasized
- Compile
wacky math.owith-fPIC:- so it can be relocated at runtime
- Link the executable against the shared library:
- Ensure the order of arguments matters:
- Library flags (e.g.,
-l...) must typically come after the source/object files that need them
- Library flags (e.g.,
- Ensure the order of arguments matters:
- Run-time library discovery:
- Executable must know where to find the
.so - Methods shown:
- Use
LD_LIBRARY_PATH=.(set to current directory) - Or use
ldconfigto add directories to the system shared library cache
- Use
- Warning noted:
- Misuse of
ldconfigcan break other programs if the cache becomes inconsistent/unreliable.
- Misuse of
- Executable must know where to find the
- Compile
-
Verification differences
- Use
nm:- For dynamic linking,
wacky_addis undefined in the executable (resolved via the.soat runtime) wacky_addis defined inside the shared library.
- For dynamic linking,
- Use
C) Linking to an existing external library (SDL example)
-
Example app behavior
- SDL (“Simple DirectMedia Layer”) program:
- Initialize SDL
- Create surfaces
- Load a bitmap image (mushroom picture)
- Blit (draw) it to a screen surface
- Update/flip buffers
- Wait, then free resources and quit
- SDL (“Simple DirectMedia Layer”) program:
-
Build instructions shown
- Add makefile target
sdl exampledepending onsdl example.c - Compiler flags:
-I <include-dir>(to find headers, e.g., whereSDL/SDL.hlives)
- Linker flags:
-L <lib-dir>and-lSDL(so it links againstlibSDL.soorlibSDL.a)
- SDL header/library locations may require installing “dev” packages.
- Add makefile target
-
Tool-assisted method
- Use
sdl-config(example of common*-configtools) to get:--cflags(compile-time include flags / defines)--libsor--static-libs(linker flags)
- Video notes:
sdl-config --libsoutput may include additional libraries (e.g.,-lpthread) that you should include for correctness.
- Use
Main lessons / “gotchas” highlighted
-
Static vs dynamic consequences
- Static: code copied into executable → larger executable, fewer runtime dependencies.
- Dynamic: code loaded at runtime from
.so→ smaller executable, but requires runtime library resolution.
-
Linker argument order matters
- Undefined reference errors can happen if the library appears before the objects/sources it should satisfy.
-
Shared library build requires PIC
- Use
-fPICwhen building objects that will go into shared libraries.
- Use
-
Runtime search paths for
.so- Either set
LD_LIBRARY_PATHor useldconfig/system cache mechanisms.
- Either set
-
External libraries require both headers and linkable binaries
- Use
-Ifor header locations and-L/-lfor libraries.
- Use
Speakers / sources featured
- Primary speaker: Unnamed presenter/instructor (voice-over; “hi there…” and teaching narration)
- Tools/utility sources referenced:
gcc/clangtoolchain,ar,nm,ldconfig, environment variableLD_LIBRARY_PATH,sdl-config(SDL configuration tool) - External library source referenced: SDL (“Simple DirectMedia Layer”)