加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何编写模式规则以分隔对象和源文件的位置?

发布时间:2020-12-16 06:52:23 所属栏目:百科 来源:网络整理
导读:假设我有一个目录结构,如: ./Header./Srcs./makefile 文件夹./Header/的内容是两个头文件: 那么header1.h #ifndef HEADER1_H#define HEADER1_H#include stdio.hvoid func1();#endif header2.h #ifndef HEADER2_H#define HEADER2_H#include stdio.hvoid fun
假设我有一个目录结构,如:

./Header
./Srcs
./makefile

文件夹./Header/的内容是两个头文件:

那么header1.h

#ifndef HEADER1_H
#define HEADER1_H
#include <stdio.h>

void func1();

#endif

header2.h

#ifndef HEADER2_H
#define HEADER2_H
#include <stdio.h>

void func2();

#endif

在./Srcs/我有以下srcs:

src1.c

#include <header1.h>

void func1() {
   printf("func1()n");
}

src2.c

#include <header2.h>

void func2() {
   printf("func2()n");
}

main.c中

#include <header1.h>
#include <header2.h>

int main(int argc,char** argv) {
   func1();
   func2();
   return 0;
}

最后makefile看起来像这样:

CC=gcc
INCLUDE=-I./Header/
SRC_DIR=./Srcs/
SRC_LIST=$(addprefix $(SRC_DIR),main.c src1.c src2.c)
OBJ_LIST=$(addsuffix .o,$(basename $(SRC_LIST)))
OUTPUT=test

%.o : %.c
    $(CC) -c $< -o $@ $(INCLUDE)

all : $(OBJ_LIST)
    $(CC) -o $(OUTPUT) $(OBJ_LIST)

clean : $(OUTPUT) $(OBJ_LIST)
    rm -r $(OUTPUT) $(OBJ_LIST)

执行makefile我得到:

gcc -c Srcs/main.c -o Srcs/main.o -I./Header/
gcc -c Srcs/src1.c -o Srcs/src1.o -I./Header/
gcc -c Srcs/src2.c -o Srcs/src2.o -I./Header/
gcc -o test ./Srcs/main.o ./Srcs/src1.o ./Srcs/src2.o

具体来说,由于我使用的模式规则,所有的目标文件都是在文件夹./Srcs/中生成的,我想要实现的是将所有目标文件放入最终输出所在的目录中,我的具体例子,最终输出将在makefile所在的同一目录中.

如何编写我的makefile以实现这样的目标?

解决方法

如果要将构建输出放在与源相同的结构中,但是在构建目录中:

#PROJDIR is the folder where your Makefile is
PROJDIR := $(realpath $(CURDIR)/..)

#SOURCEDIR is the root folder where your sources sub-folder ares
SOURCEDIR := $(PROJDIR)/Sources

#BUILDDIR is the root folder where your objects will be
BUILDDIR := $(PROJDIR)/Build

#DIRS are the sub-folder,e.g. Sources/Folder1 and Build/Folder1
DIRS = Folder0 Folder1 Folder2

#Here we create a list of source and builder folders with full path
SOURCEDIRS = $(foreach dir,$(DIRS),$(addprefix $(SOURCEDIR)/,$(dir)))
TARGETDIRS = $(foreach dir,$(addprefix $(BUILDDIR)/,$(dir)))

#We allow GNU make to search for the sources in all the sources folders
VPATH = $(SOURCEDIRS)

#We define a function to generate a Build/Folder1/%.o: %.c rule for each sub-folder
define generateRules
$(1)/%.o: %.c
    @echo Building $$@
    $(CC) -c  -o $$@ $$< 
endef

#Finally we generate the rule for each build folder
$(foreach targetdir,$(TARGETDIRS),$(eval $(call generateRules,$(targetdir))))

或者,如果要将所有构建项放在构建目录中:

#PROJDIR is the folder where your Makefile is
PROJDIR := $(realpath $(CURDIR)/..)

#SOURCEDIR is the root folder where your sources sub-folder ares
SOURCEDIR := $(PROJDIR)/Sources

#BUILDDIR is the root folder where your objects will be
BUILDDIR := $(PROJDIR)/Build

#DIRS are the sub-folder,e.g. Sources/Folder1 and Build/Folder1
DIRS = Folder0 Folder1 Folder2

#Here we create a list of source with full path
SOURCEDIRS = $(foreach dir,$(dir)))

#We allow GNU make to search for the sources in all the sources folders
VPATH = $(SOURCEDIRS)

$(BUILDDIR)/%.o: %.c
    $(CC) -o $@ $<

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读