Make: Установка целевых переменных с разными целями - PullRequest
3 голосов
/ 18 марта 2011

Я создаю make-файл, который будет использоваться для создания целевой библиотеки выпуска или отладки. Я хочу поместить объект и автоматически сгенерированные файлы зависимостей в структуру каталога отладки или выпуска, в зависимости от запрошенной цели make-файла. Я не хочу указывать аргумент командной строки тестируемого make (т.е. DBG = 1), но предпочел бы запустить make -f Makefile или make -f Makefiel dbg для целей выпуска и отладки, соответственно. Получил эту часть вниз. Я понимаю, что не могу назначить специфическую для цели переменную, содержащую имя объекта dir (или release, или debug), который можно использовать как часть спецификации Target в правиле, как я делал в примере, показанном ниже. В этом примере OBJDIR является целевой переменной, которую я хотел бы установить в зависимости от цели сборки. По этой причине в этом примере $ (OBJDIR) пусто в целевом правиле $ (OBJDIR) /%. O. Любые рекомендации о том, как правильно выполнить предложенные шаги? (Показанный пример - это просто непроверенный пример копирования / вставки ... синтаксис не проверен ... на самом деле, я не могу правильно отобразить вкладки ... Я надеюсь получить некоторые идеи реализации). (Кроме того, $ (OBJDIR) не установлен в чистой цели, как показано ... так как он не входит в иерархию зависимостей dbg / all target ... мысли?) Заранее спасибо.

Makefile:

OBJS    := a.o b.o c.o  
SRCS    := $(OBJS:.o=.c)  

-- Set up the release and the debug directory paths and object filenames  
RELEASE_DIR := ./release  
RELEASE_OBJ := $(OBJS:%=$(RELEASE_DIR)/%)  
DEBUG_DIR   := ./debug  
DEBUG_OBJ   := $(OBJS:%=$(DEBUG_DIR)/%)  

.PHONY : all dbg 

all: CFLAGS = -O3  
all: OBJDIR := RELEASE_DIR  
all: df     := $(RELEASE_DIR)/$(*F)  
all: init_release lib1.so  

dbg: CFLAGS = -g -O0  
dbg: OBJDIR := DEBUG_DIR  
dbg: df     := $(DEBUG_DIR)/$(*F)  
dbg: init_debug lib1.so  

Lib1.so: $(OBJ)  

init_release:  
    -@mkdir -p $(RELEASE_DIR)  

init_debug:  
    -@mkdir -p $(DEBUG_DIR)  

lib1.so: $(OBJ)  
    @echo '--------------------------------------------------------------'
    @echo linking $@  
    @gcc -shared -o lib1.so $(OBJ)  

-Compile including advance dependancy generation alg, per Tom Tromey:
    # http://make.paulandlesley.org/autodep.html  
$(OBJDIR)/%.o: %.c  
    echo $@    
    echo $(OBJDIR)  
    echo compiling $@  
    $(COMPILE.c) -MD -o $@ $<  
    cp $(df).d $(df).P; \  
    sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \  
             -e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \  
    rm -f $(df)/$*.d  

# If the goal is "clean", don't include these to avoid trying to build them
ifneq($(MAKECMDGOALS),clean)  
-include $(SRCS:%.c=$(OBJDIR)/%.P)
endif  

clean:  
    -@rm -f    $(OBJDIR)/*.[Pdo] lib1.so  

Ответы [ 2 ]

4 голосов
/ 18 марта 2011

Целевые переменные могут быть хитрыми.Вместо этого используйте косвенное обращение.У Make есть много синтаксиса для сокращения стандартного текста..SECONDEXPANSION часто хорошо.Эскиз:

.SECONDEXPANSION:
${DEBUG_OBJ} ${RELEASE_OBJ}: $$(patsubst %.o,%.c,$${@F})
    gcc ${copts-${@D}} -c $< -o $@

Здесь мы говорим, что ./release/a.o зависит от a.c.Когда make решает собрать ./release/a.o, она расширяет строку оболочки.При этом ${@D} естественно release, поэтому make продолжает и расширяет ${copts-release}, что вы определите с пользой.

Аналогично, при создании ./debug/a.o make расширяет ${copts-debug}.

Обильное использование $(warning [blah]), $(error [blah blah]) и обязательное --warn-undefined-variables помогут вам получить это право.

1 голос
/ 18 марта 2011

Созданный вами Makefile недействителен, и он не будет генерировать ваши цели, как вы ожидаете.Например, вы не можете установить переменную CFLAGS в определениях целей all и dbg.

Единственное решение, которое я могу придумать, - это вызвать make с тем же Makefile, определяющим переменную DBGкак хотите.Например:

ifdef DBG
CFLAGS = -O0 -ggdb
OBJDIR = dbgdir
else
CFLAGS = -O2
OBJDIR = reldir
endif

all: $(OBJDIR)/target
    #Your commands here

dbg:
    $(MAKE) DBG=1

При этом, если вы позвоните make, у вас будет сборка релиза.Если вы звоните make dbg, у вас есть сборка релиза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...