【问题标题】:convert multiple makefiles into one makefile将多个makefile转换为一个makefile
【发布时间】:2013-01-23 08:04:06
【问题描述】:

我只是写了一些纯c程序来练习,每个小程序都有一个XXX.h文件XXX.c文件和XXX_test.c文件,里面有main函数。 XXX.c 文件和 XXX_test.c 都可能包含其他一些 YYY.h 文件。我使用 gcc -MM 自动查找 XXX_test.c 文件的依赖关系。最后,我想出了makefile(使用GNU makefile)XXX.mk

# change your targets to your real targets
MINGW := MINGW32_NT-6.1
CC = gcc
OFLAG = -o 
CFLAGS = -Wall -g -DDEBUG
# get the dependent header files and change their name to source files
TARGET := XXX_test
FILES := $(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET))))
SRCS := $(FILES:.h=.c)
DEPS := $(SRCS:.c=.d)
OBJECTS := $(SRCS:.c=.o)

#determine the os platform
ifdef SystemRoot
   ifeq ($(shell uname), ${MINGW})
      RM = rm -f
      FixPath = $1
   else
      RM = del /Q
      FixPath = $(subst /,\,$1)
   endif
else
   ifeq ($(shell uname), Linux)
      RM = rm -f
      FixPath = $1
   endif
endif


all: ${TARGET}
# include .d files generated by gcc -MMD opt
-include $(DEPS)
# to generate the .o files as well as the .d files
%.o:%.c
    $(CC) $(CFLAGS) -c -MMD $< -o $@

# generate the executable program
${TARGET}: ${OBJECTS}
    ${CC} $^ ${OFLAG} $@

.PHONY:clean
# the "$" is not needed before "FixPath"
clean:
    $(RM) $(call FixPath, ${OBJECTS} ${DEPS})

每个小程序都有一个XXX.mk 文件。它们几乎相同,只是变量TARGET 中的内容不同(参见上面的makefile)。所以我有XXX.mkYYY.mk 等...我想问的问题是如何将所有的makefile,即XXX.mkYYY.mk...转换成一个makefile? 例如generic.mk,变量TARGETS(注意S)分配给XXX_test YYY_test ...。我觉得难以处理的是variable dependencies

TARGET --> OBJECTS --> SRCS --> FILES --> TARGET(the FILES is generate by gcc using -MM opt)
                         ↓
                        DEPS(used to include the .d files)

每个目标(例如 XXX_test)应该依赖于它们的一堆文件。我想看看 GNU makefile 的强大功能,我该怎么做呢?我正在学习使用 gmake。

【问题讨论】:

  • 无论二进制文件的数量如何,您是否可以使用总共需要两个单独的 Makefile 的 2 阶段构建?

标签: makefile gnu-make


【解决方案1】:

您发现,您遇到的主要问题是,从 DEPS 扩展 OBJECTS 不适用于多个目标。

解决此问题的一种可能性是使用两阶段方法,其中第二阶段仅处理构建单个二进制文件(并进行所有依赖项跟踪和二进制对象编译),第一阶段为每个调用第二阶段给定二进制文件。

此解决方案涉及 两个 Makefile(不完全符合您的要求,但仍然如此):

生成文件:

TARGETS = XXX_test YYY_test ZZZ_test XYZ_test
CLEANTARGETS=$(TARGETS:=_clean)

all: $(TARGETS)
clean: $(CLEANTARGETS)

$(TARGETS) $(CLEANTARGETS):
        make -f Makefile.sub $@

.PHONY: all clean $(CLEANTARGETS)

这个 makefile 只是调用另一个 make 程序来构建作为参数和辅助 Makefile.sub:

# change your targets to your real targets
MINGW := MINGW32_NT-6.1
CC = gcc
OFLAG = -o 
CFLAGS = -Wall -g -DDEBUG
# get the dependent header files and change their name to source files
TARGET=$(MAKECMDGOALS:_clean=)
FILES= $(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET))))
SRCS= $(patsubst %.h,%.c,$(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET)))))

DEPS= $(SRCS:.c=.d)
OBJECTS= $(SRCS:.c=.o)

#determine the os platform
ifdef SystemRoot
   ifeq ($(shell uname), $(MINGW))
      RM = rm -f
      FixPath = $1
   else
      RM = del /Q
      FixPath = $(subst /,\,$1)
   endif
else
   ifeq ($(shell uname), Linux)
      RM = rm -f
      FixPath = $1
   endif
endif


# include .d files generated by gcc -MMD opt
-include $(DEPS)
# to generate the .o files as well as the .d files
%.o:%.c
    $(CC) $(CFLAGS) -c -MMD $< -o $@

# generate the executable program
$(TARGET): $(OBJECTS)
    $(CC) $^ $(OFLAG) $@

.PHONY:clean
# the "$" is not needed before "FixPath"
clean:
    $(RM) $(call FixPath, $(OBJECTS) $(DEPS))

$(TARGET)_clean: clean

如果您坚持使用单个 Makefile,那么恐怕您必须手动进行依赖跟踪。 更常见的构建系统之一是 autotools,您必须自己提供每个二进制文件的源代码(要运行以下内容,您需要安装 autotools;运行 autoreconf 以从以下代码生成 configureMakefile.in;然后运行./configure创建跨平台Makefile):

Makefile.am:

 bin_PROGRAMS = XXX_test YYY_test
 XXX_test_SOURCES = XXX_test.c XXX.c
 YYY_test_SOURCES = YYY_test.c YYY.c

配置.ac:

AC_INIT([XYZ],[0.1])
AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION)
AC_CONFIG_FILES([Makefile])
AC_PROG_INSTALL
AC_LANG_C
AC_PROG_CC
AC_OUTPUT

【讨论】:

  • 顺便说一句,您认为我需要将%.d:%.c 依赖项添加到makefile.sub 文件吗?即当%.c文件更改时,它将通过-MMD opt生成%.d文件,但我想知道makefile.sub是否会include%.d文件而不是新文件?
【解决方案2】:

目标/依赖项可以是多值的。 如果你指定

 TARGET := XXX_test XXY_test XYZ_test XZY_test

然后运行make all(这是默认设置,因为all 是Makefile 中的第一个目标;因此您也可以简单地运行make),将为您构建所有这些???_test 文件。

【讨论】:

  • FILES var 将包含 XXX_test XXY_test XYZ_test XZY_test 以及 SRCSOBJECTS 的文件,这将导致多个 main 函数定义和不必要的依赖关系。
猜你喜欢
  • 2012-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多