Makefile初步使用

1 初步基本知识

1.1 gcc的使用

在Linux 下,gcc 比较常用的一种格式为:

gcc 源文件名 -o 目标文件名

例如源文件名称为main.c。 代码如下:

#include <stdio.h>

int main(int argc, char* argv[])
{
    int i = 0;
    for( i = 0; i < argc; i++)
    {
        printf("Argument %d : %s \n", i, argv[i]);
    }

    return 0;
}

使用gcc编译main.c文件:

gcc main.c -o main

执行之:

./main

注意:
1. 如果使用 gcc main.c 命令会生成 a.out 文件,执行 ./a.out 文件即可。
2. #include <> 表示在默认路径 “usr/include” 中搜索头文件。
3. #include ” ” 表示在本目录下搜索头文件。
4. 在使用gcc编译时要使用到 -l 或者 -L 参数。比如在使用math.h 库时,需要加上 -lm

放在 /lib/usr/lib/usr/local/lib 里面的库直接用 -l 就能够链接了,但是如果库文件没有放在这三个目录中,而是放在其他的目录下,这时候需要使用参数 -L 编译。例如常用的X11的库,它在 /usr/X11R6/lib 目录下,在编译时就要用 -L/usr/X11R6/lib -lX11 参数,-L参数跟着的是库文件所在的目录名。

例如:

把libtest.so 放在/aaa/bbb/ccc 目录下,那么链接参数就是

-L/aaa/bbb/ccc -ltest

1.2 Makefile工程文件

1.2.1 Makefile文件书写规则

target: dependencies
    system command(s)

目标文件:依赖文件

(tab)产生目标文件的命令

注意: 命令要以tab 进行文本缩进。

变量的使用要注意:

  1. 变量名不能够使用 “:”,“#”,“=” 或是空字符(空格、回车等);
  2. 大小写敏感,一般都用大写;
  3. 在声明时需赋储值,使用时要在前面加上“$”符号。

1.2.2 Makefile 文件的编写

makefile 文件的编写在Unix/Linux环境中经常使用的,使用Makefile的好处是可以实现“自动化编译”,编写Makefile文件后,需要一个* make* 命令,就能够方便的编译整个工程了。

对于大型项目而言,makefile中变量就非常重要了。在文件中常用注意有一下几点

(1)用 OBJECTOBJS 来表示最终目标的文件列表

(2)使用预定义变量

$@ —表示当前目标文件的名字。

$^ —表示用空格隔开的所有依赖文件。

$< —表示第一个依赖文件。

(3)让Makefile 自动推导,make命令可以自动推导文件以及文件依赖关系后面的命令,make会自动识别并自己推导命令。只要make查到某个 .o 文件,它就好自动把相关的 .c 加到依赖关系中。例如:如果make找到 whatever.o ,那么 whatever.c 就确定是 whatever.o 的依赖文件。

注意: makefile 文件名称首字母 m 大小写都可以,看工程要求。

例如:

makefile文件形式如下:

main:main.o mytool1.o mytool2.o
    gcc -o main main.o mytool1.o mytool2.o

main.o:main.c mytool1.h mytool2.h
    gcc -c main.c

mytool1.o:mytool1.c mytool1.h
    gcc -c mytool1.c

mytool2.o:mytool2.c mytool2.h
    gcc -c mytool2.c

使用 变量的方式把上述的makefile进行简化,结果如下所示:

main:main.o mytool1.o mytool2.o
    gcc -o $@ $^

main.o:main.c mytool1.h mytool2.h
    gcc -c $<

mytool1.o:mytool1.c mytool1.h
    gcc -c $<

mytool2.o:mytool2.c mytool2.h
    gcc -c $<

使用缺省变量把上述makefile进一步简化,即如果如下:

main:main.o mytool1.o mytool2.o
    gcc -o $@ $^

..c.o:
    gcc -c $<

2 Makefile编写示例

工程源文件示例

新建一个工程 test_makefile ,工程目录结构图下图所示:

/test_makefile
|-build
|-CMakeLists.txt
|-main.c
|-mytool1.h
|-mytool1.c
|-mytool2.h
|-mytool2.c
|-Makefile
|-readme.txt

其中 main.c 代码如下:

//main.c

#include "mytool1.h"
#include "mytool2.h"


int main()
{
    mytool1_print("mytool1 hello!");
    mytool2_print("mytool2 hello!");
    return 0;
}

mytool1.h 代码如下

 /*mytool1.h*/

