1,工具gcc:编译C文件
1.1. 无选项编译链接
用法:#gcc test.c作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。
1.2. 选项 -o
用法:#gcc test.c -o test作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。
1.3. 选项 -E
用法:#gcc -E test.c -o test.i作用:将test.c预处理输出test.i文件。
1.4. 选项 -S
用法:#gcc -S test.i作用:将预处理输出文件test.i汇编成test.s文件。
1.5. 选项 -c
用法:#gcc -c test.s作用:将汇编输出文件test.s编译输出test.o文件。
1.6. 无选项链接
用法:#gcc test.o -o test作用:将编译输出文件test.o链接成最终可执行文件test。
1.7. 选项-O
用法:#gcc -O1 test.c -o test作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。
1.8. 选项-Dmacro
用法:#gcc -DTEST_CONFIGURATION test.c -o test
作用:打开宏TEST_CONFIGURATION
1.9. 选项-Umacro
用法:#gcc -UTEST_CONFIGURATION test.c -o test
作用:关闭宏TEST_CONFIGURATION
1.10. 选项-Wall
用法:#gcc -Wall test.c -o test
作用:打开警告信息
1.11 单文件编译
$gcc -c hello.c #只编译不链接,生成hello.o
$gcc -o hello hello.o #输出可执行文件hello
1.12 多文件编译
$gcc -c thanks.c thanks2.c #thanks.c调用了thanks2.c定义的函数
$gcc -o thanks thanks.o thanks2.o #最终文件thanks
$./thanks
1.13 指定头文件和lib库参数
$gcc sin.c -lm -L/lib -L/usr/lib -I/usr/include # 还是会有警告,估计是因为libm.so是标准函数库
# l表示library,加入某函数库;m表示libm.so函数库,lib与扩展名(.a或.so)不需要写
# L/path表示library的搜索路径,Linux默认library搜索路径为/lib和/usr/lib
# I/path表示include的搜索路径,Linux默认include搜索路径为/usr/include
举例说明:
例:
gcc -o hello hello.c -I/home/hello/include -L/home/hello/lib -lworld
上面这句表示在编译hello.c时:
-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
-L /home/hello/lib表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib
-lworld表示在上面的lib的路径中寻找libworld.so动态库文件(如果gcc编译选项中加入了“-static”表示寻找libworld.a静态库文件)
或者如我编译的:
gcc -I/usr/include/mysql connect.c -L/usr/lib/mysql -lmysqlclient -lz -o connect
-lz表示链接压缩库
2,makefile基本写法
2.1 目标单文件示例
simple_write : simple_write.o
gcc -o simple_write simple_write.o
simple_write.o : simple_write.c
gcc -c simple_write.c
clean :
rm -rf *.o
do :
./simple_write
2.2 通用模板
文件Makefile
include ./xxx.mk
#变量定义
TBUS_TEST_CFILE=$(wildcard *.c)
TBUS_TEST_OBJ=$(TBUS_TEST_CFILE:.c=.o)
TEST_TOOL=test
.PHONY:all clean
all: $(TEST_TOOL)
$(TEST_TOOL): $(TBUS_TEST_OBJ)
$(CC) $^ $(LDPATH) ${LIBS} -o $@
%.o: %.c
$(CC) -c $< $(CFLAGS) ${CINC} -o $@
clean:
$(RM) core* *.o
$(RM) $(TEST_TOOL)
文件xxx.mk
#--------------work directories----------------------
XXX_HOME=/usr/local/XXX-2.5.2.28879_X86_64_Release
XXX_INC = $(XXX_HOME)/include
XXX_SERVICES = $(XXX_HOME)/services
XXX_SERVICESRC = $(XXX_HOME)/services_src
XXX_UNITTESTS = $(XXX_HOME)/unittests
XXX_UNITTESTSRC = $(XXX_HOME)/unittests_src
XXX_DEPS = $(XXX_HOME)/deps
XXX_LIB = $(XXX_HOME)/lib
XXX_LIBSRC = $(XXX_HOME)/lib_src
XXX_TOOLS = $(XXX_HOME)/tools
XXX_TOOLSRC = $(XXX_HOME)/tools_src
XXX_PACKLIBDIR = $(XXX_LIBSRC)/tmp
XXX_UNITTEST = $(XXX_HOME)/unittests
XXX_SERVICES = $(XXX_HOME)/services
XXX_APPS_INC=$(XXX_INC)/apps
#----------------libraris --------------------------
#XXX的库目录
LDPATH = -L$(XXX_LIB)/
#LDPATH += -L/usr/lib/ -L/usr/local/lib/ -L./
#XXX的库文件
LIBS = -lXXX
#XXX的include,对外使用CFLAGS
CINC = -I$(XXX_INC)/
CFLAGS= -Wall -g
CXXFLAGS=-Wall
CC = gcc
CXX = g++
RM = /bin/rm -f
2.3 目标多文件示例
.PHONY : main
main : server client
server : server.o
gcc -g -o server server.o
client : client.o
gcc -g -o client client.o
server.o : server.c
gcc -g -c server.c
client.o : client.c
gcc -g -c client.c
clean :
rm -rf *.o
ser :
./server
cli :
./client
3,工具make:执行makefile
1,make是一个程序,它会寻找一个叫Makefile的文件,根据这个文件执行相关的编译操作(需要相关的编译工具如gcc)。
2,那么Makefile是怎么来的?通常软件开发商会写一个叫configure的检测程序,去检测用户的操作环境,根据操作环境生成相应的编译规则,并把它们保存在Makefile文件中。特别的,configure检测程序会检测是否有相应的编译工具(如gcc)、是否有依赖的函数库或软件、是否适合当前的操作系统等等,如果发现不妥,并不会产生相应的Makefile文件。
3.1 C文件makefile示例
3.1.1 最基本makefile
3个头文件,8个c文件:
注意1:文件名:Makefile或makefile,如果要指定特定的Makefile,你可以使用make的“-f”和“--file”参数,如:make -f Make.Linux或make --file Make.AIX。
注意2:命令一定要以Tab键开始
edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o
3.1.2 改进版1:使用变量
objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
3.1.3 改进版2:Makefile自动推导
自动推导:只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中:如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来。