为了了解 Ada 程序编译背后的过程(不诉诸使用gpr),我决定手动编译我的一个项目。为了编译程序,我对.adb其中的每个文件运行以下命令(但是不是手动):
$ gcc -c src/<file>.adb -o obj/<file>.o
这会编译所有文件并将它们放入obj目录中。
或者更确切地说,会的。这有一个小问题。我有一个从另一个项目生成的存档(静态库),名为libapples.a,包含 package Apples。Apples您在上面看到我编译的文件使用了该包。
由于libapples.a不再有源文件(鉴于其存档格式),因此使用-I开关向上述命令提供该库的源是不可行的(甚至不可能);另一方面,如果我没有包含源代码,上面的命令会返回给我:
<file>.adb:<y>:<x>: file "apples.ads" not found
gnatmake: "src/<file>.adb" compilation error
我尝试使用标志-L和将库包含在编译过程中l(我相信这就是您在 C 中的做法;如果我错了,请随时纠正我)。在另一次尝试中,我将存档放在源目录中。
如何在编译过程中包含一个库?
我正在 Ada 中试验 IP 多播,但似乎没有收到发送到多播组的任何流量。不知何故,我似乎无法让应用程序获取传入的数据包。
我可以验证(使用 Wireshark)是否从我的计算机发送了多播加入,并且我还可以验证是否有数据发送到多播组。
我可以验证操作系统是否已通过 netsh 命令注册了多播加入:
netsh interfaces ip show joins
Run Code Online (Sandbox Code Playgroud)
如果我运行我的程序,则列出的组的引用为 1;如果不运行,则引用为 0。
以下过程显示了我的侦听器,我使用Mcast_IP => "239.255.128.128"和调用它Mcast_Port => "8807":
with GNAT.Sockets;
with Ada.Streams;
with Ada.Text_IO;
procedure Receive_Multicast (Mcast_IP : in String;
Mcast_Port : in String)
is
package GS renames GNAT.Sockets;
package AS renames Ada.Streams;
package Tio renames Ada.Text_IO;
use GS;
use type Ada.Streams.Stream_Element_Offset;
Socket : GS.Socket_Type;
Address : GS.Sock_Addr_Type;
Data : AS.Stream_Element_Array (1 .. 2**16);
Offset : AS.Stream_Element_Offset;
Sender : GS.Sock_Addr_Type;
begin …Run Code Online (Sandbox Code Playgroud) 我有一个带有多个构建配置的 Gnat/Gprbuild 项目。我有一个主源文件和一个辅助广告文件,其中主源文件包括:
with Secondary_File; use Secondary_File;
Run Code Online (Sandbox Code Playgroud)
问题是在每个配置中,辅助文件都有不同的名称。例如,一个配置的名称可能为Secondary_File_1.ads,另一配置的名称可能为Secondary_File_2.ads。这使得上面的with语句无法使用。
在C中,我会做这样的事情:
#ifdef BUILD_CFG_1
#include "secondary_file_1.h"
#else
#include "secondary_file_2.h"
#endif
Run Code Online (Sandbox Code Playgroud)
是否有一种聪明的方法可以使用 Gprbuild 系统在 ADA 中执行此类操作?
我仍然是Ada的新手,我认为我误解了Preconditions的使用,因为通过GNAT RM查看似乎检查不会在运行时执行.此外,此处的GNAT RM for Precondition不指定在不满足前提条件时抛出哪个异常.
这是我正在尝试的代码:
procedure Test is
begin
generic
type Element_Type is private;
use System.Storage_Elements;
procedure Byte_Copy (Destination : out Element_Type;
Source : in Element_Type;
Size : in Storage_Count := Element_Type'Size)
with Pre =>
Size <= Destination'Size and
Size <= Source'Size;
procedure Byte_Copy (Destination : out Element_Type;
Source : in Element_Type;
Size : in Storage_Count := Element_Type'Size)
is
subtype Byte_Array is Storage_Array (1 .. Size / System.Storage_Unit);
Write, Read : Byte_Array;
for Write'Address use Destination'Address; …Run Code Online (Sandbox Code Playgroud) 我正在阅读一个简单的文本文件.一切都按预期工作,除非遇到一个开括号("[")字符.然后我得到一个CONSTRAINT_ERROR.
我的功能是:
----------------------------------------------
-- GET_FILE_CONTENTS
function Get_File_Contents (File_Name : in String)
return String_Array is
-- Loads the entire file into a dynamically sized
-- array of Unbounded_Wide_String.
-- The line count is used to dynamically size the array.
Line_Count : Natural
:= 0;
File : Ada.Wide_Text_IO.File_Type;
begin
-- Get the line count before opening the file.
Line_Count := Get_File_Line_Count (File_Name);
Ada.Wide_Text_IO.Open (File,
In_File,
File_Name);
declare
Lines : String_Array (1 .. Line_Count);
begin
-- Step through the file and save each …Run Code Online (Sandbox Code Playgroud) 从Integer输入输入后,它将自动跳过从String获取输入.我不知道为什么?
获取String和Integer输入的简单Ada代码:
with ada.Text_IO; use ada.Text_IO;
with ada.Integer_Text_IO; use ada.Integer_Text_IO;
procedure Main is
inputText: String (1..10);
inputNmbr : Integer;
StringNatural: Integer;
begin
Put_Line("Enter Integer");
Get(inputNmbr,1);
Put_Line("Enter String");
Get_Line(inputText,StringNatural);
Put_Line("===================");
Put("Input for Integer: ");
Put(inputNmbr,1);
Put_Line("");
Put_Line("Input for String: ");
Put_Line(inputText(1..StringNatural));
end Main;
Run Code Online (Sandbox Code Playgroud)
输出:
Enter Integer
2
Enter String
===================
Input for Integer: 2
Input for String:
[2015-07-11 23:01:00] process terminated successfully, elapsed time: 00.86s
Run Code Online (Sandbox Code Playgroud) 我正在研究Ada中的一个项目,并且想要一个自定义的makefile(因为我打算最终与c和python接口,并且我非常熟悉makefile语法,而且根本不熟悉gnatmake项目语法).我搞乱了自定义编译,并认为我有它工作,但我的makefile至少看起来它完全相同的命令行执行在绑定阶段遇到问题.
我想我可能有一个off-by-one目录错误,或者过度/不完全复杂的东西.
无论如何,我的项目目前包含3个源目录(但会有更多的目录).Model包含'logic',util包含常用实用程序,test包含未打包的'main'程序.最后我还会在我的src目录中找到一些"主要"程序.ASCII图片:
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)
\- ...
Run Code Online (Sandbox Code Playgroud)
我尝试了一个非常接近我想要的"基本"makefile:
.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 …Run Code Online (Sandbox Code Playgroud) 在过去的几周里,由于各种不同的原因,我一直进入Ada。但是毫无疑问,有关我为何使用Ada的个人原因的信息超出了此问题的范围。
从前几天开始gprbuild,我开始使用Windows版本的GNAT附带的命令,以便获得以项目相关的方式管理我的应用程序的系统的好处。也就是说,能够在每个项目的基础上定义某些属性,而不是自己手动设置编译阶段。
目前,当命名我的文件时,它们的名称基于似乎是的标准grpbuild,尽管我可能会很错。对于句点(在包结构中),-在文件名中放置a ,对于下划线,_将相应地放置a。因此,名称相同的软件包App.Test.File_Utils的文件名将为app-test-file_utils:.ads,.adb因此。
在.gpr项目文件中,我指定了:
for Source_Dirs use ("app/src/**");
Run Code Online (Sandbox Code Playgroud)
这样我就可以使用多个目录来存储我的文件,而不需要将它们全部都放在同一个目录中。
但是,出现的问题是文件名往往变得很长。因为我已经根据文件包含的包名称将文件放在目录中,所以我想知道是否有某种方法可以使编译器理解可以从文件的目录名中检索包名称。
也就是说,我不必将其命名为App.Test.File_Utils文件名app-test-file_utils,而是希望它app/test通过name 驻留在目录下file_utils。
这是可行的,还是会令我最终不得不按以下方式命名我的文件的恐惧app-test-some-then-one-has-more_files-another_package-knew-test-more-important_package.ads?当然,我没有错过有关Ada应用程序实际结构的一些知识。
我试图package Naming在gpr文档中的文件配置中寻找答案,但无济于事。此外,我一直在浏览网络以获取信息,但我决定最好通过Stackoverflow寻求帮助,以便将来可能会遇到此问题的其他人(首先是遇到问题的人)也可能会获得帮助。 。
任何正确方向的指点都会非常有帮助!
将一些旧代码移植到较新的 CentOs Linux 机器。我使用带有几个标志的 linux gnat:
Default_Switches ("ada") use ("-fstack-check", "-g", "-gnatVr", "-gnato", "-gnatE", "-gnatwmuv", "-gnata", "-m32");
Run Code Online (Sandbox Code Playgroud)
我有 gnat 版本:
gcc-gnat.i686 4.8.5-11.el7
Run Code Online (Sandbox Code Playgroud)
所以这些是前提条件。我现在有一个肯定可以工作的自写存储管理器,它被称为
St_Wa.Alloc(StoragePool, BitSize)
Run Code Online (Sandbox Code Playgroud)
所以现在我的问题是,说实话,我真的不明白编译器失败的原因,所以我将非常感谢您详细解释为什么它不起作用!
function AllocMem(StoragePool : in St_Wa.Mem_Pool_Type;
Option: in Option_Type)
return Option_Ref is
subtype New_Type is Option_Type (Option.Kind);
New_Option : New_Type;
for New_Option use at St_Wa.Alloc( StoragePool => StoragePool,
BitSize => New_Type'Size)
begin
Bl_Bl.Move( ... sth happens here ... )
return Pointer(New_Option'Address);
end AllocMem;
Run Code Online (Sandbox Code Playgroud)
然而:
type Option_Type ( Kind : Option_Kind_Type := Marker) is
record
Next …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用编译.adb文件gnatmake,并且该-o标志未产生我想要的目标文件名:
$ gnatmake --GCC=g++ -D bin/src/ghdl_grt/ -f -u -c src/ghdl_grt/grt-vstrings_io.adb -o bin/src/ghdl_grt/grt-vstrings_io.adb.o
g++ -c -Isrc/ghdl_grt/ -I- -o /home/jon/controlix-code/bin/src/ghdl_grt/grt-vstrings_io.o src/ghdl_grt/grt-vstrings_io.adb
Run Code Online (Sandbox Code Playgroud)
如您所见,它获得正确的路径,但文件名应以结尾,.adb.o并且仅以结尾.o。有任何想法吗?