【问题标题】:How to pass a value to Make, which gets passed to C code如何将值传递给 Make,然后传递给 C 代码
【发布时间】:2012-08-21 18:53:45
【问题描述】:

我正在寻求帮助,让我的 Makefile 做我想做的事。

我已经弄清楚如何将预处理代码添加到我的 C 源代码中,只有在我为调试而编译时才会编译:

#if DEBUG
  printf("main()\n");

  {
    /* Pauses execution so gdb can attach. */
    int i=9;
    pid_t PID;
    char hostname[256];
    gethostname(hostname, sizeof(hostname));
    printf("PID %d on %s ready for attach.\n", PID=getpid(), hostname);
    fflush(stdout);
    while (i>0) {
      sleep(5);
      i--;
    }
  }
#endif

而且我发现如果我将-DDEBUG=1 添加到我的编译语句中,上面的代码将被编译(否则它不会被编译)。

接下来,我想向我的 Makefile 传递一个标志,该标志将包含或不包含 -D 选项。目前,我有两个单独的编译行,我酌情评论和取消评论。这是我的 Makefile(我从某人那里继承的,我很难理解)。看看上面写着CFLAGS?的行:

SHELL = /bin/sh

prefix       = /home/schwarz/sundials/instdir
exec_prefix  = ${prefix}
includedir   = ${prefix}/include
libdir       = ${exec_prefix}/lib

CPP         = cc -E
CPPFLAGS    =
CC          = cc
# CFLAGS      = -Wall -g
CFLAGS      = -Wall -g -DDEBUG=1
# CFLAGS      = -g -O2
LDFLAGS     =
LIBS        = -lm
MPICC       = /usr/local/mpi/bin/mpicc
MPI_INC_DIR = /usr/local/mpi/bin/../include
MPI_LIB_DIR = /usr/local/mpi/bin/../lib
MPI_LIBS    =
MPI_FLAGS   =

INCLUDES = -I${includedir} -I${MPI_INC_DIR}
LIBRARIES = -lsundials_cvode -lsundials_nvecparallel ${LIBS}
LIBRARIES_BL =

EXAMPLES = FPU          # cvAdvDiff_non_p cvDiurnal_kry_bbd_p cvDiurnal_kry_p


OBJECTS = ${EXAMPLES:=.o}

# -----------------------------------------------------------------------------------------

.SUFFIXES : .o .c

.c.o :
        ${MPICC} ${CPPFLAGS} ${CFLAGS} ${MPI_FLAGS} ${INCLUDES} -c $<

# -----------------------------------------------------------------------------------------

all: ${OBJECTS}
        @for i in ${EXAMPLES} ; do \
          echo "${MPICC} -o $${i} $${i}.o ${MPI_FLAGS} ${CFLAGS} ${LDFLAGS} -L${libdir} ${LIBRARIES} -L${MPI_LIB_DIR} ${MPI_LIBS} ${LIBRARIES_BL}" ; \
          ${MPICC} -o $${i} $${i}.o ${MPI_FLAGS} ${CFLAGS} ${LDFLAGS} -L${libdir} ${LIBRARIES} -L${MPI_LIB_DIR} ${MPI_LIBS} ${LIBRARIES_BL}; \
        done

clean:
        rm -f ${OBJECTS}
        rm -f ${EXAMPLES}

我已经搜索过网络 - 我发誓! - 但无法弄清楚如何将参数传递到makefile。 如何设置我的 Makefile,以便它针对不同的编译需求对同一代码进行不同类型的编译? 如果我可以将特定值传递给 Makefile,这将传递一个编译的特定值,我可以用它来初始化代码中的i。 (IOW,我编译为make 8,C 编译为int i=8;)。在 Make 中是否有可能?

顺便说一句,我通过列出带有标签(冒号)的文件以及它们的依赖项来了解 Makefile 以及它们如何工作。但我不明白这个 Makefile 是如何工作的,或者为什么它会发出两个编译语句。因此,简短的解释也会有所帮助。

【问题讨论】:

  • 您阅读过手​​册的this section 吗?另外,尽可能不要使用=,而是使用:=
  • @KerrekSB 很好的链接,虽然例子不多。我仍然需要如何将值传递给 make。谢谢。

标签: c linux makefile


【解决方案1】:

在调试版本和发布版本之间进行选择:

ifeq($(debug),1)
  CFLAGS      = -Wall -g -DDEBUG=1
else
  CFLAGS      = -Wall -g
endif

然后调用make:

make debug=1

使用 DEBUG 编译,或者:

make

无需调试即可编译。

用于初始化 i:

#include <stdio.h>

#ifndef INIT_I
# define INIT_I 9
#endif
int main() {
  int i = INIT_I;
  return 0;
}

和生成文件:

ifneq ($(init_i),)
CFLAGS = "-DINIT_I=$(init_i)"
endif

all:
  gcc d.c $(CFLAGS) -E

设置初始 i:

make init_i=10

或使用默认值:

make

【讨论】:

  • 我相信您在第一个代码块中的ifeq 之后需要一个空格(没有它,我的 Linux 会出现错误)。我尝试添加一个以供将来参考,但我的编辑必须是很多字符! :(
【解决方案2】:

示例生成文件:

...
CFLAGS = whatever
....
ifeq ("$(DEBUG)","yes")
CFLAGS += -DDEBUG=1
endif

有了这个,你可以运行 make:

make "DEBUG=yes"

基本上,您可以在 make 命令行上设置 makefile 变量。您可以像使用 makefile 中的任何其他变量一样使用它们,因此您也可以直接使用它们。

编辑:不过,你必须小心。除非您注意适当地命名您的目标文件,或使用不同的构建目录,否则使用不同的“DEBUG”设置运行 make 不会自动重新编译。

【讨论】:

  • 你能澄清你的“编辑”吗?你的意思是如果你对DEBUG 使用不同的值执行make,但源没有改变,那么它不会编译?对于我的下一个项目,我将找到一种使 Makefile 成为依赖项(或其他东西!)的方法。 :D
【解决方案3】:

实现您想要的一种方法是将CFLAGS 的值从您的shell 传递到您的makefile。

CFLAGS='-Wall -g -DDEBUG=1' make -e 

为您调试版本,或

CFLAGS='-Wall -g' make -e

对于你的非调试者

【讨论】:

  • 谢谢斯蒂芬妮。有关如何在 Makefile 中设置 DEBUG 的值,请参阅其他答案。
【解决方案4】:

是的。

您可以使用 gcc 的 -D 选项来声明一个宏,在您的代码中使用它:

> gcc -DMYINT=8 foo.c

与 foo.c

int foo(void)
{
  int my = MYINT;
}

并在您的 makefile 中使用:

CFLAGS    =    -DMYINT=$(MYINT)

然后调用 make :

> make MYINT=8

【讨论】:

    【解决方案5】:

    你可以像这样在 make 中分配你的 CFLAGS 变量: CFLAGS ?= -Wall -g -DDEBUG=1

    如果你运行不带参数的 make 命令, CFLAGS 将有一个默认值 '-Wall -g -DDEBUG=1'

    如果你像这样运行 make: 使 CFLAGS='-DDEBUG=0'

    此命令将为 CFLAGS 值分配值“-DDEBUG=0” 分配的值将覆盖 makefile 中分配的默认值

    【讨论】:

    • 谢谢。我使用?= 来设置延迟。例如。 delay ?=0 CFLAGS = &lt;options&gt; -DDELAY=$(delay)(“延迟”和“CFAGS”之前应该有一个新行)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 2015-04-12
    • 2011-12-10
    • 1970-01-01
    相关资源
    最近更新 更多