2016-07-04 2 views
0

나는 몇 가지 다른 프로그램을 만들기 위해 만들어진 Makefile을 가지고있다. 내 SOURCESOBJECTSPRODUCT에 따라 달라지며, 이는 제작되는 제품이어야합니다. 지금이 순간, 나는 각 규칙에 OBJECTS에 대한 종속성을 나열하기 전에 PRODUCT을 설정의존성 변수를 재평가하지 마라.

CORE_LIB := libcore 
SCANNER  := scanner 
FLETCHER := fletcher 

PRODUCT  := $(SCANNER) 

SOURCE_DIR := ./src 
BUILD_DIR := ./build 
OBJECTS_DIR := $(BUILD_DIR)/intermediate 
PRODUCT_DIR := $(BUILD_DIR)/product 


SOURCES  = $(wildcard $(SOURCE_DIR)/$(PRODUCT)/*.c) $(wildcard $(SOURCE_DIR)/$(PRODUCT)/*/*.c) 
OBJECTS  = $(SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o) 

# change PRODUCT based on rule being ran 

$(SCANNER): PRODUCT := $(SCANNER) 
$(SCANNER): $(OBJECTS) 
    # link stuff 

$(CORE_LIB): PRODUCT := $(CORE_LIB) 
$(CORE_LIB): $(OBJECTS) 
    # link stuff 

그러나 OBJECTS 킵은 PRODUCT이 설정되기 전에 평가되고,하고 규칙에 따라되지 변경됩니다 않았다. 제가 빠진 것이 있습니까?

답변

2

당신은 그렇게 할 수 없습니다. 는 GNU 대상 특정 변수에 대해 states 설명서를 만들 : 자동 변수와 마찬가지로

를,이 값은 대상의 조리법의 컨텍스트 내에서만 사용할 수 있습니다 (다른 목표 별 과제에서).

즉, $(OBJECTS)과 같이 필수 구성 요소를 확장하는 동안 대상 별 변수 값을 사용할 수 없습니다. 또는 변수를 사용할 수 있지만 대상 특정 값을 사용할 수 없습니다. PRODUCT의 값을 $(SCANNER) (scanner)으로 설정 했으므로이 값은 모든 선행 조건에서 사용될 값입니다.

여러 가지 옵션이 있습니다.

$(SCANNER)_SOURCES = $(wildcard $(SOURCE_DIR)/$(SCANNER)/*.c) $(wildcard $(SOURCE_DIR)/$(SCANNER)/*/*.c) 
$(CORE_LIB)_SOURCES = $(wildcard $(SOURCE_DIR)/$(CORE_LIB)/*.c) $(wildcard $(SOURCE_DIR)/$(CORE_LIB)/*/*.c) 

다음과 같은 규칙을 만들 : 당신은 다음과 같이 여러 변수를 정의 할 수 있습니다 당신이 더있는 경우

$(SCANNER): $($(SCANNER)_SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o) 
     # link stuff 
$(CORE_LIB): $($(CORE_LIB)_SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o) 
     # link stuff 

, 당신은 매크로를 작성하고 eval를 사용할 수 있지만 않을 것 당신이 정말로 그 (것)들의 낱단이 있기 위하여려고하고 않는 한 복잡성으로 성가시다.

대상을 단순화 할 수는 다음과 같이, Secondary Expansion를 사용하여 비트를 정의

OBJECTS = $$([email protected]_SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o) 

.SECONDEXPANSION: 
$(SCANNER): $(OBJECTS) 
     # link stuff 
$(CORE_LIB): $(OBJECTS) 
     # link stuff 
+0

가 대단히 감사합니다. 나는 2 차 확장 솔루션과 함께 가기로 결정했는데 완벽하게 작동합니다. – amyinorbit

관련 문제