2016-10-04 2 views
1

나는 Ada의 프로젝트에서 일하고 있으며 사용자 정의 makefile을 원합니다 (결국 c 및 python과 인터페이스하고 makefile 구문에 익숙하며 gnatmake 프로젝트 구문에 익숙하지 않으므로). 나는 커스텀 컴파일을 망쳐 놓았고, 제대로 작동한다고 생각했지만, 적어도 똑같은 커맨드 라인 실행이 바인딩 단계에서 문제가된다.Ada Makefile 바인딩 문제

나는 오프 - 바이 - 원 디렉토리 오류가 있거나, 복잡하거나 이상한 것으로 생각합니다.

어쨌든, 내 프로젝트는 현재 3 개의 소스 디렉토리를 포함하고 있습니다. 모델에 'logic'이 포함되어 있으며 util에는 일반적인 유틸리티가 들어 있으며 test에는 패키지되지 않은 'main'절차가 포함되어 있습니다. 결국에는 src 디렉토리에 'main'프로 시저가 있습니다. ASCII 그림 :

.PHONY: clean test 

MAKE=gnatmake 
INCLUDE_DIRS=-Imodel -Iutil -Itest 
GNATMAKEFLAGS=-g -fprofile-arcs -ftest-coverage --GNATLINK="gnatlink -v" --GNATBIND="gnatbind -v" 
GCCFLAGS=-g -fprofile-arcs -ftest-coverage 
OBJDIR=../obj 
BINDFLAGS=-a0$(OBJDIR) 

PLAYER_TEST_EXE=../bin/player_test.out 

test : $(PLAYER_TEST_EXE) 

$(PLAYER_TEST_EXE) : test/player_test.adb 
    gnatmake $< -D $(OBJDIR) $(INCLUDE_DIRS) -o [email protected] $(GNATMAKEFLAGS) 