#ifndef MYTOOL1_H
#define MYTOOL1_H

void mytool1_print(char *print_str);

#endif

mytool1.c 代码如下

 /*mytool1.c*/

#include "mytool1.h"
#include <stdio.h>

void mytool1_print(char *print_str)
{
    printf("this is mytool1 print: %s \n",print_str);
}

mytool2.h 代码如下

 //mytool2.h


#ifndef MYTOOL2_H
#define MYTOOL2_H

void mytool2_print(char *print_str);

#endif

mytool2.c 代码如下

 /*mytool2.c*/

#include "mytool2.h"
#include <stdio.h>

void mytool2_print(char *print_str)
{
    printf("this is mytool2 print: %s \n",print_str);
}

编写makefile文件可以使用一下方式。

注:使用 camke 的方式需要使用 CMakeLists.txt 文件,生成的中间文件一般放在 build 目录中,防止影响源文件目录,其中在使用cmake方式的时候会自动生成 Makefile 文件。

(1)方式一

使用常规方式进行编写,打开Makefile 文件,在里面添加如下:

main:main.o mytool1.o mytool2.o
    gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
    gcc -c main.c
mytool1.o:mytool1.c mytool1.h
    gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
    gcc -c mytool2.c
clean:
    rm -f *.o main

直接在 Makefile 所在的目录中运行 make 命令即可,然后生成 main 文件,使用 ./main 即可执行。

(2)方式二

使用 自定义目标变量 的方式进行编写,把上述的makefile进行简化,简化后如下所示:

OBJ = main.o mytool1.o mytool2.o
make:$(OBJ)
    gcc -o main $(OBJ)
main.o:main.c mytool1.h mytool2.h
    gcc -c main.c
mytool1.o:mytool1.c mytool1.h
    gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
    gcc -c mytool2.c
clean:
    rm -f main $(OBJ)

(3)方式三

使用 make自动推导的 方式进行编写,把上述的makefile进行简化,简化后如下所示:

CC = gcc
OBJ = main.o mytool1.o mytool2.o
make:$(OBJ)
    $(CC) -o main $(OBJ)
main.o:mytool1.h mytool2.h
mytool1.o:mytool1.h
mytool2.o:mytool2.h
.PHONY: clean
clean:
    rm -f main $(OBJ)

(4)方式四

使用变量的方式把上述的makefile进行简化,简化后如下所示:

CC = gcc
OBJ = main.o mytool1.o mytool2.o
main:$(OBJ)
    $(CC) -o $@ $^
main.o:main.c mytool1.h mytool2.h
    gcc -c $<
mytool1.o:mytool1.c mytool1.h
    gcc -c $<
mytool2.o:mytool2.c mytool2.h
    gcc -c $<
.PHONY : clean
clean:
    rm -f main $(OBJ)

(5)方式五

使用函数的方式进行编写,把上述的makefile进行简化,简化后如下所示:

CC = gcc 
CFLAGS = -Wall -c 
LDFLAGS = -lpthread
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
TARGET = main

$(TARGET):$(OBJS)
    $(CC) $(LDFLAGS) -o $@ $^
%.o:%.c
    $(CC) $(CFLAGS) -o $@ $<
.PHONY:clean
clean:
    @rm -f *.o $(TARGET)

(6)方式六(使用cmake方式)

使用cmake方式进行编译工程,打开CMakeLists.txt 文件,在里面添加如下:

cmake_minimum_required(VERSION 2.8)
project(test_proj)
add_compile_options(-std=c++11)
#add_definitions(-std=c++11)

#first way
aux_source_directory(. DIR_SRCS)
add_executable(test ${DIR_SRCS})

#second way
#set(SOURCE_FILES main.c mytool1.c mytool2.c)
#add_executable(test ${SOURCE_FILES})

添加完成后,使用 cd build 进入到 build 目录,
build 目录中,执行如下命令,首先执行 cmake 命令,然后执行 make 命令

 /build$cmake ..

 /build$make 

执行完成后,在 build 目录中会生成 test 文件, 通过 ./test 即可执行。

参考文献(References)

[1]. 刘加海、骆建华. Linux程序设计实践和编程技巧[M].杭州:浙江大学出版社,2013.6.

[2]. Makefile wiki(https://en.wikipedia.org/wiki/Makefile).

[3]. GCC and Make Compiling,Linking and Building C/C++ Applications . http://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html) .

[4]. cmake tutorial.

注:如有错误和不足,欢迎指正。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值