组织多目录的 Makefile 和一些小问题

简单的程序,用一些标准的 Makefile 就可以解决所有问题。

一般过于复杂的系统,可以使用 autoconf 和 automake 来解决问题。

对于一些不大不小的项目,就需要稍微深入的了解 Makefile,这里有一个对于 Makefile 非常好的说明,(http://www.chinaunix.net/old_jh/23/408225.html),但是个人感觉写的有点多了,可以拿它当一个手册来看。

对于我遇到的项目,其实并不复杂,比最简单的 Makefile 就多做了以下的内容:

  1. 但是由于有多个模块共存,所以将他们放在了不同的目录当中;
  2. 根据不同的操作系统,需要变更一些编译选项;
对于多目录的问题,原来想用 Makefile 嵌套的方式来解决,但是麻烦不少,最重要的是路径问题。

后来发现可以使用 $(MAKE) 这个宏来进行;并且在测试当中,直接使用 SHELL的cd 命令是无法转换工作目录的。

ALL: ${OBJS}
        @$(MAKE) moduleinside
        ${MY_CC} -o  ${EXE} ${OBJS} ${LIB_DIRS} ${LIBS} ${STATIC_LIBS}
        strip ${EXE}

%.o:%.c ${HEADERS}
        ${MY_CC} -g ${INCLUDE_DIRS} -c $< -o $@

moduleinside:
        @list='$(ALL_DIRS)'; for subdir in $$list; do \
         test "$$subdir" = . || (cd $$subdir && $(MAKE)); \
        done

上面的代码很简单,All 标签是给Make的主标签,通过 $(MAKE) 宏来执行运行哪个Makefile文件。$(MAKE) 这个宏,可以理解为相当于打入 make 命令。

所有的模块目录,写入 $(ALL_DIRS) 变量中,然后通过 for 循环取出,然后执行其自己的Makefile文件。

运行完成以后,Make 会自动将工作目录返回当前目录,所以只需要cd出去,而不需要管回来的命令。

对于每个子目录中的 Makefile 就按照标准的 Makefile 完成就可以了。


如果有什么需要设定的变量,要在其他目录中的 Makefile 中继承。

export CC = gcc

可以像上面这样声明一下就可以了。


因为我们的需要在多种系统中进行编译,每个系统一些动态库的挂接可能是不一样的,这样我们需要进行操作系统的处理。

RUN_OS = $(shell uname)         # 当前的系统

ALL: ${OBJS}
        @$(MAKE) moduleinside
ifeq ($(firstword $(RUN_OS)), SunOS)
        ${MY_CC} -o  ${EXE} ${OBJS} ${LIB_DIRS_SUN} ${LIBS_SUN} ${STATIC_LIBS}
else
        ${MY_CC} -o  ${EXE} ${OBJS} ${LIB_DIRS} ${LIBS} ${STATIC_LIBS}
endif
        strip ${EXE}
这里 RUN_OS 变量的获取方式,可以通过 uname 命令的结果拿到当前的执行系统。然后 通过 ifeq 来进行与目标系统的比较。

这里可能会注意到,使用了一个 $(firstword <target>) 的内置函数,为什么使用这个函数呢?

RUN_OS = $(shell uname)         # 当前的系统

RUN_OS = $(shell uname)

可以看到,上面两行内容应该是完全一样的,但是在 Makefile 当中通过上面定义的变量,通过  ifeq 进行结果判断时竟然是不一样的。

原因就是变量命名以后,后面有多余的空格或者TAB或者其他 OOXX。

这样,就需要使用一个 $(firstword <target>) 函数进行处理,当然,你也可以写的时候注意一些,不要在变量命名后面添加任何多余的字符和注释等等内容。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值