C語言專案編譯
阿新 • • 發佈:2021-06-21
在《linux-Unix系統程式設計》一書中,發現作者的原始碼編譯寫的非常高明。雖然尚不能完全理解,順手牽過來分享給大家。
一、專案結構
首先,專案的目錄結構如下,lib是共享的原始檔,fileio是一個模組,fileio的原始檔會依賴到lib中的檔案,這也是一般專案的結構
. ├── fileio │ ├── main │ ├── main2 │ ├── main2.c │ ├── main.c │ └── makefile ├── lib │ ├── Build_ename.sh │ ├── function.c │ ├── function.h │ └── Makefile ├── Makefile └── Makefile.inc
二、一級目錄的Makefile
一級目錄的Makefile是make命令的配置檔案,大概是按順序將所有二級目錄進行構建,這裡的lib一定要在fileio之前
DIRS = lib fileio all: for i in $(DIRS); do \ (cd $$i && echo "making $$i" && $(MAKE) ) || exit 1; \ done allgen: for dir in ${DIRS}; do (cd $${dir}; ${MAKE} allgen) ; doneclean: for i in $(DIRS); do \ (cd $$i && echo "cleaning $$i" && $(MAKE) clean) || exit 1; \ done
一級目錄的Makefile.inc是二級目錄的Makefile都要引用到的
TLPI_DIR = .. TLPI_LIB = ${TLPI_DIR}/libtlpi.a TLPI_INCL_DIR = ${TLPI_DIR}/lib LINUX_LIBRT = -lrt LINUX_LIBDL = -ldl LINUX_LIBACL= -lacl LINUX_LIBCRYPT = -lcrypt LINUX_LIBCAP = -lcap IMPL_CFLAGS = -std=c99 -D_XOPEN_SOURCE=600 \ -D_DEFAULT_SOURCE \ -g -I${TLPI_INCL_DIR} \ -pedantic \ -Wall \ -W \ -Wmissing-prototypes \ -Wno-sign-compare \ -Wno-unused-parameter CFLAGS = ${IMPL_CFLAGS} IMPL_THREAD_FLAGS = -pthread IMPL_LDLIBS = ${TLPI_LIB} -lm LDLIBS = ${IMPL_LDLIBS} RM = rm -f
三、lib下的Makefile
裡面引用了當前目錄的一個shell指令碼Build_ename.sh,我貼在後面
include ../Makefile.inc allgen : ${TLPI_LIB} ${TLPI_LIB} : *.c ename.c.inc ${CC} -c -g ${CFLAGS} *.c ${RM} ${TLPI_LIB} ${AR} rs ${TLPI_LIB} *.o ename.c.inc : sh Build_ename.sh > ename.c.inc echo 1>&2 "ename.c.inc built" clean : ${RM} *.o ename.c.inc ${TLPI_LIB}
Build_ename.sh
#!/bin/sh echo '#include <errno.h>' | cpp -dM | sed -n -e '/#define *E/s/#define *//p' |sort -k2n | awk ' BEGIN { entries_per_line = 4 line_len = 68; last = 0; varname =" enames"; print "static char *ename[] = {"; line = " /* 0 */ \"\""; } { if ($2 ~ /^E[A-Z0-9]*$/) { # These entries are sorted at top synonym[$1] = $2; } else { while (last + 1 < $2) { last++; line = line ", "; if (length(line ename) > line_len || last == 1) { print line; line = " /* " last " */ "; line = sprintf(" /* %3d */ ", last); } line = line "\"" "\"" ; } last = $2; ename = $1; for (k in synonym) if (synonym[k] == $1) ename = ename "/" k; line = line ", "; if (length(line ename) > line_len || last == 1) { print line; line = " /* " last " */ "; line = sprintf(" /* %3d */ ", last);; } line = line "\"" ename "\"" ; } } END { print line; print "};" print ""; print "#define MAX_ENAME " last; } '
四、fileio中的makefile
include ../Makefile.inc GEN_EXE = main main2 LINUX_EXE = EXE = ${GEN_EXE} ${LINUX_EXE} all : ${EXE} allgen : ${GEN_EXE} clean : ${RM} ${EXE} *.o showall : @ echo ${EXE} ${EXE} : ${TLPI_LIB}
其中fileio/main.c,lib/function.h lib/function.c程式碼都在上一篇文章中,這裡就不貼了