clean : 
    @rm -rf $(OBJDIR)/* $(PLAYER_TEST_EXE) b~* 

문제는이 작업 디렉토리에있는 그 b~* 파일을 생성하는 때마다 디버그 플래그 :

project 
    \- bin 
     \- test 
      \- ....out 
     \- other_dirs_coming_soon 
      \- ....out 
     \- ....out 
    \- obj 
     \- all the mess that ada compilation makes 
     \- including .o, .ali, and b~whatever.ad(b/s) 
    \- src 
     \- model 
      \- ....ad(b/s) 
     \- util 
      \- ....ad(b/s) 
     \- ... 

나는 내가 원하는 것을 매우 가까웠다는 '기본'메이크 시도 통과된다. 많은 실행 파일을 갖고 자 할 때 이것은 작업 디렉토리를 심각하게 오염시킬 것입니다. 이와 같이

나는 메이크 단계별를 열고 껍질을 벗겨로 끝났다는 바인딩에 도달 할 때를 제외하고, 정말 가까이 될 것으로 보인다

.PHONY: clean test 

GCC=gcc 
BINDER=gnatbind 

ADALIBLOC=`gnatls -v | grep adalib` 

FLAGS= 
LINKFLAGS=-gnatA -gnatWb -gnatiw -gnatws 

test: FLAGS+=-g -fprofile-arcs -ftest-coverage 
test: LINKFLAGS+=-g 

# Where to put the object files and ali extensions 
OBJDIR=../obj 

# Source directories 
MODEL_DIR=model 
UTIL_DIR=util 
TEST_DIR=test 

SRC_DIRS=$(MODEL_DIR) $(UTIL_DIR) $(TEST_DIR) 
INC_DIRS=${SRC_DIRS:%=-I%} 
LIB_DIRS=${SRC_DIRS:%=-L%} 
BIND_DIRS=${SRC_DIRS:%=-aO./%} 

# Model sources 
MODEL_SPECS=$(wildcard $(MODEL_DIR)/*.ads) 
MODEL_BODIES=$(wildcard $(MODEL_DIR)/*.adb) 
MODEL_OBJECTS=$(patsubst %.ads,$(OBJDIR)/%.o,$(MODEL_SPECS)) 
MODEL_ALI=$(patsubst %.ads,$(OBJDIR)/%.ali,$(MODEL_SPECS)) 

# Util sources 
UTIL_SPECS=$(wildcard $(UTIL_DIR)/*.ads) 
UTIL_BODIES=$(wildcard $(UTIL_DIR)/*.adb) 
UTIL_OBJECTS=$(patsubst %.ads,$(OBJDIR)/%.o,$(UTIL_SPECS)) 
UTIL_ALI=$(patsubst %.ads,$(OBJDIR)/%.ali,$(UTIL_SPECS)) 

# All sources 
ALL_SPECS=$(MODEL_SPECS) $(UTIL_SPECS) 
ALL_BODIES=$(MODEL_BODIES) $(UTIL_BODIES) 
ALL_OBJECTS=$(MODEL_OBJECTS) $(UTIL_OBJECTS) 
ALL_ALIS=$(MODEL_ALI) $(UTIL_ALI) 

# Executables 
EXE_DIR=../bin 
PLAYER_TEST_EXE=$(EXE_DIR)/test/player_test.out 

# Targets 
test : $(PLAYER_TEST_EXE) 

# Executable creation 
$(EXE_DIR)/%.out : $(EXE_DIR)/%.o $(ALL_OBJECTS) 
    cd $(EXE_DIR) 
    $(GCC) $*.o $(ALL_OBJECTS) $(FLAGS) -o [email protected] $(LIB_DIRS) -L$(ADALIBLOC)/libgnat.a --static-libgcc 

# Executable object creation 
$(EXE_DIR)/%.o : $(EXE_DIR)/%.adb 
    cd $(OBJBINDIR) 
    $(GCC) -c $(FLAGS) $(LINKFLAGS) $< -o [email protected] 

# Executable source creation 
$(EXE_DIR)/%.adb : $(OBJDIR)/%.ali $(ALL_OBJECTS) 
    cd $(EXE_DIR) 
    $(BINDER) $(BIND_DIRS) $(INC_DIRS) -v -x ../$< -o ../$*.adb 

# Object creation 
$(OBJDIR)/%.o : %.adb %.ads 
$(OBJDIR)/%.o : 
    if [ -a $*.adb ]; then \ 
     gcc -c $*.adb $(INC_DIRS) -o [email protected] $(FLAGS); \ 
    else \ 
     gcc -c $*.ads $(INC_DIRS) -o [email protected] $(FLAGS); \ 
    fi; 

# ALI creation 
$(OBJDIR)/%.ali : %.adb %.ads 
$(OBJDIR)/%.ali : 
    if [ -a $*.adb ]; then \ 
     gcc -c $*.adb $(INC_DIRS) -o $(OBJDIR)/$*.o $(FLAGS); \ 
    else \ 
     gcc -c $*.ads $(INC_DIRS) -o $(OBJDIR)/$*.o $(FLAGS); \ 
    fi; 

clean: 
    @rm -f $(ALL_OBJECTS) $(ALL_ALI) 

이 player_test.ali을 찾을 수 없습니다 단계.

어떤 조언이 필요합니까?

+0

이렇게하면 종속성을 제대로 얻지 못할 것입니다. gnatmake는 -M을 사용하여 메이크 파일 양식의 종속성을 출력하지만 더 이상 사용하지 않습니다. –

답변

5

프로젝트 파일없이 문제를 완전히 해결하겠다는 결정을 다시 한번 생각해보십시오. 일반적으로 GNAT를 사용하여 Ada 프로젝트를 빌드 할 때 프로젝트 파일과 makefile의 조합을 사용합니다.

프로젝트 파일은 단일 개체 디렉터리를 가리킬 수 있기 때문에 개체 디렉터리 당 GNAT 프로젝트 파일이 필요합니다.

대부분의 프로젝트에 공통적 인 컴파일러 플래그가있는 경우 다른 프로젝트 파일에서 파생 된 공통 프로젝트 파일에 컴파일러 플래그를 포함하는 것이 좋습니다.

+0

좋아, 나는 그것이 할 수있는 것의 범위를 벗어나는 문제 일 수 있다고 생각했다. GNAT 프로젝트 파일을 사용하는 방법을 연구 할 시간! 현실감을 주셔서 감사합니다. – LambdaBeta

1

참고 : GNAT 프로젝트를 사용하는 것이 이상적인 솔루션입니다. 그럼에도 불구하고 :

GNAT 프로젝트는 시스템으로서 매우 성가 셨습니다. 특히 gprbuild가 아직 내 시스템의 표준 패키지가 아니며, gnatmake가 -P 플래그를 부추겼 기 때문에 더욱 그렇습니다. 따라서 중간 솔루션을 만들었습니다.

디렉토리와 함께 build 디렉토리를 새로 만들었습니다. 인사이드 build 내 모든 소스 디렉토리를 symlink했습니다.

.SILENT: 
BUILD_DIR=../build 

% : force_make 
    cd $(BUILD_DIR); make [email protected] 

force_make: 
    true 

지금 내 소스 디렉토리 내에서 make test를 실행하고 나의 테스트 실행 파일을 생성합니다 :

.PHONY: clean test 
.SILENT: 

FLAGS=-d 
GNATLINKFLAGS= 
GNATBINDFLAGS= 

test: FLAGS+=-g -fprofile-arcs -ftest-coverage 

MAKE=gnatmake 
INCLUDE_DIRS=-Imodel -Iutil -Itest 
GNATLINK=--GNATLINK="gnatlink $(GNATLINKFLAGS)" 
GNATBIND=--GNATBIND="gnatbind $(GNATBINDFLAGS)" 
GNATMAKEFLAGS=$(FLAGS) $(GNATLINK) $(GNATBIND) 

OBJDIR=../obj 
SRCDIR=../src 

# Executable definitions 
PLAYER_TEST_SRC=test/player_test.adb 
PLAYER_TEST_EXE=../bin/player_test.out 

test : $(PLAYER_TEST_EXE) 

$(PLAYER_TEST_EXE) : force_make 
    gnatmake $(PLAYER_TEST_SRC) -D $(OBJDIR) $(INCLUDE_DIRS) -o [email protected] $(GNATMAKEFLAGS) 

force_make: 
    true 

clean : 
    @rm -rf $(OBJDIR)/* 

가 그럼 난 SRC 내에서이 아주 최소한의 Makefile을 만들어 : 나는 다음 빌드에서이 Makefile을 추가 예상했다.

이 시스템의 이점은 프로젝트 파일에 대해 배우면서 순수 GNU make 솔루션에서 순수 GNAT 프로젝트 솔루션으로의 점진적 전환을 허용 할 수 있도록 해당 파일을 빌드 디렉토리에 쉽게 추가 할 수 있다는 것입니다.