如何使用 gnatmake 编译 spec _.ada 和 body .ada?

How to compile spec _.ada and body .ada using gnatmake?

gnatmake xx.ada xx_.ada     
gcc -c -x ada xx.ada      
xx.ada:44:14: warning: file name does not match unit name, should be 
"xx.adb"  
xx.ada:44:14: file "xx.ads" not found
gnatmake: "xx.ada" compilation error

尝试使用 gnatmake 编译..它不起作用。

除非有一些非常非常重要的原因让您必须坚持该文件命名约定,否则如果您使用默认的 GNAT 约定会容易得多:规范文件被命名为 .ads,正文文件 .adb.

实际上,当你说 gnatmake xx.ada 时,你会得到文件名不符合预期的警告,然后编译器继续;它看到 xx.ada 是一个包体,然后去寻找规范(在 xx.ads 中,因为你没有告诉它任何不同)并且找不到它。

有一个实用程序 gnatname(请参阅 here),您可以 运行 使用您的资源(gnatname *.ada 为我工作,与只有 4 个文件)来生成 "configuration file" gnat.adcgnatmake 首先读取以明确告诉它哪个文件包含什么。我的测试结果

pragma Source_File_Name
  (Linked_List,
   Body_File_Name => "linked_list.ada");
pragma Source_File_Name
  (Lists,
   Spec_File_Name => "lists_.ada");
pragma Source_File_Name
  (Lists,
   Body_File_Name => "lists.ada");
pragma Source_File_Name
  (Linked_List,
   Spec_File_Name => "linked_list_.ada");

或者,您可以通过编写项目文件来使用 GNAT Project Manager 中的等效项,例如t.gpr包含

project T is

   package Naming is
      for Spec_Suffix ("ada") use "_.ada";
      for Body_Suffix ("ada") use ".ada";
   end Naming;

end T;

并使用 gnatmake -P t.gpr.

进行编译

(较新版本的 GNAT 包括一个实用程序 gprbuild,它理解 .gpr 个文件;gnatmake 实际上会调用 gprbuild 如果它找到了,那么你实际上说的是 gprbuild -P t.gpr.)

为了补充 Simon Wright anwser,如果您能够编辑源文件,一些额外的提示。

如文档所述here

Pragma Source_File_Name

引用 link:

Use this to override the normal naming convention. It is a configuration pragma, and so has the usual applicability of configuration pragmas (i.e. it applies to either an entire partition, or to all units in a compilation, or to a single unit, depending on how it is used. unit_name is mapped to file_name_literal. The identifier for the second argument is required, and indicates whether this is the file name for the spec or for the body.

Another form of the Source_File_Name pragma allows the specification of patterns defining alternative file naming schemes to apply to all files.

 pragma Source_File_Name
   (  [Spec_File_Name  =>] STRING_LITERAL
    [,[Casing          =>] CASING_SPEC]
    [,[Dot_Replacement =>] STRING_LITERAL]);

 pragma Source_File_Name
   (  [Body_File_Name  =>] STRING_LITERAL
    [,[Casing          =>] CASING_SPEC]
    [,[Dot_Replacement =>] STRING_LITERAL]);

 pragma Source_File_Name
   (  [Subunit_File_Name =>] STRING_LITERAL
    [,[Casing            =>] CASING_SPEC]
    [,[Dot_Replacement   =>] STRING_LITERAL]);

 CASING_SPEC ::= Lowercase | Uppercase | Mixedcase

The first argument is a pattern that contains a single asterisk indicating the point at which the unit name is to be inserted in the pattern string to form the file name. The second argument is optional. If present it specifies the casing of the unit name in the resulting file name string. The default is lower case. Finally the third argument allows for systematic replacement of any dots in the unit name by the specified string literal.

和警告:

Note that Source_File_Name pragmas should not be used if you are using project files. The reason for this rule is that the project manager is not aware of these pragmas, and so other tools that use the projet file would not be aware of the intended naming conventions. If you are using project files, file naming is controlled by Source_File_Name_Project pragmas, which are usually supplied automatically by the project manager. A pragma Source_File_Name cannot appear after a Pragma Source_File_Name_Project.

据我所知,根据 Simon 的 link,这些似乎基本上就是 gnatname 所做的,引用:

To help maintain the correspondence between compilation unit names and source file names within the compiler, GNAT provides a tool gnatname to generate the required pragmas for a set of files.