2017-02-19 22 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» перекомпилирует библиотеку без вывода «Ничего не нужно делать для все », вот новый файл Makefile, содержащий статический lib:

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  

Как я могу исправить эту проблему, чтобы предотвратить перекомпилирование make-файла, когда статическая библиотека уже скомпилирована и не нуждается в повторной компиляции?

Большое спасибо

ответ

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] $^ 

 Смежные вопросы

  • Нет связанных вопросов^_^