2012-06-07 4 views
1

Makefile을 사용하여 라이브러리의 디버그 및 릴리스 버전을 빌드하고 해당 라이브러리를 관련 빌드 디렉토리에 복사하려고합니다.'all'에 여러 대상 만들기

.PHONY: all clean distclean 

all: $(program_NAME_DEBUG) 
    $(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG) 
    $(RM) $(program_NAME_DEBUG) 
    $(RM) $(program_OBJS) 
    $(program_NAME_RELEASE) 
    $(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE) 
    $(RM) $(program_NAME_RELEASE) 
    $(RM) $(program_OBJS) 

$(program_NAME_DEBUG): $(program_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(program_OBJS) -o $(program_NAME_DEBUG) 

$(program_NAME_RELEASE): $(program_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(program_OBJS) -o $(program_NAME_RELEASE) 

모든 (program_NAME_DEBUG)의 1 차 목표는 OK 컴파일하지만 2 일 (program_NAME_RELEASE는) 다음과 같은 오류 발생 : 그것은하지 않습니다 program_NAME_RELEASE

의 값이

libGlam_rel.so 
make: libGlam_rel.so: Command not found 
make: *** [all] Error 127 

libGlam_rel.so입니다 제 1 목표대로 제 2 목표를 인식하고있는 것처럼 보입니까?

편집은 마지막으로이 작업을 얻었다.

하나의 문제가 여러 개의 디렉토리에 src 파일이있는 경우 VPATH를 사용하여이를 분류합니다 (예 :

# specify dirs other then current dir to search for src files 
VPATH = ../../pulse_IO/src ../../../g2/src 

플랫폼 조건부 항목에 추가 라이브러리 타겟에 추가되었습니다.

DEBUG_OBJS := $(addprefix $(BUILD_DIR)/debug/,${program_OBJS}) 
RELEASE_OBJS := $(addprefix $(BUILD_DIR)/release/,${program_OBJS}) 

내 디버깅을 설정하고 해제 CFLAGS :

DEBUG_CFLAGS := -fPIC -g -Wall -DDEBUG=1 
RELEASE_CFLAGS := -fPIC -O2 -Wall -DDEBUG=0 

모든 디버그를 대조 및 공개 컴파일러 옵션 :

DEBUG_LINK.c := $(CC) $(DEBUG_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 
RELEASE_LINK.c := $(CC) $(RELEASE_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 
# Platform specific conditional compilation 
UNAME := $(shell uname) 

TARGET := Glam 

ifeq ($(UNAME), Linux) 
# LINUX version 
program_NAME := lib$(TARGET).so 
program_DEBUG_NAME := lib$(TARGET)_dbg.so 
program_RELEASE_NAME := lib$(TARGET)_rel.so 
BUILD_DIR = ../build/linux 
endif 

ifeq ($(UNAME), MINGW32_NT-6.1) 
# WINDOWS version 
program_NAME := lib$(TARGET).dll 
program_DEBUG_NAME := lib$(TARGET)_dbg.dll 
program_RELEASE_NAME := lib$(TARGET)_rel.dll 
BUILD_DIR = ../build/windows 
endif 

는 오브젝트 파일을 새로운 디버그를 추가 해제

광고 내 모든 규칙을 '모든'목표에 적용하십시오.

.PHONY: all clean 

all: $(program_DEBUG_NAME) $(program_RELEASE_NAME) 

규칙 세트는 다음과 같습니다 (inc. 암시 적 오브젝트 파일 생성을위한 대체) :

$(program_DEBUG_NAME): $(DEBUG_OBJS) 
    $(DEBUG_LINK.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/debug/[email protected] 

$(program_RELEASE_NAME): $(RELEASE_OBJS) 
    $(RELEASE_LINK.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/release/[email protected] 

# rule to build object files (replaces implicit rule) 
$(BUILD_DIR)/debug/%.o: %.c 
    $(DEBUG_LINK.c) $< -c -o [email protected] 

$(BUILD_DIR)/release/%.o: %.c 
    $(RELEASE_LINK.c) $< -c -o [email protected] 

나는 모든 새 파일을 다룰 깨끗한 수정 마무리 할 :

clean: 
    @- $(RM) $(BUILD_DIR)/debug/$(program_DEBUG_NAME) 
    @- $(RM) $(DEBUG_OBJS) 
    @- $(RM) $(BUILD_DIR)/release/$(program_RELEASE_NAME) 
    @- $(RM) $(RELEASE_OBJS) 

이 날 디버그를 생산하고 버전을 출시 할 수 있도록 작동 하나의 Makefile로 리눅스와 윈도우 플랫폼의 라이브러리 $ make -k

+0

이유는 무엇입니까? 여기서 vpath를 올바르게 사용하고 있다고 생각합니다. 즉 소스가 아닌 * 타겟을 검색하고 있습니까? – bph

+0

간단한 메이크 파일에 대한 괜찮아요. 프로젝트가 동일한 경로의 이름을 가진 파일을 가지고 시작하면 문제가 발생할 것입니다. – ThePosey

+0

아 - 그렇습니다. 잠재적 인 문제가 될 수 있습니다. – bph

답변

2

처음으로 먼저. 두 라이브러리에 대해 서로 다른 버전의 오브젝트 파일이 필요할 것 같지만,이 makefile에는 아무것도 제공되지 않습니다.

여러 가지 방법이 있습니다.

ang_debug.o 
    naur_debug.o 
    gul_debug.o 

    ang_rel.o 
    naur_rel.o 
    gul_rel.o 
RELEASE_OBJSDEBUG_OBJS에 대한

어느 쪽이든, 당신이 쓸 수있는 규칙 (우리가 도움이 될 수 있습니다 : 두 번째-깨끗한 다른 파일 이름을 가지고있다

debug_objs/ 
    ang.o 
    naur.o 
    gul.o 

release_objs/ 
    ang.o 
    naur.o 
    gul.o 

: 깨끗한 두 개의 디렉토리를 가지고 아마 필요한 경우).

지금 도서관 규칙을 보면 :

$(program_NAME_DEBUG): $(DEBUG_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(DEBUG_OBJS) -o $(program_NAME_DEBUG) 

$(program_NAME_RELEASE): $(RELEASE_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(RELEASE_OBJS) -o $(program_NAME_RELEASE) 

우리는 그들을 더 간결하게 Automatic Variables를 사용할 수 있습니다

$(program_NAME_DEBUG): $(DEBUG_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,[email protected] $^ -o [email protected] 

$(program_NAME_RELEASE): $(RELEASE_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,[email protected] $^ -o [email protected] 

(우리는 조금 더 멀리 이동하지만, 현실을 밀어하지 말자 수 있습니다.) all 지금

.

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE) 
    $(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG) 
    $(RM) $(program_NAME_DEBUG) 
    $(RM) $(DEBUG_OBJS) 
    $(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE) 
    $(RM) $(program_NAME_RELEASE) 
    $(RM) $(RELEASE_OBJS) 

을하지만 그들은 충돌 할 수 있기 때문에, 오브젝트 파일을 제거하고 그들이 중간 파일이라면 어쨌든 삭제됩니다 확인 할 이유가 없습니다 : 자신이 속한 곳 우리는 전제 조건 목록에 $(program_NAME_RELEASE) 이동합니다. 그리고 우리가 단지 mv 일 수있는 때 $(CP)와 그 다음 $(RM)의 어떤 필요도 없다. 그리고 mv은 필요 없습니다. 라이브러리가 속해있는 곳이 있다면, 우리는 처음에 그들을 거기를 구축 할 수 있습니다 :

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE) 

$(program_NAME_DEBUG): $(DEBUG_OBJS) 
    $(LINK_DEBUG.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/debug/[email protected] 

$(program_NAME_RELEASE): $(RELEASE_OBJS) 
    $(LINK_RELEASE.c) -shared -Wl,-soname,[email protected] $^ -o $(BUILD_DIR)/release/[email protected] 

편집 :
오브젝트 파일을 만들려면 (난 당신이 C를 사용하고 있는지 추측됩니다) :

OBJS:= ang.o naur.o gul.o 
DEBUG_OBJS := $(addprefix debug_objs/,$(OBJS)) 
RELEASE_OBJS := $(addprefix release_objs/,$(OBJS)) 

debug_objs/%.o: $(SOURCE_DIR)/%.c 
    $(CC) $(DEBUG_FLAGS) $< -o [email protected] 

release_objs/%.o: $(SOURCE_DIR)/%.c 
    $(CC) $(RELEASE_FLAGS) $< -o [email protected] 

(그냥 만들어 그 디렉토리 exist-- 당신도 그를 자동화 할 수 있습니다,하지만 당신은 하루 동안 충분히 변경하고 있는지 확인합니다.)

+0

이것은 멋지게 보입니다 - 내 혼란의 일부는 오브젝트 파일이 자동으로 만들어지고 내가 원하는 것을 원하지 않는다는 것입니다. , 나는 두 개의 dir, 디버그 및 릴리스 디렉토리에 해당 오브젝트 파일을 빌드하는 두 개의 대상을 갖고 싶습니다. 어떻게 수행 할 것입니까? – bph

+0

나는 간결함을 유지하면서 메이크 파일을 뚫을 수 없게 만들었습니다. – bph

+0

@Hiett, 저는 라이브러리 규칙의 개선을 생각했지만, 한번에 너무 많이 치고 싶지는 않습니다 ... – Beta

1

이 변경을 수행해야합니다

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE) 

그렇지 않으면, make all 오류 메시지가 당신을 말하고 무엇 인 $(program_NAME_RELEASE)를 만들기 위해 실패합니다.

+0

감사합니다.하지만 객체 파일의 제거가 올바른 순서로 이루어집니다. , 예. 라이브러리의 디버그 버전과 릴리스 버전을 빌드하는 사이에? – bph

+0

이것은 두 라이브러리가 모두 빌드 된 것처럼 작동하지만 동일한 객체 파일이 각 경우에 사용되므로 (즉, 빌드 사이에서 삭제되지 않음) 효과적으로 두 번 isn 라이브러리와 동일한 라이브러리를 구축하고 있으므로, 나는하려고 애쓴다. – bph

+0

나는 본다. Makefile은 까다로울 수 있으므로 이것을 생각해 봅시다. '$ (program_name_DEBUG) :'타겟은 분명히'libGlamdring_rel.so'을 빌드하지 않습니다. 그랬 으면 좋겠어? – thb

관련 문제