1

我有两个makefile,它们包含在一个主makefile中。在第二个 makefile 中有以下规则:

$(MAKEFILE2_OBJS): CFLAGS += -fPIC

据我了解,当我编写这样的规则时,-fPIC 将仅针对 MAKEFILE2_OBJS 添加到 CFLAGS。但是当我使用隐式规则编译 MAKEFILE1_OBJS 时,CFLAGS 具有来自第二个 makefile 的 -fPIC 标志。

为什么会这样?

主要生成文件:

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 > $@

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

生成文件1:

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 $^) $< > $@

$(DIR)/original-definitions: $(DIR)/arora-original $(DIR)/extract-definitions.sh
    $(lastword $^) $< > $@

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

$(DIR)/arora-main-overwritten: $(DIR)/arora-original $(DIR)/stage1_main.bin
    dd if=$< of=$@ 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=$< of=$@ 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=$< of=$@ 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 $^ $@

$(DIR)/stage1_exec.bin: $(DIR)/stage1.elf
    objcopy -j .arora_exec_free_space -O binary $^ $@ 

$(DIR)/stage1_data.bin: $(DIR)/stage1.elf
    objcopy -j .arora_data_free_space -O binary $^ $@

$(DIR)/stage1.elf: $(STAGE1_OBJS) utils/libpluginutils.a $(DIR)/linker_script.lds
    $(LD) $(STAGE1_OBJS) utils/libpluginutils.a -o $@ $(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)/  > $@

生成文件2:

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 $^ > $@ && chmod +x $@

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

$(STAGE2_OBJS): CFLAGS += -fPIC

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

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

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

$(DIR)/overwritten/main-overwritten.h: $(DIR)/overwritten/main-overwritten.o $(DIR)/create_objcopy_header.sh
    $(lastword $^) $< > $@

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

$(DIR)/overwritten/data-free-space-overwritten.h: $(DIR)/overwritten/data-free-space-overwritten.o $(DIR)/create_objcopy_header.sh
    $(lastword $^) $< > $@
4

1 回答 1

1

GNU make 在开始评估规则之前将整个 Makefile(以及所有包含的 Makefile)读入内存。规则命令中的变量在规则执行时展开,而不是在读取时展开。请参见以下示例:

VAR = aaa

all:
    @echo $(VAR)

VAR += bbb

“make”产生输出“aaa bbb”,因为当执行“all”规则时,$(VAR) 具有该值。

如果 Makefile 包含其他文件,则所有内容都被视为一个大 Makefile。

于 2012-07-24T17:23:03.833 回答