【问题标题】:Make file two macros制作文件两个宏
【发布时间】:2012-09-28 02:04:43
【问题描述】:

我想在单个 Makefile 中使用宏来编译两个程序。当我运行 make 时,它​​会产生以下输出:

Makefile:27: warning: overriding commands for target `compose'
Makefile:24: warning: ignoring old commands for target `compose'
g++ -g `Magick++-config --cppflags` -c alphamask.cpp
g++ -g `Magick++-config --ldflags` -o alphamask alphamask.o -L /usr/lib64/ -lglut -lGL -lGLU -lMagick++ -lm

它只编译第二个程序。有没有办法让宏编译两个程序?这是我当前的 Makefile:

CC      = g++
C       = cpp

CFLAGS      = -g `Magick++-config --cppflags`
LFLAGS      = -g `Magick++-config --ldflags`

ifeq ("$(shell uname)", "Darwin")
  LDFLAGS     = -framework Foundation -framework GLUT -framework OpenGL -lMagick++ -lm
else
  ifeq ("$(shell uname)", "Linux")
    LDFLAGS     = -L /usr/lib64/ -lglut -lGL -lGLU -lMagick++ -lm
  endif
endif

ALPHA       = alphamask
COMP = compose 

${ALPHA}:   ${ALPHA}.o
    ${CC} ${LFLAGS} -o ${ALPHA} ${ALPHA}.o ${LDFLAGS}

${ALPHA}.o: ${ALPHA}.${C}
    ${CC} ${CFLAGS} -c ${ALPHA}.${C}

${COMP}:    ${COMP}.o
    ${CC} ${LFLAGS} -o ${COMP} ${COMP}.o ${LDFLAGS}

${COMP}.o:  ${COMP}.${C}
    ${CC} ${CFLAGS} -c ${COMP}.${C}


run:
    ./alphamask dhouse.png
    ./compose alphamask.png


clean:
    rm -f core.* *.o *~ ${ALPHA} ${COMP}

【问题讨论】:

  • 你可以在一行上写else ifeq ...而丢掉一个endif。

标签: makefile


【解决方案1】:

第一个问题:

COMP = compose 

${COMP}.o: ...

在 Make 中为变量添加后缀并不是那么简单。在这种情况下,您会遇到一些空白问题,这就是您收到警告消息的原因,以及即使您尝试也无法构建 compose 的原因。

既然您是初学者,让我们采用一种简单的方法,粗略但有效。我们将重写这些规则,并在顶部添加一个,以便您可以使用make 构建这两个文件:

all: alphamask compose

alphamask: alphamask.o
    ${CC} ${LFLAGS} -o alphamask alphamask.o ${LDFLAGS}

alphamask.o: alphamask.cpp
    ${CC} ${CFLAGS} -c alphamask.cpp

compose: compose.o
    ${CC} ${LFLAGS} -o compose compose.o ${LDFLAGS}

compose.o: compose.cpp
    ${CC} ${CFLAGS} -c compose.cpp

在你完美地完成这项工作后,可以进行很多改进。

编辑:

现在它运行良好,我们可以改进它。首先让我们放入自动变量,以减少冗余:$@ 是目标的名称,$^ 是先决条件,$< 是第一个先决条件。

all: alphamask compose

alphamask: alphamask.o
    ${CC} ${LFLAGS} -o $@ $^ ${LDFLAGS}

alphamask.o: alphamask.cpp
    ${CC} ${CFLAGS} -c $<

compose: compose.o
    ${CC} ${LFLAGS} -o $@ $^ ${LDFLAGS}

compose.o: compose.cpp
    ${CC} ${CFLAGS} -c $<

现在我们看到命令中有冗余,所以我们可以组合规则:

all: alphamask compose

alphamask: alphamask.o

compose: compose.o

alphamask compose:
    ${CC} ${LFLAGS} -o $@ $^ ${LDFLAGS}

alphamask.o: alphamask.cpp    

compose.o: compose.cpp

alphamask.o compose.o:
    ${CC} ${CFLAGS} -c $<

现在我们可以用模式规则替换对象 (.o) 规则:

all: alphamask compose

alphamask: alphamask.o

compose: compose.o

alphamask compose:
    ${CC} ${LFLAGS} -o $@ $^ ${LDFLAGS}

%.o: %.cpp
    ${CC} ${CFLAGS} -c $<

以及可执行文件的静态模式规则。 (我们也可以对这些使用模式规则,但这有点太笼统了。)

EXECUTABLES = alphamask compose

.PHONY: all
all: $(EXECUTABLES)

$(EXECUTABLES): % : %.o
    ${CC} ${LFLAGS} -o $@ $^ ${LDFLAGS}

%.o: %.cpp
    ${CC} ${CFLAGS} -c $<

当您进行这些改进时,在进行下一个改进之前,让每项改进完美运行。

【讨论】:

  • tyler@Tyler-Satellite-A665:~/Desktop/404/assignment4$ make Makefile:18: *** 缺少分隔符。停止。我收到此错误
  • 您还建议哪些类型的改进?
  • @user1210093:第 18 行是all: alphamask compose,对吗?
  • ${CC} ${LFLAGS} -o alphamask alphamask.o ${LDFLAGS} 这是第 18 行
  • 我不希望看到${COMP}.o 有任何问题,除非您习惯在代码周围留下尾随空格,即使那样我也不希望有太多麻烦。修改后的 makefile 对宏来说太轻了,我不喜欢;您至少可以使用-o $@ 以避免在链接行中重复输出文件名;我仍然希望看到${COMP}.o 或宏COMP.c = compose.c 和另一个COMP.o = ${COMP.c:.c=.o},并在适当的地方使用它们。尽可能避免重复任何简单的名称。
【解决方案2】:

我很确定您需要一个规则来制作它们(对两个项目都使用依赖项):

    all: ${ALPHA} ${COMP}

当然还有:

make all

【讨论】:

  • 我想让宏完成这项工作,而不必键入 make all 之类的内容。当我只有一个宏时,我只需键入 make 就可以了。有什么想法吗?
  • 最好的办法是了解您正在使用的工具。来自 GNU make 的文档 (gnu.org/software/make/manual/make.html),“[b]y 默认情况下,make 从第一个目标开始”。如果您的第一个目标是 ${ALPHA},那么这将默认执行。将“all”目标放在 Makefile 的顶部会得到你想要的结果。
  • 如果没有指定目标,make 会重建文件中的第一个目标。按照惯例,这个目标是all,它会做所有应该默认做的事情。它是一个伪目标,在 GNU 中,make 适合被列为虚假目标:.PHONY: all(因为在构建之后你真的不需要一个名为“all”的文件)。
猜你喜欢
  • 1970-01-01
  • 2014-03-08
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 1970-01-01
相关资源
最近更新 更多