2012-08-27 109 views
2

我在寻找帮助让我的Makefile做我想做的事情。如何将一个值传递给Make,将其传递给C代码

我想通了如何预处理代码添加到我的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,该Makefile会将特定值传递给编译,我可以使用它来在代码中初始化i。 (IOW,我编译为make 8,C编译为int i=8;)。 Make有甚么可能?

顺便说一下,我已经阅读了有关Makefiles以及它们如何使用标签(冒号)列出文件以及依赖关系的工作方式。但我不明白这个Makefile是如何工作的或者它为什么会发出两个编译语句。所以简单的解释也会有帮助。

+2

你读过手册中的[本节](http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_7.html)?另外,尽可能不要使用'='并且更喜欢':='。 –

+0

@KerrekSB良好的链接,但不是很多的例子。我仍然需要如何将价值传递给make。谢谢。 – Jeff

回答

7

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

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

,然后调用化妆:

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 
+0

我相信你在你的第一个代码块中需要一个ifeq后面的空格(我的Linux在没有它的情况下踢出一个错误)。我试图添加一个供将来参考,但我的编辑必须是lota字符! :( – Jeff

3

Makefile例子:

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

有了这个,你可以运行作出:

make "DEBUG=yes" 

基本上,你可以设置make命令行上的makefile变量。你可以像makefile中的其他变量一样使用它们,所以你也可以直接使用它们。

编辑:你必须小心,虽然。除非你小心地命名你的目标文件或使用不同的build dirs,否则运行make不同的“DEBUG”设置不会自动重新编译。

+0

你能澄清你的“编辑”吗?你的意思是说,如果你执行'DEBUG'的一个不同的值,但源文件没有改变,那么它将不会编译?对于我的下一个项目,我会找到一种使Makefile成为依赖的方法(或者其他的东西):D – Jeff

1

实现所需目标的一种方法是将CFLAGS的值从shell中传递到makefile。

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

为你调试版本,或

CFLAGS='-Wall -g' make -e 

用于非调试一个

+0

感谢Stephanie,看看如何在Makefile中设置'DEBUG'的值的其他答案 – Jeff

2

是的。

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

> gcc -DMYINT=8 foo.c 

与foo.c的

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

,并在你的makefile使用:

CFLAGS = -DMYINT=$(MYINT) 

and call make:

> make MYINT=8 
1

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

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

,如果你运行make时一样这样的: 让CFLAGS =“ - DDEBUG = 0”

此命令将分配与价值“-DDEBUG = 0” 的CFLAGS值分配的值将覆盖在生成文件指定的默认值

+0

谢谢,我用'?='来设置延迟,例如 'delay?= 0 CFLAGS = -DDELAY = $(delay)'(应该在“delay”和“CFAGS”之前有一个新行)。 – Jeff