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

这一篇源代码沿用上一篇的源代码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, 2014-10-19
# 指令编译器和选项  
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

4 directories, 7 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 =15; 
    printf("Value:%f\n",log(value)); 
  return(0);
}

hellofunc.c:

//#include"../include/hellofunc.h"
#include<hellofunc.h>
#include<stdio.h>
void myPrintHelloMake(void) {

  printf("Hello makefiles!\n");
  return;
}

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 ./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))

posted @ 2014-10-19 22:29  Magnum Programm Life  阅读(1057)  评论(0编辑  收藏  举报