这一篇源代码沿用上一篇的源代码hellomake.c hellofunc.c hellofunc.h makefile

但是代码内容和结构有变化,如下:

  1. .
  2. ├── include
  3.    └── hellofunc.h
  4. ├── makefile
  5. └── src
  6. ├── hellofunc.c
  7. └── hellomake.c

hellomake.c 代码:

  1. #include"../include/hellofunc.h"
  2. #include<stdio.h>
  3. void myPrintHelloMake(void) {
  4.  
  5. printf("Hello makefiles!\n");
  6. return;
  7. }

hellofunc.c代码:

  1. #include"../include/hellofunc.h"
  2. #include<stdio.h>
  3. void myPrintHelloMake(void) {
  4.  
  5. printf("Hello makefiles!\n");
  6. return;
  7. }

hellofunc.h代码:

  1. /*
  2. example include file
  3. */
  4.  
  5. void myPrintHelloMake(void);

makefile 文件代码:

  1. #Hellomake
  2. #Magnum, --
  3. # 指令编译器和选项
  4. CC=gcc
  5. CFLAGS=-Wall
  6. LIBS=-lm
  7. IncludeDir = -I./hellofunc/
  8. LinkDir = -L
  9. OBJ_DIR = ./obj
  10. BIN_DIR = ./bin
  11. PROJECT_TOP_DIR=.#$(shell pwd) #$(shell cd ../; pwd)
  12. PROJECT_BIN_DIR=./bin
  13. PROJECT_SRC_DIR=./src
  14. PROJECT_LIB_DIR=./lib
  15. PROJECT_OBJ_DIR=./objs
  16. MKDIR := mkdir -p
  17.  
  18. # 目标文件
  19. TARGET=$(BIN_DIR)/hellomake
  20.  
  21. src=$(wildcard ./src/*.c)
  22. dir= $(notdir $(src))
  23. PROJECT_OBJ= $(patsubst %.c,%.o,$(dir) )
  24. PROJECT_ALL_OBJS= $(addprefix ./objs/, $(PROJECT_OBJ))
  25.  
  26. $(TARGET): $(PROJECT_ALL_OBJS)
  27. $(CC) -o $@ $^ $(LIBS)
  28.  
  29. .PHONY : clean
  30. clean:
  31. -rm -rf $(TARGET) $(PROJECT_ALL_OBJS)
  32.  
  33. ./objs/%.o:./src/%.c
  34. @if test ! -d $(PROJECT_OBJ_DIR) ; \
  35. then \
  36. mkdir $(PROJECT_OBJ_DIR) ; \
  37. fi
  38.  
  39. @if test ! -d $(PROJECT_BIN_DIR) ; \
  40. then \
  41. mkdir $(PROJECT_BIN_DIR) ; \
  42. fi
  43.  
  44. $(CC) $(CFLAGS) -o $@ -c $<

makefile执行命令的部分记得改为tab而不是空格,否则会报错。

执行make,结果如下:

  1. .
  2. ├── bin
  3.    └── hellomake
  4. ├── include
  5.    └── hellofunc.h
  6. ├── makefile
  7. ├── objs
  8.    ├── hellofunc.o
  9.    └── hellomake.o
  10. └── src
  11. ├── hellofunc.c
  12. └── hellomake.c
  13.  
  14. directories, files

这里面课执行文件放在拉bin文件夹中,而中间.o文件全部放在objs文件夹内。

执行命令"./bin/hellomake"得到:

  1. Hello makefiles!
  2. Value:2.708050

可以发现hellomake.c 和 hellofunc.c 在引入头文件的地方有变化,其他内容还是和之前的一样。

也可以这样修改:

hellomake.c:

  1. //#include "../include/hellofunc.h"
  2. #include<hellofunc.h>
  3. #include<stdio.h>
  4. #include<math.h>
  5. int main() {
  6. // call a function in another file
  7. myPrintHelloMake();
  8. double value =;
  9. printf("Value:%f\n",log(value));
  10. return();
  11. }

hellofunc.c:

  1. //#include"../include/hellofunc.h"
  2. #include<hellofunc.h>
  3. #include<stdio.h>
  4. void myPrintHelloMake(void) {
  5.  
  6. printf("Hello makefiles!\n");
  7. return;
  8. }

makefile:

  1. #Hellomake
  2. #Magnum, --
  3. # 指令编译器和选项
  4. CC=gcc
  5. CFLAGS=-Wall
  6. LIBS=-lm
  7. IncludeDir = -I./include/
  8. LinkDir = -L
  9. OBJ_DIR = ./obj
  10. BIN_DIR = ./bin
  11. PROJECT_TOP_DIR=.#$(shell pwd) #$(shell cd ../; pwd)
  12. PROJECT_BIN_DIR=./bin
  13. PROJECT_SRC_DIR=./src
  14. PROJECT_LIB_DIR=./lib
  15. PROJECT_OBJ_DIR=./objs
  16. MKDIR := mkdir -p
  17.  
  18. # 目标文件
  19. TARGET=$(BIN_DIR)/hellomake
  20.  
  21. src=$(wildcard ./src/*.c)
  22. dir= $(notdir $(src))
  23. PROJECT_OBJ= $(patsubst %.c,%.o,$(dir) )
  24. PROJECT_ALL_OBJS= $(addprefix ./objs/, $(PROJECT_OBJ))
  25.  
  26. $(TARGET): $(PROJECT_ALL_OBJS)
  27. $(CC) -o $@ $^ $(LIBS)
  28.  
  29. .PHONY : clean
  30. clean:
  31. -rm -rf $(TARGET) $(PROJECT_ALL_OBJS)
  32.  
  33. ./objs/%.o:./src/%.c
  34. @if test ! -d $(PROJECT_OBJ_DIR) ; \
  35. then \
  36. mkdir $(PROJECT_OBJ_DIR) ; \
  37. fi
  38.  
  39. @if test ! -d $(PROJECT_BIN_DIR) ; \
  40. then \
  41. mkdir $(PROJECT_BIN_DIR) ; \
  42. fi
  43.  
  44. $(CC) $(CFLAGS) -o $@ -c $< $(IncludeDir)

进一步优化makefile:

  1.  

#Hellomake
#Magnum, 2014-10-19
# 指令编译器和选项
CC=gcc
CFLAGS=-Wall
LIBS=-lm
IncludeDir = -I./include/
LinkDir = -L
OBJ_DIR = ./obj
BIN_DIR = ./bin
PROJECT_TOP_DIR=$(shell pwd)#$(shell cd ../; pwd)
PROJECT_BIN_DIR=./bin
PROJECT_SRC_DIR=./src
PROJECT_LIB_DIR=./lib
PROJECT_OBJ_DIR=./objs
MKDIR := mkdir -p

  1.  

# 目标文件
TARGET=$(BIN_DIR)/hellomake

  1.  

src=$(wildcard $(PROJECT_SRC_DIR)/*.c)
dir= $(notdir $(src))
PROJECT_OBJ= $(patsubst %.c,%.o,$(dir) )
PROJECT_ALL_OBJS= $(addprefix $(PROJECT_OBJ_DIR)/, $(PROJECT_OBJ))

  1.  

all: chdir $(TARGET)

  1.  

$(TARGET): $(PROJECT_ALL_OBJS)
$(CC) -o $@ $^ $(LIBS)

  1.  

chdir:
@if test ! -d $(PROJECT_OBJ_DIR) ; \
then \
mkdir $(PROJECT_OBJ_DIR) ; \
fi

  1.  

@if test ! -d $(PROJECT_BIN_DIR) ; \
then \
mkdir $(PROJECT_BIN_DIR) ; \
fi

  1.  

.PHONY : clean
clean:
-rm -rf $(TARGET) $(PROJECT_ALL_OBJS)

  1.  

./objs/%.o:./src/%.c
$(CC) $(CFLAGS) -o $@ -c $< $(IncludeDir)

  1.  

执行make也能得到正确的结果, "-I"指定啦编译的时候系统搜索头文件的系统路径首先是"-I"后面的路径,然后才是/usr/include 之类的。

提示: makefile文件结束后请删除不必要的空格,很可能你google 超久最后就是由于这些多余的空格引起的。

关于下面这部分代码不懂的,可以百度,网上有很多详细的解释:

src=$(wildcard ./src/*.c)
dir= $(notdir $(src))
PROJECT_OBJ= $(patsubst %.c,%.o,$(dir) )
PROJECT_ALL_OBJS= $(addprefix ./objs/, $(PROJECT_OBJ))

一步一步写一个简单通用的makefile(二)的更多相关文章

  1. 一步一步写一个简单通用的makefile(三)

    上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...

  2. 一步一步写一个简单通用的makefile(一)

    经常会用写一些小的程序有的是作为测试,但是每次都需要写一些简单的GCC 命令,有的时候移植一些项目中的部分代码到小程序里面进行测试,这个时候GCC 命令并不好些,如果写啦一个比较常用的makefile ...

  3. [置顶] 自己写一个简单通用的Makefile

    转自:http://blog.csdn.net/u011913612/article/details/52102241 一.makefile的作用 Makefile是用于自动编译和链接的,一个工程有很 ...

  4. 一步一步写一个简单通用的makefile(四)--写一个通用的makefile编译android可执行文件

    通常要把我们自己的的代码编译成在android里面编译的可执行文件,我们通常是建一个文件夹 . ├── Android.mk ├── Application.mk ├── convolve.cl ├─ ...

  5. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  6. linux设备驱动第三篇:如何写一个简单的字符设备驱动?

    在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存 ...

  7. 用node.js从零开始去写一个简单的爬虫

    如果你不会Python语言,正好又是一个node.js小白,看完这篇文章之后,一定会觉得受益匪浅,感受到自己又新get到了一门技能,如何用node.js从零开始去写一个简单的爬虫,十分钟时间就能搞定, ...

  8. linux设备驱动第三篇:写一个简单的字符设备驱动

          在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分 ...

  9. 用C写一个简单的推箱子游戏(一)

    我现在在读大二,我们有一门课程叫<操作系统>,课程考查要求我们可以写一段程序或者写Windows.iOS.Mac的发展历程.后面我结合网上的资料参考,就想用自己之前简单学过的C写一关的推箱 ...

随机推荐

  1. IOS 学习笔记 2015-03-24 OC-API-常用结构体

    一 标题 常用结构体 二 API 1 NSRange 表示一个范围 A 实例化 NSRange rg={3,5};//第一参数是起始位置第二个参数是长度 B 实例化 NSRange rg2=NSMak ...

  2. MongoDB笔记(一)MongoDB概述和安装

    概述 关键词:关系数据库.非关系数据库 关系数据库: 关系数据库,是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据.目前主流的关系数据库有oracle.SQL.ac ...

  3. django 学习点滴

    django连接数据库要安装第三方包,比如mysql的就是 python-mysqldb, 用apt-cache search python-mysql 搜索一下. django的project可以放 ...

  4. isset(), empty()

    isset()测试$a = '';isset($a); // true $a = FALSE;var_dump(isset($a)); // true $a = NULL;var_dump(isset ...

  5. gentoo下的wpa_supplicant无线网配置

    在linux使用wpa_supplicant获得无线网的最痛苦的是莫过于去配置wpa_supplicant.conf文件了(当然对于linux老手这不算什么), 但是可以用一种简便的方法直接输入命令行 ...

  6. 【javascript 引用类型(一)】

    javascript 的引用类型大致分为:Object 类型.Array 类型.Date 类型.RegExp 类型.Function 类型.基本包装类型和单体内置对象.这里我们着重介绍 Object ...

  7. uboot顶层config.mk分析

    uboot顶层目录中的config.mk定义了确定了当前执行makefile所对应的源文件目录.目标文件目录,编译的程序编译.连接的选项,以及目标文件生成的规则等等.它被包含在顶层的makefile以 ...

  8. swift 与 OC 混合编程

    原文地址:http://www.cocoachina.com/swift/20150608/12025.html 一.解决问题 Swift项目需要使用封装好的Objective-c组件.第三方类库,苹 ...

  9. The CircuitCalculator.com Blog a blog with live web calculators Home About Policies Contact PCB

    PCB Trace Width Calculator 转载自:CircuitCalculator.com 关键词: PCB,Layout,电流,导线宽度. This Javascript web ca ...

  10. Struts, Namespace用法

    最近在用SSH框架做一个项目,在使用Struts 的namespace时遇到不少问题,现在就对struts namespace 做一个简单的介绍吧.(本文从项目结构展开叙述) (第1次写博客, 写的不 ...