2012-07-01 2 views
1

У меня есть два make-файла, которые включены в один основной make-файл. Во втором Makefile есть следующее правило:Переменная утечка в Makefile

$(MAKEFILE2_OBJS): CFLAGS += -fPIC 

Как я понял, когда я пишу правило, как этот -fPIC будет добавлен в CFLAGS только для MAKEFILE2_OBJS. Но когда я компилирую MAKEFILE1_OBJS с неявным правилом, CFLAGS имеет флаг -fPIC из второго make-файла.

Почему это происходит?

Главная Makefile:

CC := gcc 
LD := gcc 
AS := nasm 
DEPEND := ./depend.sh 

CFLAGS += -Wall -Werror -I. -g -DNDEBUG -masm=intel 
ASFLAGS += -f elf64 
LDFLAGS += 

TARGET := arora 
MODULES := utils stage1 stage2 

all: $(TARGET) 

$(TARGET): stage1/arora-stage1 stage2/arora-stage2 

SRCS := 
ERROR_FILES := 
OBJS := 
DEPS := 
OUTPUTS := 

include $(wildcard $(patsubst %,%/*.mk,$(MODULES))) 

OBJS += $(SRCS:.c=.o) 
DEPS += $(SRCS:.c=.d) 
OUTPUTS += $(OBJS) $(DEPS) $(TARGET) 

include $(DEPS) 

%.d: %.c 
    $(DEPEND) `dirname $*` $(CFLAGS) $*.c > [email protected] 

.PHONY: clean 
clean: 
    rm -f $(OUTPUTS) 

Makefile1:

STAGE1_ASM_SRCS := $(wildcard $(DIR)/*/*.s) 
STAGE1_ASM_OBJS := $(STAGE1_ASM_SRCS:.s=.o) 

STAGE1_C_SRCS := $(wildcard $(DIR)/*/*.c) 
STAGE1_C_OBJS := $(STAGE1_C_SRCS:.c=.o) 
STAGE1_C_DEPS := $(STAGE1_C_OBJS:.o=.d) 
STAGE1_SRCS := $(STAGE1_ASM_SRCS) $(STAGE1_C_SRCS) 
STAGE1_OBJS := $(STAGE1_ASM_OBJS) $(STAGE1_C_OBJS) 

SRCS += $(STAGE1_C_SRCS) 
ERROR_FILES += $(wildcard $(DIR)/*/*_errors.hx) 
OUTPUTS += $(patsubst %,$(DIR)/%, linker_script.lds stage1.elf stage1_exec.bin stage1_data.bin stage1_main.bin arora-main-overwritten arora-exec-free-space-overwritten arora-stage1 original-definitions original-definitions.h) $(STAGE1_ASM_OBJS) 

STAGE1_INCLUDE_PATH := $(DIR) 

$(STAGE1_C_OBJS) $(STAGE1_C_DEPS): CFLAGS += -fno-stack-protector -nostdlib -I$(STAGE1_INCLUDE_PATH) 

# hack 
include $(DIR)/original-definitions 

.PHONY: $(DIR)/stage1 
$(DIR)/stage1: $(DIR)/arora-stage1 $(DIR)/arora-main-overwritten $(DIR)/arora-exec-free-space-overwritten $(DIR)/original-definitions $(DIR)/original-definitions.h 

$(DIR)/original-definitions.h: $(DIR)/original-definitions $(DIR)/create_original_definitions_header.sh 
    $(lastword $^) $< > [email protected] 

$(DIR)/original-definitions: $(DIR)/arora-original $(DIR)/extract-definitions.sh 
    $(lastword $^) $< > [email protected] 

$(DIR)/arora-stage1: $(DIR)/stage1_main.bin $(DIR)/stage1_exec.bin $(DIR)/stage1_data.bin $(DIR)/arora-original 
    cat $(lastword $^) > [email protected] && dd if=$< [email protected] bs=c seek=$(ARORA_MAIN_FILE_OFFSET) conv=notrunc && dd if=$(word 2, $^) [email protected] bs=c seek=$(ARORA_EXEC_FREE_SPACE_FILE_OFFSET) conv=notrunc && dd if=$(word 3, $^) [email protected] bs=c seek=$$(($(ARORA_EXEC_FREE_SPACE_FILE_OFFSET) + $$(wc -c $(word 2, $^) | awk '{print $$1}'))) conv=notrunc && chmod +x [email protected] 

$(DIR)/arora-main-overwritten: $(DIR)/arora-original $(DIR)/stage1_main.bin 
    dd if=$< [email protected] bs=c skip=$(ARORA_MAIN_FILE_OFFSET) count=$$(wc -c $(lastword $^) | awk '{print $$1}') 

$(DIR)/arora-exec-free-space-overwritten: $(DIR)/arora-original $(DIR)/stage1_exec.bin 
    dd if=$< [email protected] bs=c skip=$(ARORA_EXEC_FREE_SPACE_FILE_OFFSET) count=$$(wc -c $(lastword $^) | awk '{print $$1}') 

$(DIR)/arora-data-free-space-overwritten: $(DIR)/arora-original $(DIR)/stage1_exec.bin $(DIR)/stage1_data.bin 
    dd if=$< [email protected] bs=c skip=$$(($(ARORA_EXEC_FREE_SPACE_FILE_OFFSET) + $$(wc -c $(word 2, $^) | awk '{print $$1}'))) count=$$(wc -c $(lastword $^) | awk '{print $$1}') 

$(DIR)/stage1_main.bin: $(DIR)/stage1.elf 
    objcopy -j .arora_main -O binary $^ [email protected] 

$(DIR)/stage1_exec.bin: $(DIR)/stage1.elf 
    objcopy -j .arora_exec_free_space -O binary $^ [email protected] 

$(DIR)/stage1_data.bin: $(DIR)/stage1.elf 
    objcopy -j .arora_data_free_space -O binary $^ [email protected] 

$(DIR)/stage1.elf: $(STAGE1_OBJS) utils/libpluginutils.a $(DIR)/linker_script.lds 
    $(LD) $(STAGE1_OBJS) utils/libpluginutils.a -o [email protected] $(LDFLAGS) -ldl -nostdlib -T $(lastword $^) 

$(DIR)/linker_script.lds: $(DIR)/linker_script.lds.template 
    echo stage1_main will be at $(ARORA_MAIN_ADDRESS), the exec will be at $(ARORA_EXEC_FREE_SPACE_ADDRESS), the data will be after the exec. && sed s/ARORA_MAIN_ADDRESS/$(ARORA_MAIN_ADDRESS)/ $^ | sed s/ARORA_EXEC_FREE_SPACE_ADDRESS/$(ARORA_EXEC_FREE_SPACE_ADDRESS)/ | sed s/ARORA_DATA_LOADING_FREE_SPACE_ADDRESS/$(ARORA_DATA_LOADING_FREE_SPACE_ADDRESS)/ > [email protected] 

Makefile2:

DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) 

