Ada Makefile绑定问题
我在Ada中从事一个项目,希望有一个自定义的makefile(因为我打算最终与c和python进行接口,我非常熟悉makefile语法,但对gnatmake项目语法一点也不熟悉)。我把自定义编译搞得一团糟,还以为它能正常工作,但我的makefile在绑定阶段遇到了问题,它至少看起来像是执行完全相同的命令行 我想我可能有一个“一个接一个”的目录错误,或者把事情复杂化了 无论如何,我的项目目前包含3个源目录(但还有更多的源目录)。模型包含“逻辑”,util包含公共实用程序,test包含未打包的“主”过程。最终,我的src目录中还会有一些“main”过程。ASCII图片:Ada Makefile绑定问题,makefile,ada,gnat,Makefile,Ada,Gnat,我在Ada中从事一个项目,希望有一个自定义的makefile(因为我打算最终与c和python进行接口,我非常熟悉makefile语法,但对gnatmake项目语法一点也不熟悉)。我把自定义编译搞得一团糟,还以为它能正常工作,但我的makefile在绑定阶段遇到了问题,它至少看起来像是执行完全相同的命令行 我想我可能有一个“一个接一个”的目录错误,或者把事情复杂化了 无论如何,我的项目目前包含3个源目录(但还有更多的源目录)。模型包含“逻辑”,util包含公共实用程序,test包含未打包的“主”
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
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 $@ $(GNATMAKEFLAGS)
clean :
@rm -rf $(OBJDIR)/* $(PLAYER_TEST_EXE) b~*
这看起来非常接近,只是在绑定阶段找不到player_test.ali
有什么建议吗?我建议您重新考虑您的决定,在没有项目文件的情况下完全解决问题。我通常使用项目文件和makefile的组合来使用GNAT构建Ada项目 每个对象目录都需要一个GNAT项目文件,因为项目文件只能指向单个对象目录
如果大多数项目都有通用编译器标志,那么将它们放在一个通用项目文件中是有意义的,其他项目文件都是从该文件派生的。我建议您重新考虑完全不使用项目文件来解决问题的决定。我通常使用项目文件和makefile的组合来使用GNAT构建Ada项目 每个对象目录都需要一个GNAT项目文件,因为项目文件只能指向单个对象目录
如果大多数项目都有公共编译器标志,那么将它们放在公共项目文件中是有意义的,其他项目文件都是从该文件派生的。注意:使用GNAT项目是理想的解决方案。尽管如此: 我发现GNAT项目作为一个系统非常麻烦,特别是因为gprbuild还不是我的系统的标准包,而且gnatmake已经取消了
-p
标志。因此,我创建了一个中间解决方案
我在我的src
目录旁边创建了一个新目录build
。在build
I内部,我将所有源目录进行了符号链接。然后,我在build中添加了这个Makefile:
.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 $@ $(GNATMAKEFLAGS)
force_make:
true
clean :
@rm -rf $(OBJDIR)/*
然后我在src中创建了这个非常小的Makefile:
.SILENT:
BUILD_DIR=../build
% : force_make
cd $(BUILD_DIR); make $@
force_make:
true
现在我可以从源目录中运行maketest
,它将按预期创建测试可执行文件
这个系统的好处是,当我了解项目文件时,我可以轻松地将它们添加到构建目录,以便允许从纯GNU make解决方案到纯GNAT项目解决方案的增量转换。注意:使用GNAT项目是理想的解决方案。尽管如此: 我发现GNAT项目作为一个系统非常麻烦,特别是因为gprbuild还不是我的系统的标准包,而且gnatmake已经取消了
-p
标志。因此,我创建了一个中间解决方案
我在我的src
目录旁边创建了一个新目录build
。在build
I内部,我将所有源目录进行了符号链接。然后,我在build中添加了这个Makefile:
.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 $@ $(GNATMAKEFLAGS)
force_make:
true
clean :
@rm -rf $(OBJDIR)/*
然后我在src中创建了这个非常小的Makefile:
.SILENT:
BUILD_DIR=../build
% : force_make
cd $(BUILD_DIR); make $@
force_make:
true
现在我可以从源目录中运行maketest
,它将按预期创建测试可执行文件
这个系统的好处是,当我了解项目文件时,我可以轻松地将它们添加到构建目录中,以便允许从纯GNU make解决方案到纯GNAT项目解决方案的增量转换。这样做,您永远不会获得正确的依赖项。gnatmake过去支持-M以Makefile形式输出依赖项,但现在不支持了。这样做,依赖项永远不会正确。gnatmake过去支持-M以Makefile的形式输出依赖项,但现在没有了。好吧,我认为这可能是一个超出make功能范围的问题。是时候研究如何使用GNAT项目文件了!谢谢你的现实。好吧,我想这可能是一个超出make能力范围的问题。是时候研究如何使用GNAT项目文件了!谢谢你的现实。