2017-02-19 53 views
2

我有一個Makefile效果很好時,沒有靜態庫編譯:如何防止我的makefile文件重新鏈接由於靜態庫

CC    = g++ -std=c++11                                   

RM    = rm -f                                     

NAME   = hello                                                                                                        

SRCS   = Main.cpp \                                    
        srcs/Controller.cpp \ 
        ...                           
        srcs/Parser.cpp                                                                

OBJS   = $(SRCS:.cpp=.o)                                  

CPPFLAGS  += -W -Wall -Wextra -Werror                                

all  : $(NAME)                                      

$(NAME) : $(OBJS)                                      
      $(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(OBJS) -I./inc                           

clean :                                        
      $(RM) $(OBJS)                                                                       

fclean : clean                                       
      $(RM) $(NAME)                                     

re  : fclean all                                      

.PHONY : all clean fclean re 

這個Makefile作品,不重新鏈接(當我輸入兩次「make」,它不會重新編譯並輸出「沒有任何事情要做」)

但是當我想編譯一個靜態庫時,「make」命令重新編譯這個庫而不輸出「Nothing to be done for全部「,這裏是包含靜態庫的新Makefile:

CC    = g++ -std=c++11                                   

RM    = rm -f                                     

NAME   = hello                                   

LIBNAME   = libhello.a                                  

SRCS   = srcs/Controller.cpp \ 
        ...                                 
        srcs/Parser.cpp                                

OBJS   = $(SRCS:.cpp=.o)                                  

CPPFLAGS  += -W -Wall -Wextra -Werror                                

all  : $(NAME)                                      

$(NAME) : $(OBJS)                                      
      ar rc $(LIBNAME) $(OBJS) 
      $(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(LIBNAME) Main.cpp -I./inc                                                                

clean :                                        
      $(RM) $(OBJS)                                     
      $(RM) $(LIBNAME)                                    

fclean : clean                                       
      $(RM) $(NAME)                                     

re  : fclean all                                      

.PHONY : all clean fclean re  

我該如何解決這個問題,以防止生成文件重新編譯,當靜態庫已編譯,不需要重新編譯?

非常感謝您

回答

1

$(NAME) : $(OBJS)                                      
     $(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(OBJS) -I./inc 

它期望默認的編譯語句將用於生成目標文件,make將在執行規則之前生成這些目標文件。並且由於它在此配方中沒有執行任何編譯,參數-I./inc不需要。

如果沒有在依賴關係中列出頭文件,更改頭文件將無法重新編譯關聯的源文件。

推薦:

HEADERS := .. 

$(name): $(OBJS) 
<tab> $(CC) -o [email protected] $(OBJS) $(LFLAGS) 

%.o:%.cpp $(HEADERS) 
<tab> $(CC) $(CPPFLAGS) -c $< -o [email protected] -I./inc 

注意在該行:

CPPFLAGS  += -W -Wall -Wextra -Werror 

-W關閉所有先前打開了警告,可能不是你想要的東西,建議刪除該參數。

類似的考慮需要在創建靜態庫,類似時應用:

這一行:

$(NAME) : $(OBJS)                                      
     ar rc $(LIBNAME) $(OBJS) 
     $(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(LIBNAME) Main.cpp -I./inc 

變爲:

HEADER := ... 

all: $(LIBNAME) $(NAME) 

$(LIBNAME): $(OBJS) 
<tab> ar rc -o [email protected] $^ 

%.o:%.cpp 
<tab> $(CC) $(CPPFLAGS) -c $< -o [email protected] -I./inc 

$(NAME): main.o $(LIBNAME) 
<tab> $(CC) $< -o [email protected] $(LFLAGS) -l$(LIBNAME) 
+0

感謝了很多關於你的答案和你的筆記關於-W國旗! – void

0

問題是$NAME是假目標,由於這條規則:

all  : $(NAME) 

我認爲這個問題可以通過,而不是將其更改爲一個實際的目標來解決:

all  : $(LIBNAME) 

而且,你有這樣的規則:

$(NAME) : $(OBJS) 
     ar rc $(LIBNAME) $(OBJS) 
     $(CC) $(CPPFLAGS) $(CFLAGS) -o $(NAME) $(LIBNAME) Main.cpp -I./inc 

這有點令人困惑:該庫構建爲$LIBNAME,但後來它連接了一個名爲$NAME的可執行文件。因此,每次您對Main.cpp進行更改時,圖書館都必須重建。

0

對於$(NAME),您的規則實際上並沒有生成一個名爲$(NAME)(即hello)的文件,因此make會每次都嘗試重新制作。配方必須與規則相匹配(這就是爲什麼你應該使用自動變量,如下面最後一個例子):

all: $(LIBNAME) 
$(LIBNAME): $(OBJS) 
    ar rc $(LIBNAME) $(OBJS) 

GNU做也有內置的歸檔功能,雖然它不具有並行發揮好令:

ARFLAGS := rc 
all: $(LIBNAME)($(OBJS)) 

更地道,並行安全的方式將是關於這個食譜是這樣

ARFLAGS := rc 
.PHONY: all 
all: $(LIBNAME) 
$(LIBNAME): $(OBJS) 
    $(AR) $(ARFLAGS) [email protected] $^