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

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

.
├── include
│   └── hellofunc.h
├── makefile
└── src
├── hellofunc.c
└── hellomake.c

hellomake.c 代码:

#include"../include/hellofunc.h"
#include<stdio.h>
void myPrintHelloMake(void) { printf("Hello makefiles!\n");
return;
}

hellofunc.c代码:

#include"../include/hellofunc.h"
#include<stdio.h>
void myPrintHelloMake(void) { printf("Hello makefiles!\n");
return;
}

hellofunc.h代码:

/*
example include file
*/ void myPrintHelloMake(void);

makefile 文件代码:

#Hellomake
#Magnum, --
# 指令编译器和选项
CC=gcc
CFLAGS=-Wall
LIBS=-lm
IncludeDir = -I./hellofunc/
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 # 目标文件
TARGET=$(BIN_DIR)/hellomake src=$(wildcard ./src/*.c)
dir= $(notdir $(src))
PROJECT_OBJ= $(patsubst %.c,%.o,$(dir) )
PROJECT_ALL_OBJS= $(addprefix ./objs/, $(PROJECT_OBJ)) $(TARGET): $(PROJECT_ALL_OBJS)
$(CC) -o $@ $^ $(LIBS) .PHONY : clean
clean:
-rm -rf $(TARGET) $(PROJECT_ALL_OBJS) ./objs/%.o:./src/%.c
@if test ! -d $(PROJECT_OBJ_DIR) ; \
then \
mkdir $(PROJECT_OBJ_DIR) ; \
fi @if test ! -d $(PROJECT_BIN_DIR) ; \
then \
mkdir $(PROJECT_BIN_DIR) ; \
fi $(CC) $(CFLAGS) -o $@ -c $<

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

执行make,结果如下:

.
├── bin
│   └── hellomake
├── include
│   └── hellofunc.h
├── makefile
├── objs
│   ├── hellofunc.o
│   └── hellomake.o
└── src
├── hellofunc.c
└── hellomake.c directories, files

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

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

Hello makefiles!
Value:2.708050

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

也可以这样修改:

hellomake.c:

//#include "../include/hellofunc.h"
#include<hellofunc.h>
#include<stdio.h>
#include<math.h>
int main() {
// call a function in another file
myPrintHelloMake();
double value =;
printf("Value:%f\n",log(value));
return();
}

hellofunc.c:

//#include"../include/hellofunc.h"
#include<hellofunc.h>
#include<stdio.h>
void myPrintHelloMake(void) { printf("Hello makefiles!\n");
return;
}

makefile:

#Hellomake
#Magnum, --
# 指令编译器和选项
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 # 目标文件
TARGET=$(BIN_DIR)/hellomake src=$(wildcard ./src/*.c)
dir= $(notdir $(src))
PROJECT_OBJ= $(patsubst %.c,%.o,$(dir) )
PROJECT_ALL_OBJS= $(addprefix ./objs/, $(PROJECT_OBJ)) $(TARGET): $(PROJECT_ALL_OBJS)
$(CC) -o $@ $^ $(LIBS) .PHONY : clean
clean:
-rm -rf $(TARGET) $(PROJECT_ALL_OBJS) ./objs/%.o:./src/%.c
@if test ! -d $(PROJECT_OBJ_DIR) ; \
then \
mkdir $(PROJECT_OBJ_DIR) ; \
fi @if test ! -d $(PROJECT_BIN_DIR) ; \
then \
mkdir $(PROJECT_BIN_DIR) ; \
fi $(CC) $(CFLAGS) -o $@ -c $< $(IncludeDir)

进一步优化makefile:


#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


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


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


all: chdir $(TARGET)


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


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


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


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


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

 

执行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. c++ primer复习(三)

    1 istream.ostream类型,cin.cout.cerr是istream或ostream类型的具体的对象,<<和>>是操纵符 getline函数的参数是istream ...

  2. OpenJudge 2775 文件结构“图”/ Poj 1057 FILE MAPPING

    1.链接地址: http://bailian.openjudge.cn/practice/2775 http://poj.org/problem?id=1057 2.题目: 总时间限制: 1000ms ...

  3. 简单Linq笔记

    Linq是.net 3.5才引入的 要引入命名空间System.Linq. Linq  to XML要引入System.Xml.Linq Linq to ADO.NET要引入System.Data.L ...

  4. 用javascript操作xml(二)JavaScript 将XML转换成字符串(xml to string)

    function xmlToString(xmlData) { var xmlString; //IE if (window.ActiveXObject){ xmlString = xmlData.x ...

  5. 基于smarty+medoo手搭php简单的框架

    1.首先看一下搭建好的smarty目录(箭头位置是后新建的文件夹,也是框架结构的最终目录结构) 2.首先在根目录下新建index.php文件即入口文件,内容如下 <?phprequire_onc ...

  6. (转载)delphi 常用函数(数学)

    delphi 常用函数(数学) Delphi中怎么将实数取整? floor 和 ceil 是 math unit 里的函数,使用前要先 Uses Math.trunc 和 round 是 system ...

  7. Python 集合(set)使用

    1.python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差 ...

  8. 面试题:实现LRUCache::Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  9. 第 15 章 组合模式【Composite Pattern】

    以下内容出自:<<24种设计模式介绍与6大设计原则>> 大家在上学的时候应该都学过“数据结构”这门课程吧,还记得其中有一节叫“二叉树”吧,我们上 学那会儿这一章节是必考内容,左 ...

  10. OpenTSDB案例总结

    加宽行可增加扫描速度 采用组合rowkey,利用数据本地性加快扫描 少数宽行,并不比多数窄行节省空间 缩短Column family 和 column的名字 合并若干列.