天天看点

gcc与Makefile使用实例

有文件夹src放下面文件

hello_1.c hello.c main.c

有文件夹include放下面文件

hello_1.h hello.h

脚本如下:

1 NAME=   main
  2 DIR_INC=./include
  3 DIR_SRC=./src
  4 DIR_OBJ=./obj
  5 DIR_BIN=./bin
  6
  7 INCLUDE=-I$(DIR_INC)
  8 TARGET=$(DIR_BIN)/$(NAME)
  9
 10 SRC=$(wildcard ${DIR_SRC}/*.c)
 11 OBJS=$(SRC:$(DIR_SRC)/%.c=$(DIR_OBJ)/%.o)
 12
 13 $(TARGET):$(OBJS)
 14         @echo 'depend file "$^" ...'
 15         gcc -o $(TARGET) $(OBJS)
 16 $(DIR_OBJ)/%.o:${DIR_SRC}/%.c
 17         @echo 'compiling object file "[email protected]" ...'
 18         gcc -c -o [email protected] $<
 19 clean:
 20         rm -fr $(OBJS) $(TARGET);
           

上面代码可以直接运行,其基本原理:

( T A R G E T ) : (TARGET): (TARGET):(OBJS)依赖所有.o文件,并且生成目标执行文件$(TARGET)

( D I R O B J ) / (DIR_OBJ)/%.o: (DIRO​BJ)/{DIR_SRC}/%.c 所有.o文件依赖于对应的.c文件,并且生成对应的.o文件。

  • Makefile的规则

target … : prerequisites …

command//记住此处必须使用tab,不能使用空格

  • gcc

gcc -o hello hello.c -I /home/hello/include-L /home/hello/lib –lworld

I目录作为第一个寻找头文件的目录,

L表示将/home/hello/lib目录作为第一个寻找库文件的目录,

gcc -lm 的选项,C代码调用math.h中的函数有问题,如sqrt函数。若如sqrt(3.0)则可以编译通过并运行正常,若如sqrt(n),这里n是定义好的double型变量,则不能编译通过,错误信息为:undefined reference to ‘sqrt’。

-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找.

-o 输出可执行文件

-c 编译生成目标文件

-g 输出调试信息

-O2 编译器优化级别 1-3

-Wall 警告选项 输出警告信息

-l 紧接着链接库 lpthread

-L 指定链接库的路径

-I 头文件路径

-shared 编译成动态链接库

注意-c只是生成目标文件,而-o直接回生成可执行文件

.c.o:

这句话的意思就是 %.o : %.c

也就是说,所有的.o文件,依赖于对应的.c文件

src=$(wildcard .c ./sub/.c)

dir=$(notdir $(src))

obj= ( p a t s u b s t (patsubst %.c,%.o, (patsubst(dir) )

wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。

notdir把展开的文件去除掉路径信息

patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o

符号意义:

$(Files),取File变量的值。

[email protected] 目标文件

$^ 全部依赖

$< 第一个依赖

$? 第一个变化的依赖

下面放一个g++编译的通用脚本:

NAME=   cache
DIR_INC=./include
DIR_SRC=./src
DIR_OBJ=./output/obj
DIR_BIN=./output/bin

#CC      = gcc
CC      = g++

## debug flag
DBG_ENABLE   = 0


INCLUDE=-I$(DIR_INC)


## debug for debug info, when use gdb to debug
ifeq (1, ${DBG_ENABLE})
CFLAGS += -D_DEBUG -O0 -g -DDEBUG=1
endif

## get all include path
CFLAGS  += $(foreach dir, $(DIR_INC), -I$(dir))
CFLAGS += -std=c++11


TARGET=$(DIR_BIN)/$(NAME)

#SRC         =  $(wildcard ${DIR_SRC}/*.c)
SRC         += $(wildcard $(DIR_SRC)/*.cpp)


#OBJS        = $(SRC:$(DIR_SRC)/%.c=$(DIR_OBJ)/%.o)
OBJS        +=$(SRC:$(DIR_SRC)/%.cpp=$(DIR_OBJ)/%.o)

$(TARGET):$(OBJS)
        @echo 'depend file "$^" ...'
        $(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
$(DIR_OBJ)/%.o:${DIR_SRC}/%.cpp
        @echo 'compiling object file "[email protected]" ...'
        $(CC) $(CFLAGS) -c -o [email protected] $<
clean:
        rm -fr $(OBJS) $(TARGET);
        rm -fr $(DIR_OBJ)/* $(DIR_BIN)/*;

test:
        @echo $(SRC)
        @echo $(OBJS)