在Makefile依赖项中强制订单

时间:2017-09-07 04:35:39

标签: c sed makefile

我需要一些帮助编写GNU makefile。我有一个C程序" main.c",这取决于" CONSTANT"的值。在文件" constants.h"中定义。

" main.c中"

#include <stdio.h>
#include "constants.h"

void work(void)
{
    int array[CONSTANT];
    for (int i = 0; i < CONSTANT; i++) {
        printf("%d\n", i);
    }
}

int main(int argc, char const* argv[])
{
    printf("constant=%d\n", CONSTANT);
    work();
    return 0;
}

&#34; constant.h&#34;

#ifndef CONSTANTS_H
#define CONSTANTS_H

#define CONSTANT 4
#endif

我在这里尝试做的是使用不同的值编译程序&#34; CONSTANT&#34;。例如,&#34; out1&#34;编译时使用&#34; CONSTANT = 1&#34;并且使用&#34; make all&#34;,我应该能够生成所有变体(&#34; out1&#34;,&#34; out2&#34;&#34; out4&#34;)。

问题是&#34; a.o&#34; &#34; main.c&#34;也取决于&#34; CONSTANT&#34;的价值。所以&#34; a.o&#34;必须在&#34; sed%&#34;之后编译。但是,据我所知,没有办法在&#34; make&#34;强制依赖命令(我想这是使用makefile的重点)。

解决这种情况的推荐方法是什么?

&#34;生成文件&#34;

CC= gcc
CFLAGS  = -std=c99 -Wall

CONSTANTS = 1 2 4
targets = $(addprefix out, $(CONSTANTS))
seds = $(addprefix sed, $(CONSTANTS))

.PHONY: $(seds)
$(seds): sed%:
  sed -i 's/define CONSTANT [0-9]*/define CONSTANT $*/g' constants.h

$(targets): out%: main.c sed% a.o
  $(CC) $(CFLAGS) $< a.o -o $@

a.o: a.c constant.h
  $(CC) $(CFLAGS) $< a.o -o $@

 .PHONY: all
 all : $(targets)

请注意,我知道我可以重写&#34; main.c&#34;这样它就会从命令行中获取一个参数。在实践中,除了&#34; main.c&#34;之外的许多其他文件。取决于&#34; CONSTANT&#34;,所以我想避免重写所有这些文件。我也知道我可以做类似&#34; gcc -DCONSTANT = n main.c&#34;,但是每个文件都依赖于&#34; CONSTANT&#34;必须重新编译。

相关问题

1 个答案:

答案 0 :(得分:3)

  

我知道我可以做类似&#34; gcc -DCONSTANT = n main.c&#34;   但是每个文件都依赖于&#34; CONSTANT&#34;必须重新编译。

如果你生成了makefile,这不是一个障碍 每个编译配方中正确的-DCONSTANT=n和不同的目标文件。

以下是一个例子:

<强> constants.h

#ifndef CONSTANTS_H
#define CONSTANTS_H

#ifndef CONSTANT
#define CONSTANT 4
#endif

#endif

<强> foo.c的

#include "constants.h"

int foo = CONSTANT;

<强>的main.c

#include <stdio.h>
#include "constants.h"

extern int foo;

int main()
{
    printf("%d\n",CONSTANT + foo);
    return 0;
}

<强>生成文件

CC := gcc
CFLAGS := -std=c99 -Wall

CONSTANTS = 1 2 4
TARGETS = $(addprefix out, $(CONSTANTS))
SRCS := main.c foo.c

define compile =
$(basename $(1))$(2).o: $(1) constants.h
    $$(CC) -c -DCONSTANT=$(2) $$(CFLAGS) $$< -o $$@
endef

.PHONY: all clean

all : $(TARGETS)

$(foreach src,$(SRCS),\
    $(foreach const,$(CONSTANTS),$(eval $(call compile,$(src),$(const))))) 

out%: main%.o foo%.o 
    $(CC) $^ -o $@


clean:
    rm -f $(TARGETS) *.o

这就像:

$ make
gcc -c -DCONSTANT=1 -std=c99 -Wall main.c -o main1.o
gcc -c -DCONSTANT=1 -std=c99 -Wall foo.c -o foo1.o
gcc main1.o foo1.o -o out1
gcc -c -DCONSTANT=2 -std=c99 -Wall main.c -o main2.o
gcc -c -DCONSTANT=2 -std=c99 -Wall foo.c -o foo2.o
gcc main2.o foo2.o -o out2
gcc -c -DCONSTANT=4 -std=c99 -Wall main.c -o main4.o
gcc -c -DCONSTANT=4 -std=c99 -Wall foo.c -o foo4.o
gcc main4.o foo4.o -o out4

结果程序运行如下:

$ for i in 1 2 4; do ./out$i; done
2
4
8