2012-08-27 150 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