Skip to content

Instantly share code, notes, and snippets.

@jamesyang124
Last active May 6, 2017 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesyang124/486cbffea8096798a93366992985558f to your computer and use it in GitHub Desktop.
Save jamesyang124/486cbffea8096798a93366992985558f to your computer and use it in GitHub Desktop.
Review of C Makefile and compile process.

Compile & Linking

  1. C compile source file then link object files and include libs to an executable prorgram.
  2. Linking phase is runned by ld.exe another program, or as.exe as assembly program.
  3. To compile and link a program as a shared library(.dll in windows, .so in Unixes), use -shared.
  4. By default compile will inlcude default dependencies, cpp -v to check the list.
g++ -Wall -g -o Hello.exe Hello.cpp

# compile and link seperately
g++ -c -Wall -g Hello.cpp
g++ -g -o Hello.exe Hello.o

For example, below is some part of nginx 1.12.0 makefile:

CC =	cc
CFLAGS =  -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g
CPP =	cc -E
LINK =	$(CC)

ALL_INCS = -I src/core \
	-I src/event \
	-I src/event/modules #...

binary:	objs/nginx

build:	binary modules manpage

objs/nginx:	objs/src/core/nginx.o \
			objs/src/core/ngx_log.o \
			objs/src/core/ngx_palloc.o \
			objs/src/core/ngx_array.o #...
            
$(LINK) -o objs/nginx \
	objs/src/core/nginx.o \
    objs/src/core/ngx_log.o \
	objs/src/core/ngx_palloc.o \
    # ...
    objs/ngx_modules.o \
    # include library files
	-ldl -lpthread -lcrypt -lpcre -lcrypto -lz \
	-Wl,-E
  1. Compile phase needs to include header files from any #include <lib.h> in source code.
  2. Linking phase require to include the source code of that lib, or, include library by -l in Unixes.

When compiling the program, the compiler needs the header files to compile the source codes; the linker needs the libraries to resolve external references from other object files or libraries. The compiler and linker will not find the headers/libraries unless you set the appropriate options, which is not obvious for first-time user.

The include-paths are specified via -Idir option (or environment variable CPATH).

The linker searches the so-called library-paths for libraries needed to link the program into an executable. The library-path is specified via -Ldir option.

In Unixes, the library libxxx.a is specified via -lxxx option (lowercase letter l, without the prefix lib and .a extension). In Windows, provide the full name such as -lxxx.lib. The linker needs to know both the directories as well as the library names.

In Centos7, you can check defauly lib by pkg-config --list-all.

Static Library vs Shared Library

A library is a collection of pre-compiled object files that can be linked into your programs via the linker. ex: sqrt, printf.

There are two types of external libraries: static library and shared library. A static library has file extension of .a (archive file) in Unixes or .lib (library) in Windows. When your program is linked against a static library, the machine code of external functions used in your program is copied into the executable. A static library can be created via the archive program ar.exe.

A shared library has file extension of .so (shared objects) in Unixes or .dll (dynamic link library) in Windows. When your program is linked against a shared library, only a small table is created in the executable.

Before the executable starts running, the operating system loads the machine code needed for the external functions - a process known as dynamic linking.

Dynamic linking makes executable files smaller and saves disk space, because one copy of a library can be shared between multiple programs. Furthermore, most operating systems allows one copy of a shared library in memory to be used by all running programs, thus, saving memory. The shared library codes can be upgraded without the need to recompile your program.

This means the shared library required the linker to know both the directories as well as the library names. So you need supply -llib to let operating system resolve it.

Reference

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment