2015-09-04 85 views
0

在爲源代碼樹編寫Makefile文件時需要幫助。 我已經試過了Makefile的簡單例子,那些工作正常。但無法弄清楚如何爲以下類型的源代碼樹編寫Makefile。C源代碼樹的Makefile文件

我安排我的代碼如下

root_dir: 

    Makefile 

    component1: 
     dir1: 
      file1.c file1.h 
     dir2: 
      file2.c file2.h 
     dir3: 
      file3.c file3.h 

    component2: 
     dir4: 
      file4.c file4.h 
     dir5: 
      file5.c file5.h 

    common: 
     debug.c debug.h 
     utils.c utils.h 
     main.c main.h 

這裏,main.c中使用的debug.h,utils.h,file1.h和file4.h宣佈某些功能。這些file1.c和file4.c使用debug.h和utils.h。我已經開始編寫如下的Makefile規則。

CC=gcc 
CFlags=-c -g3 -Wall 

myexec: main.o 
     $(CC) main.o -o myexec 

main.o: common/main.c common/main.h common/utils.h 
     $(CC) $(CFLAGS) common/main.c 

此Makefile給utils.h中聲明的函數提供「未定義引用」錯誤消息。它可以關於在debug.h,file1.h或file4.h中聲明的函數,但不應該從utils.h提供函數的錯誤消息。

請幫我找出哪裏出了什麼問題Makefile在這裏。

+2

'make'不是一個給你未定義的引用錯誤;它是'gcc'。你在哪裏_define_ utils.h中的函數? –

+0

所有的定義都在各自的.c文件中。函數gcc給出的錯誤在utils.c中定義,並在utils.h中聲明以供其他文件使用。 – Peeyushpd

+1

你的makefile只編譯'common/main.c';你不會在任何地方編譯'utils.c'。 –

回答

2

首先,讓我們修正main.o規則:

main.o: common/main.c common/main.h common/utils.h 
    $(CC) $(CFLAGS) common/main.c 

如果像你說的main.c uses some functions declared in debug.h, utils.h, file1.h and file4.h,那麼這些標題應該是規則的先決條件(因此,如果您修改一個頭,使將重建main.o):

main.o: common/main.c common/main.h common/debug.h common/utils.h component1/dir1/file1.h component2/dir4/file4.h 
    $(CC) $(CFLAGS) common/main.c 

現在來看看myexec規則:

myexec: main.o 
    $(CC) main.o -o myexec 

毫無疑問,你會得到「未定義的參考」錯誤; debug.h聲明的功能,utils.hfile1.hfile4.h是定義在(I假定)debug.cutils.cfile1.cfile4.c和,其中該生成文件從未提及。 直到你明白這一點,才能繼續。

來處理,這是壽有myexec規則鏈接所有相關的目標文件的方式:

myexec: main.o debug.o utils.o file1.o file4.o 
    $(CC) main.o debug.o utils.o file1.o file4.o -o myexec 

當然,你必須有debug.outils.ofile1.ofile4.o,類似於一個規則main.o

一旦做到這一點,你有工作,但不必要地長,多餘的makefile文件。 「有效但粗糙」。它可以做得更短,更優雅,但這個答案越來越長;讓它工作,然後我們可以努力使它更清潔。

+0

謝謝測試版。我對目標的依賴關係做了錯誤的處理。能夠解決這個問題。 – Peeyushpd

0

這裏是一個長期的例子:它是一個Linux的嵌入式系統,但將與您的應用程序只有輕微的變化工作

這兩個makefile文件將在每個子目錄

創建一個可執行它有一個目錄樹類似如下:makefile.mak的

top 
    utility .h and .c files 
    makefile.top 
    makefile.bot 
    /executable1 
     exec1 .h and .c files 
    /executable2 
     exec2 .h and .c files 

內容

SHELL = /bin/sh 


# note: this makefile.mak needs to be run from the ./src directory 
# of the GOT4 directory tree 


SRC := $(wildcard *.c) 
OBJ := $(SRC:.c=.o) 
DEP := $(SRC:.c=.d) 
INC := $(SRC:.c=.h) 


MAKE := /usr/bin/make 

CC  := /usr/bin/gcc 

CP  := cp 

MV  := mv 

LDFLAGS := -L/usr/local/lib -L/usr/lib -L/lib 

DEBUG := -ggdb3 

CCFLAGS := $(DEBUG) -Wall -Wextra -pedantic 

#CPPFLAGS += =MD 

LIBS := -lssl -ldl -lrt -lz -lc -lm 



.PHONY: AllDirectories 


AllDirectories := \ 
    executable1 \ 
    executable2 



.PHONY: all 

all: $(OBJ) $(AllDirectories) 
    $(foreach d,$(AllDirectories), \ 
    (cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d all);) 



# 
# create dependancy files 
# 
%.d: %.c 
    # 
    # ========= START $< TO [email protected] ========= 
    $(CC) -M $(CPPFLAGS) $< > [email protected]$$$$;      \ 
    sed 's,\($*\)\.o[ :]*,\1.o [email protected] : ,g' < [email protected]$$$$ > [email protected];  \ 
    rm -f [email protected]$$$$ 
    # ========= END $< TO [email protected] ========= 



