1

1つのメインmakefileに含まれている2つのmakefileがあります。2番目のmakefileには、次のルールがあります。

$(MAKEFILE2_OBJS): CFLAGS += -fPIC

私が理解したように、このようなルールを作成すると、-fPICはMAKEFILE2_OBJSのCFLAGSにのみ追加されます。しかし、暗黙のルールを使用してMAKEFILE1_OBJSをコンパイルすると、CFLAGSには2番目の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)

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

$(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)/  > $@

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 $^ > $@ && 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」は出力「aaabbb」を生成します。これは、「all」ルールが実行されると、$(VAR)がその値を持つためです。

Makefileに他のファイルが含まれている場合、すべてが1つの大きなMakefileとして扱われます。

于 2012-07-24T17:23:03.833 に答える