创建一个无需 gnat-tools 即可链接的静态 Ada-Library
Create a static Ada-Library which can be linked without gnat-tools
我想从 Ada-Code 创建静态库并将其部署到没有 GNAT-Toolchain 的开发人员(对于 C/C++ 代码)。
当我尝试使用 C 程序 Link Ada-Library ('.a') 时,我会遇到以下 Linker-Errors:
undefined reference to `__gnat_rcheck_CE_Overflow_Check'
undefined reference to `ada__text_io__put_line__2'
我怎样才能做到这一点?它接缝我应该 link 反对运行时库,但如何?
测试代码:
main.c:
#include <stdio.h>
extern void adaTest();
extern int add5(int);
int main(){
adaTest();
int b = add5(2);
printf("--> %d \ndone.\n", b);
return 0;
}
ada_lib_project.gpr:
library project ada_lib_project is
for Languages use ("Ada");
for Library_Name use "My_Ada_Lib";
for Library_Dir use "my_generated_lib";
for Library_Kind use "Static";
end ada_lib_project;
adatestpacket.ads:
with Interfaces.C; use Interfaces.C;
package adatestpacket is
procedure adatest with
Export, Convention => C, External_Name => "adaTest";
function add5(x: in int) return int with
Export, Convention => C, External_Name => "add5";
end adatestpacket;
adatestpacket.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C; use Interfaces.C;
package body adatestpacket is
procedure adatest is
begin
Put_Line("This is executed ADA/SPARK-Code...");
null;
end adatest;
function add5(x: in int) return int is
begin
return x + 5;
end add5;
end adatestpacket;
正在编译:
gcc -c main.c -o main.o # .c -> .o
gprbuild -P ada_lib_project.gpr # .ad[sb] -> .a
gcc main.o -L my_generated_lib -l My_Ada_Lib -o a.out # Linking -- with undefined References
可能最简单的方法是简单地也用 gprbuild 编译 C 源代码(即使你不能在你的目标场景中这样做,你可以做测试并用 -v
GPRbuild 是如何让它工作的):
with "ada_lib_project";
project My_Executable is
for Languages use ("C");
for Main use ("main.c");
end My_Executable;
您还需要调用 adainit
和 adafinal
来初始化/完成 Ada 包:
#include <stdio.h>
extern void adainit();
extern void adafinal();
extern void adaTest();
extern int add5(int);
int main(){
adainit();
adaTest();
int b = add5(2);
printf("--> %d \ndone.\n", b);
adafinal();
return 0;
}
adainit
和 adafinal
由 gnatbind
为独立库生成。当看到您使用 C 可执行文件中的 Ada 库时,我不完全确定 GPRBuild 是否会处理这个问题;如果没有,你需要
package Binder is
for Default_Switches ("Ada") use ("-n");
end Binder;
在你的图书馆。这样做之后,你应该可以做到
gprbuild my_executable.gpr
如果你想在没有 GPRbuild 的情况下完成它,-n
/adainit
/adafinal
部分仍然适用,你需要 link 你的可执行文件
-l<your-gnat-lib>
其中 是您的 GNAT 版本的 Ada 标准库;上次我这样做时,它类似于 gnat-2021
。您可能需要添加一个 -L<directory-containing-that-lib>
,具体取决于它所在的位置。
(这个答案可能有错误,因为我在M1上目前无法测试它)
编辑:如果您真的想为开发人员提供无法访问 GNAT 的权限,您需要构建一个 encapsulated,即动态库。 This answer 涵盖了该过程。如果需要提供静态库,您必须至少提供 GNAT 标准库文件。
我已经用 -static
生成了静态二进制文件。我不知道在生成您的库时是否可以使用类似的东西,或者您还需要 GNAT 运行时才能与 C/C++ 工具链接。
对于任何对工作实施感兴趣的人,这些是我的问题的变化:
main.c:
#include <stdio.h>
extern void adainit();
extern void adafinal();
extern void adaTest();
extern int add5(int);
int main(){
adainit();
adaTest();
int b = add5(2);
printf("--> %d \ndone.\n", b);
adafinal();
return 0;
}
ada_lib_project.gpr:
library project ada_lib_project is
for Languages use ("Ada");
for Library_Name use "My_Ada_Lib";
for Library_Dir use "my_generated_lib";
for Library_Kind use "static-pic";
for Library_Interface use ("adatestpacket");
package Binder is
-- "-Lada" set "ada" as Prefix for "init" and "final" Function
for Default_Switches ("Ada") use ("-n","-Lada");
end Binder;
end ada_lib_project;
正在编译:
gprbuild -P ada_lib_project.gpr # .adb -> .a
gcc main.c -L my_generated_lib -l My_Ada_Lib -l gnat_pic -ldl
对于最后一个命令,我只需要将库 (My_Ada_Lib) 和运行时 (libgnat_pic.a) 从 GNAT/2021/lib/gcc/x86_64-pc-linux-gnu/10.3.1/rts-native/adalib 传输到远程机器。
我想从 Ada-Code 创建静态库并将其部署到没有 GNAT-Toolchain 的开发人员(对于 C/C++ 代码)。
当我尝试使用 C 程序 Link Ada-Library ('.a') 时,我会遇到以下 Linker-Errors:
undefined reference to `__gnat_rcheck_CE_Overflow_Check'
undefined reference to `ada__text_io__put_line__2'
我怎样才能做到这一点?它接缝我应该 link 反对运行时库,但如何?
测试代码:
main.c:
#include <stdio.h>
extern void adaTest();
extern int add5(int);
int main(){
adaTest();
int b = add5(2);
printf("--> %d \ndone.\n", b);
return 0;
}
ada_lib_project.gpr:
library project ada_lib_project is
for Languages use ("Ada");
for Library_Name use "My_Ada_Lib";
for Library_Dir use "my_generated_lib";
for Library_Kind use "Static";
end ada_lib_project;
adatestpacket.ads:
with Interfaces.C; use Interfaces.C;
package adatestpacket is
procedure adatest with
Export, Convention => C, External_Name => "adaTest";
function add5(x: in int) return int with
Export, Convention => C, External_Name => "add5";
end adatestpacket;
adatestpacket.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C; use Interfaces.C;
package body adatestpacket is
procedure adatest is
begin
Put_Line("This is executed ADA/SPARK-Code...");
null;
end adatest;
function add5(x: in int) return int is
begin
return x + 5;
end add5;
end adatestpacket;
正在编译:
gcc -c main.c -o main.o # .c -> .o
gprbuild -P ada_lib_project.gpr # .ad[sb] -> .a
gcc main.o -L my_generated_lib -l My_Ada_Lib -o a.out # Linking -- with undefined References
可能最简单的方法是简单地也用 gprbuild 编译 C 源代码(即使你不能在你的目标场景中这样做,你可以做测试并用 -v
GPRbuild 是如何让它工作的):
with "ada_lib_project";
project My_Executable is
for Languages use ("C");
for Main use ("main.c");
end My_Executable;
您还需要调用 adainit
和 adafinal
来初始化/完成 Ada 包:
#include <stdio.h>
extern void adainit();
extern void adafinal();
extern void adaTest();
extern int add5(int);
int main(){
adainit();
adaTest();
int b = add5(2);
printf("--> %d \ndone.\n", b);
adafinal();
return 0;
}
adainit
和 adafinal
由 gnatbind
为独立库生成。当看到您使用 C 可执行文件中的 Ada 库时,我不完全确定 GPRBuild 是否会处理这个问题;如果没有,你需要
package Binder is
for Default_Switches ("Ada") use ("-n");
end Binder;
在你的图书馆。这样做之后,你应该可以做到
gprbuild my_executable.gpr
如果你想在没有 GPRbuild 的情况下完成它,-n
/adainit
/adafinal
部分仍然适用,你需要 link 你的可执行文件
-l<your-gnat-lib>
其中 gnat-2021
。您可能需要添加一个 -L<directory-containing-that-lib>
,具体取决于它所在的位置。
(这个答案可能有错误,因为我在M1上目前无法测试它)
编辑:如果您真的想为开发人员提供无法访问 GNAT 的权限,您需要构建一个 encapsulated,即动态库。 This answer 涵盖了该过程。如果需要提供静态库,您必须至少提供 GNAT 标准库文件。
我已经用 -static
生成了静态二进制文件。我不知道在生成您的库时是否可以使用类似的东西,或者您还需要 GNAT 运行时才能与 C/C++ 工具链接。
对于任何对工作实施感兴趣的人,这些是我的问题的变化:
main.c:
#include <stdio.h>
extern void adainit();
extern void adafinal();
extern void adaTest();
extern int add5(int);
int main(){
adainit();
adaTest();
int b = add5(2);
printf("--> %d \ndone.\n", b);
adafinal();
return 0;
}
ada_lib_project.gpr:
library project ada_lib_project is
for Languages use ("Ada");
for Library_Name use "My_Ada_Lib";
for Library_Dir use "my_generated_lib";
for Library_Kind use "static-pic";
for Library_Interface use ("adatestpacket");
package Binder is
-- "-Lada" set "ada" as Prefix for "init" and "final" Function
for Default_Switches ("Ada") use ("-n","-Lada");
end Binder;
end ada_lib_project;
正在编译:
gprbuild -P ada_lib_project.gpr # .adb -> .a
gcc main.c -L my_generated_lib -l My_Ada_Lib -l gnat_pic -ldl
对于最后一个命令,我只需要将库 (My_Ada_Lib) 和运行时 (libgnat_pic.a) 从 GNAT/2021/lib/gcc/x86_64-pc-linux-gnu/10.3.1/rts-native/adalib 传输到远程机器。