# 
# compile the .c file into .o files using the compiler flags 
# 
%.o: %.c %.d 
    # 
    # ========= START $< TO [email protected] ========= 
    $(CC) $(CCFLAGS) -c $< -o [email protected] -I. 
    # ========= END $< TO [email protected] ========= 
    # 



.PHONY: clean 
#clean: $(AllDirectories) 
# # ========== start clean activities ========== 
# rm -f *.o 
# rm -f $(name).map 
# rm -f $(name) 
# rm -f *.d 
# $(foreach d,$(AllDirectories), \ 
# (cd $d && $(MAKE) -f makefile.mak clean);) 
# # ========== end clean activities ========== 

clean: $(AllDirectories) 
    # ========== start clean activities ========== 
    rm -f *.o 
    rm -f $(name).map 
    rm -f $(name) 
    rm -f *.d 
    rm -f ../bin/Tsk_* 
    $(foreach d,$(AllDirectories), \ 
    (cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d clean);) 
    # ========== end clean activities ========== 



.PHONY: install 
#install: $(AllDirectories) 
# # ========== start install activities ========== 
# $(foreach d,$(AllDirectories), \ 
# (cd $d && $(MAKE) -f makefile.mak clean);) 
# # ========== end install activities ========== 

install: $(AllDirectories) 
    # ========== start install activities ========== 
    $(foreach d,$(AllDirectories), \ 
    (cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d install);) 
    # ========== end install activities ========== 



# include the contents of all the .d files 
# note: the .d files contain: 
# <filename>.o:<filename>.c plus all the dependancies for that file 
# I.E. the #include'd header files 
# wrap with ifneg... so will not rebuild *.d files when goal is 'clean' 
# 
ifneq "$(MAKECMDGOALS)" "clean" 
-include $(DEP) 
endif 

和makefile.bot

SHELL = /bin/sh 


BINDIR := /home/user/bin 


.PHONY: all 
all : $(BINDIR)/$(name) ../makefile.mak ../makefile.bot 


# 
# macro of all *.c files 
# (NOTE: 
# (the following 'wildcard' will pick up ALL .c files 
# (like FileHeader.c and FunctionHeader.c 
# (which should not be part of the build 
# (so be sure no unwanted .c files in directory 
# (or change the extension 
# 
SRC := $(wildcard *.c) 
OBJ := $(SRC:.c=.o) 
DEP := $(SRC:.c=.d) 
INC := $(SRC:.c=.h) 


COMMON_OBJ := $(wildcard ../*.o) 
#COMMON_SRC := $(wildcard ../*.c) 
#COMMON_OBJ := $(COMMON_SRC:.c=.o) 
#COMMON_DEP := $(COMMON_SRC:.c=.d) 
#COMMON_INC := $(COMMON_SRC:.c=.h) 

MAKE := /usr/bin/make 

CC  := /usr/bin/gcc 

CP  := cp 

MV  := mv 

LDFLAGS := -L/usr/local/lib 

DEBUG := -ggdb3 

CCFLAGS := $(DEBUG) -Wall -Wextra -pedantic -std=c99 

#CPPFLAGS += =MD 

LIBS := -lssl -ldl -lrt -lz -lc -lm 



# 
# link the .o files into the executable 
# using the linker flags 
# -- explicit rule 
# 
$(name): $(OBJ) $(COMMON_OBJ) ../makefile.mak ../makefile.bot 
    # 
    # ======= $(name) Link Start ========= 
    $(CC) $(LDFLAGS) -o [email protected] $(OBJ) $(COMMON_OBJ) $(LIBS) 
    # ======= $(name) Link Done ========== 
    # 



# note: 
# using MV rather than CP results in all executables being re-made everytime 
$(BINDIR)/$(name): $(name) 
    # 
    # ======= $(name) Copy Start ========= 
    sudo $(CP) $(name) $(BINDIR)/. 
    # ======= $(name) Copy Done ========== 
    # 



# 
#create dependancy files -- inference rule 
# list makefile.mak as dependancy so changing makfile forces rebuild 
# 
%.d: %.c 
    # 
    # ========= START $< TO [email protected] ========= 
    $(CC) -M $(CPPFLAGS) $< > [email protected]$$$$;      \ 
    sed 's,\($*\)\.o[ :]*,\1.o [email protected] : ,g' < [email protected]$$$$ > [email protected];  \ 
    rm -f [email protected]$$$$ 
    # ========= END $< TO [email protected] ========= 



# 
# compile the .c file into .o files using the compiler flags 
# -- inference rule 
# 
%.o: %.c %.d 
    # 
    # ========= START $< TO [email protected] ========= 
    $(CC) $(CCFLAGS) -c $< -o [email protected] -I. 
    # ========= END $< TO [email protected] ========= 
    # 



.PHONY: clean 
clean: 
    # ========== CLEANING UP ========== 
    rm -f *.o 
    rm -f $(name).map 
    rm -f $(name) 
    rm -f *.d 
    # ========== DONE ========== 



.PHONY: install 
install: all 

# include the contents of all the .d files 
# note: the .d files contain: 
# <filename>.o:<filename>.c plus all the dependancies for that .c file 
# I.E. the #include'd header files 
# wrap with ifneg... so will not rebuild *.d files when goal is 'clean' 
# 
ifneq "$(MAKECMDGOALS)" "clean" 
-include $(DEP) 
endif