STAGE2_SRCS := $(wildcard $(DIR)/*/*.c) 
STAGE2_OBJS := $(STAGE2_SRCS:.c=.o) $(DIR)/overwritten/main-overwritten.o $(DIR)/overwritten/exec-free-space-overwritten.o $(patsubst %.s, %.o, $(wildcard $(DIR)/*/*.s)) 
STAGE2_DEPS := $(STAGE2_OBJS:.o=.d) 

SRCS += $(STAGE2_SRCS) 
ERROR_FILES += $(DIR)/stage2_errors.hx 

OBJS += $(DIR)/overwritten/main-overwritten.o $(DIR)/overwritten/exec-free-space-overwritten.o 
OUTPUTS += $(DIR)/stage2.so $(DIR)/overwritten/exec-free-space-overwritten.h $(DIR)/overwritten/main-overwritten.h $(DIR)/arora-stage2 

.PHONY: $(DIR)/stage2 
$(DIR)/stage2: $(DIR)/arora-stage2 

$(DIR)/arora-stage2: stage1/arora-stage1 $(DIR)/stage2.so 
    cat $^ > [email protected] && chmod +x [email protected] 

$(DIR)/stage2.so: LDFLAGS += -shared 
$(DIR)/stage2.so: $(STAGE2_OBJS) utils/libpluginutils.a 
    $(LD) $(LDFLAGS) $^ -o [email protected] 

$(STAGE2_OBJS): CFLAGS += -fPIC 

$(DIR)/overwritten/main-overwritten.o: stage1/arora-main-overwritten 
    objcopy -F elf64-x86-64 -B i386 -I binary $^ [email protected] 

$(DIR)/overwritten/exec-free-space-overwritten.o: stage1/arora-exec-free-space-overwritten 
    objcopy -F elf64-x86-64 -B i386 -I binary $^ [email protected] 

$(DIR)/overwritten/data-free-space-overwritten.o: stage1/arora-data-free-space-overwritten 
    objcopy -F elf64-x86-64 -B i386 -I binary $^ [email protected] 

$(DIR)/overwritten/main-overwritten.h: $(DIR)/overwritten/main-overwritten.o $(DIR)/create_objcopy_header.sh 
    $(lastword $^) $< > [email protected] 

$(DIR)/overwritten/exec-free-space-overwritten.h: $(DIR)/overwritten/exec-free-space-overwritten.o $(DIR)/create_objcopy_header.sh 
    $(lastword $^) $< > [email protected] 

$(DIR)/overwritten/data-free-space-overwritten.h: $(DIR)/overwritten/data-free-space-overwritten.o $(DIR)/create_objcopy_header.sh 
    $(lastword $^) $< > [email protected] 
+0

Это странно. Можете ли вы дать нам минимальный полный файл makefile, который дает такое поведение? То есть, можете ли вы сбрасывать свои файлы, вырезать столько, сколько сможете, сохраняя при этом такое поведение и отправляя то, что осталось? – Beta

+0

Это не минимальный make-файл, который иллюстрирует проблему; по меньшей мере 50% материала в нем является излишним для минимального воспроизведения. (Например, обработка зависимостей не минимальна или, если это так, нужно объяснить, почему крайне важно воспроизвести проблему, и вам нужно будет показать содержимое кода обработки зависимостей.) Также вам нужно показать два файла: основной файл makefile и один файл. Мы не можем бояться того, что вы делаете. –

+0

Главная make - http://pastebin.com/zhyVwHJc Сделать 1 -http: //pastebin.com/BtuBTEM6 Сделать 2 - http://pastebin.com/LgMwgFPn – Jah

ответ

1

GNU Make читает весь файл сборки (и все включено Makefiles) в память перед началом оценки правила. Переменные в командах правила расширяются, когда правило выполняется, а не когда оно считывается. Смотрите следующий пример:

VAR = aaa 

all: 
    @echo $(VAR) 

VAR += bbb 

«делают» производит выход «ааа БББ», потому что, когда «все» правило выполняется, $ (VAR) имеет это значение.

Если Makefile содержит другие файлы, все рассматривается как один большой Makefile.

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