2017-11-17 7 views
0

저는 다소 이상합니다. 알아 내는데 어려움을 겪습니다. 나는 몇몇 .cpp 파일들로 시작하는 C++ 프로젝트를 가지고 있으며 여러 애플리케이션에서 사용되는 여러 원격 디렉토리에서 일부 소스 파일을 컴파일해야한다. 이것은 이상적이지는 않지만, 이것은 내 dev 그룹이 사용하는 레거시 디렉토리/컴파일 구조입니다.Make : VPATH를 사용하여 다른 확장자의 파일을 컴파일하고 연결하십시오.

다른 프로젝트는이를 수행하기 위해 VPATH를 사용합니다. 그러나, 그들은 링크 된 필요한 객체의리스트를 하드 코딩하는 것을 끝내지 만,이 접근법은 나에게 우아하거나 융통성이없는 것처럼 보입니다. 나는 동적으로 컴파일하고 모든 것을 연결하려고합니다. 또 다른 잠재적 인 복잡성은 이러한 원격 VPATH 디렉토리 중 일부는 .cpp가 아닌 .c 확장자 (C++로 컴파일 됨)가있는 파일을 가지고 있다는 것입니다.

내 현재 솔루션 :

# Directory for object files 
OBJ_DIR = build 

CPPSRC := $(wildcard *.cpp) 
CSRC := $(wildcard *.c) 
OBJ := $(CSRC:%.c=$(OBJ_DIR)/%.o) $(CPPSRC:%.cpp=$(OBJ_DIR)/%.o) 

# Directory for output binaries 
BIN_DIR = bin 

# Name of binary executable 
OUTPUT = foo 

# VPATH allows you to specify other directories to search for prereqs in 
VPATH = /one/remote/dir /another/remote/dir 

# 'make all' 
all: $(BIN_DIR)/$(OUTPUT) 

# 'make clean' 
clean: 
    @rm -rf $(BIN_DIR) 
    @rm -rf $(OBJ_DIR) 

$(OBJ_DIR)/%.o: %.cpp 
    @mkdir -p $(OBJ_DIR) 
    $(CXX) -c $< -o [email protected] 

$(OBJ_DIR)/%.o: %.c 
    @mkdir -p $(OBJ_DIR) 
    $(CXX) -c $< -o [email protected] 

$(BIN_DIR)/$(OUTPUT): $(OBJ) 
    @mkdir -p $(BIN_DIR) 
    $(CXX) -g -ansi -Wall -Werror -o [email protected] $(OBJ) 

결과는 모든 컴파일 내 VPATH 디렉토리에있는 파일 제외에 연결됩니다 있다는 것입니다. 내 $ (OBJ) prereq가 평가되고 나면 결과 객체 자체가 소스 파일 인 VPATH에 위치하지 않기 때문일 수 있습니다.

제가 취할 수있는 더 좋은 방법이 있습니까? 다른 VPLS 디렉토리의 내용을 쉽게 변경할 수있는 능력이 없습니다. VPLS 디렉토리가 여러 다른 응용 프로그램에서 다른 소유자와 함께 사용되기 때문입니다. 보면

+0

MadScientist의 솔루션은 내가 필요한 것 이었지만, 그가 언급 한주의 사항은 앞으로 이런 종류의 문제에서 벗어날 수있게 해줄 것입니다 ... –

답변

2

: 첫 번째 줄은 말한다

CPPSRC := $(wildcard *.cpp) 
CSRC := $(wildcard *.c) 
OBJ := $(CSRC:%.c=$(OBJ_DIR)/%.o) $(CPPSRC:%.cpp=$(OBJ_DIR)/%.o) 

$(BIN_DIR)/$(OUTPUT): $(OBJ) 

는, 패턴 *.cpp 일치 나의 현재 디렉토리에있는 모든 파일을 얻을. 두 번째 라인은 패턴이 *.c과 일치하는 현재 디렉토리의 모든 파일을 가져옵니다. 세 번째 줄에는이 모든 소스 파일을 $(OBJ_DIR) 디렉토리의 개체 파일 이름으로 변환한다고 나와 있습니다.

마지막 줄에는 $(BIN_DIR)/$(OUTPUT)을 빌드 할 때 먼저 모든 해당 오브젝트 파일을 빌드해야합니다.

다른 곳에서 찾을 수있는 소스에 대한 객체 파일을 빌드해야한다고 (예 : /one/remote/dir 또는 /another/remote/dir)라고 말한 적이 없습니다. 그런데 왜 그것들을 만들어야합니까?

이러한 파일을 찾아서 개체 목록에 추가해야합니다.

이 같은 시도 할 수 : 다음 와일드 카드가 일치하는 모든 파일을 얻을 않습니다

VPATH = /one/remote/dir /another/remote/dir 
OBJ += $(patsubst %,$(OBJ_DIR)/%.o,$(notdir $(basename $(wildcard $(addsuffix /*.cpp,$(VPATH)) $(addsuffix /*.c,$(VPATH)))))) 

$(VPATH)의 각 디렉토리에 /*.cpp/*.c 접미사를 추가는 다음베이스 이름 (제거 걸리는 .cpp.c 접미사)를 입력 한 다음 디렉토리 경로를 제거한 다음 각 기본 파일 이름을 $(OBJ_DIR) 앞에 추가하고 .o을 끝에 추가합니다.

물론 시스템에 동일한 기본 이름을 가진 두 개의 파일이 있다면 운이 없으므로 디렉토리 구조를 유지하면서 더 복잡한 작업을 수행해야합니다.