Ada gprbuild将外部信息获取到源中
我正试图让gprbuild在我的源代码中自动设置一些变量的值——以这样或那样的方式。我特别希望某些命令的输出可以从代码中访问。在使用Makefiles的C中,这很简单: 资料来源:Ada gprbuild将外部信息获取到源中,ada,gnat,Ada,Gnat,我正试图让gprbuild在我的源代码中自动设置一些变量的值——以这样或那样的方式。我特别希望某些命令的输出可以从代码中访问。在使用Makefiles的C中,这很简单: 资料来源: #include <stdio.h> int main() { printf("%s\n", COMMAND_OUTPUT); return 0; } 然而,我不知道如何用gprbuild和Ada做这样的事情。(除了放弃gprbuild,只使用make——但我更喜欢gprbuild)Ada不像C那样使用
#include <stdio.h>
int main() { printf("%s\n", COMMAND_OUTPUT); return 0; }
然而,我不知道如何用gprbuild和Ada做这样的事情。(除了放弃gprbuild,只使用make——但我更喜欢gprbuild)Ada不像C那样使用预处理器。你不能指望Ada编译器修改代码中的字符串。
使用这种内联编辑很容易违反Ada强类型,这将很难诊断,并且对源代码静态分析完全不可见。Ada不像C那样使用预处理器。您不能期望Ada编译器修改代码中的字符串。
使用这种内联编辑很容易违反Ada强类型,这将很难诊断,并且对源代码静态分析完全不可见。我通过在构建之前从makefile生成Ada文件来解决这个问题 例如:
HG_STATE_SOURCE = src/mercurial.ads
HG_MODIFIER = `test $$(hg status | wc -c || echo 0) -gt 0 && echo "plus changes" || echo "as committed"`
HG_REVISION = `hg tip --template '{node}' 2>/dev/null || echo N/A_____________________________________`
[...]
$(HG_STATE_SOURCE): Makefile $(REPOSITORY_CONFIG) $(REPOSITORY_STATE) $(PROJECT_ROOT_SOURCE)
@mkdir -p src
@echo 'package 'Mercurial is' > $(HG_STATE_SOURCE)
@echo ' Revision : constant String (1 .. 53) :=' >> $(HG_STATE_SOURCE)
@echo ' "'$(HG_REVISION)' '$(HG_MODIFIER)'";' >> $(HG_STATE_SOURCE)
@echo 'end 'Mercurial;' >> $(HG_STATE_SOURCE)
我通过在构建之前从makefile生成一个Ada文件来解决这个问题 例如:
HG_STATE_SOURCE = src/mercurial.ads
HG_MODIFIER = `test $$(hg status | wc -c || echo 0) -gt 0 && echo "plus changes" || echo "as committed"`
HG_REVISION = `hg tip --template '{node}' 2>/dev/null || echo N/A_____________________________________`
[...]
$(HG_STATE_SOURCE): Makefile $(REPOSITORY_CONFIG) $(REPOSITORY_STATE) $(PROJECT_ROOT_SOURCE)
@mkdir -p src
@echo 'package 'Mercurial is' > $(HG_STATE_SOURCE)
@echo ' Revision : constant String (1 .. 53) :=' >> $(HG_STATE_SOURCE)
@echo ' "'$(HG_REVISION)' '$(HG_MODIFIER)'";' >> $(HG_STATE_SOURCE)
@echo 'end 'Mercurial;' >> $(HG_STATE_SOURCE)
是的,gnatprep预处理器允许与C代码中完全相同的操作: main.adb:
带有Ada.Text\u IO;使用Ada.Text\u IO;
主要程序是
开始
Put_行($Command_Output);
端干管;
simple_gnatprep.gpr:
生成文件:
注意:我已将命令输出包含在所使用的obj/目录中,如果命令输出任何不能出现在目录名中的符号,则命令输出将失败。但是,如果您省略它,那么gprbuild会说您的可执行文件是最新的,除了命令的输出外,没有任何更改
另一种选择是在编译之前始终删除对象目录,但如果可能,最好在对象路径中包含任何预处理器符号的值,以便从一种配置(例如调试/发布)切换到另一种配置并返回不会丢弃中间结果并减慢开发过程
Gnatprep只包含在GNAT编译器中,因为Ada标准中还没有任何预处理的规定。对于其他编译器,您需要在Makefile中分别通过gnatprep运行每个文件,然后将其传递给编译器。在这种情况下,不需要修改对象目录名,因为源文件总是新的,编译器总是需要重新编译所有内容。是的,gnatprep预处理器允许与C代码中完全相同的内容: main.adb:
带有Ada.Text\u IO;使用Ada.Text\u IO;
主要程序是
开始
Put_行($Command_Output);
端干管;
simple_gnatprep.gpr:
生成文件:
注意:我已将命令输出包含在所使用的obj/目录中,如果命令输出任何不能出现在目录名中的符号,则命令输出将失败。但是,如果您省略它,那么gprbuild会说您的可执行文件是最新的,除了命令的输出外,没有任何更改
另一种选择是在编译之前始终删除对象目录,但如果可能,最好在对象路径中包含任何预处理器符号的值,以便从一种配置(例如调试/发布)切换到另一种配置并返回不会丢弃中间结果并减慢开发过程
Gnatprep只包含在GNAT编译器中,因为Ada标准中还没有任何预处理的规定。对于其他编译器,您需要在Makefile中分别通过gnatprep运行每个文件,然后将其传递给编译器。在这种情况下,不需要修改对象目录名,因为源文件总是新的,编译器将始终需要重新编译所有内容。如果有某种方法只使用gprbuild传递它,这将非常有效,尽管我想我总是可以将gprbuild包装在make中。如果gprbuild本机无法实现,那么我将接受您的答案为正确。在看到Simon Wright的建议后,我将接受此答案为正确,直到gnatprep允许运行外部命令来生成其内容。这不是一个令人愉快的解决方案。我有一个更整洁的地方。博客描述了我如何使用gprbuild做同样的事情:如果有某种方法可以使用gprbuild来传递它,这将非常有效,尽管我想我总是可以用make包装gprbuild。如果gprbuild本机无法实现,那么我将接受您的答案为正确。在看到Simon Wright的建议后,我将接受此答案为正确,直到gnatprep允许运行外部命令来生成其内容。这不是一个令人愉快的解决方案。我有一个更整洁的地方。博客描述了我如何用gprbuild做同样的事情:它应该仍然可以初始化一个字符串,就像雅各布·斯帕雷·安德森(Jacob Sparre Andersen)的回答一样。如果不是的话,我想我只能使用这个解决方案。这不是真的,虽然不雅致且有一定的限制(可能是出于设计),但它将对源代码进行预处理,而gnatprep并不是Ada语言的一部分。这是一个由一个供应商提供的工具,它应该仍然可以初始化一个字符串,就像Jacob Sparre Andersen的响应一样。如果不是的话,我想我只能使用这个解决方案。这不是真的,虽然不雅致且有一定的限制(可能是出于设计),但它将对源代码进行预处理,而gnatprep并不是Ada语言的一部分。这是一个由一个供应商提供的工具。您可以使用,特别是在模式下。我使用了gnatprep,但没有使用集成的预处理。为什么信息必须在源代码中?通常,您可以将信息放入文件中,并让程序读取该文件。您可以使用,特别是在模式下。我用过啃咬法,但是
project simple_gnatprep is
for Create_Missing_Dirs use "True";
Command_Output := external ("Command_Output");
for Source_Dirs use (".");
for Exec_Dir use ".";
for Main use ("main.adb");
for Object_Dir use "obj/" & "CommandOutput_" & Command_Output;
package Compiler is
for Switches ("Ada") use ("-gnateDCommand_Output=""" & Command_Output & """");
end Compiler;
end simple_gnatprep;
COMMAND_OUTPUT=$(shell echo hello there)
all:
gprbuild -d -p -g -XCommand_Output='${COMMAND_OUTPUT}'
clean:
rm -rf obj/ *.exe