ar rc libmy_lib.a *.o
当我尝试阅读lib
中的内容时
ld libmy_lib.a
我得到这个错误 LD:警告:找不到条目符号_start;未设置开始地址
项目文件: 我的ada项目文件prj.gpr
project Prj is
for Source_Dirs use ("source1/", "source2", ....);
for Object_Dir use ".";
for Languages use ("Ada");
for Library_Name use "test";
for Library_Dir use "lib";
for Library_Interface use (
--All my ada packages
);
package Naming is
for Spec_Suffix ("ada") use ".1.ada";
for Body_Suffix ("ada") use ".2.ada";
for Separate_Suffix use ".2.ada";
for Dot_Replacement use ".";
end Naming;
package Compiler is
for Default_Switches ("ada") use ("-v", "-g", "-gnato", "-gnatwa", "-gnatQ", "-gnat05");
end Compiler;
package Builder is
for Global_Compilation_Switches ("Ada") use ("-gnat95");
end Builder;
package Ide is
end Ide;
end Prj;
MyC Project FileC_Main.gpr
with "prj.gpr";
project C_Main is
for Source_Dirs use ("source_c_1/", "source_c_2/");
for Languages use ("C");
for Main use ("source_c_1/main.c");
end C_Main;
当我运行命令时 gprbuildc_main.gpr
我有2个不同的错误: 首先是对我ADA代码一部分的某些软件包的不确定引用,然后在我不知道存在的GNAT .ADB文件中。我想的库是如此破库。 其次是即使代码良好并运行,也无法找到某些软件包的字段。它给了我错误,指出该字段不存在ADA代码中。 tldr: 我在3个不同的目录中有一个ADA项目,我想从它们创建一个库。然后链接到C测试程序。最终,我只需要交付库文件即可。命令行最好。我不想处理项目文件。
创建静态库的问题很大。 首先,ADA代码极有可能在ADA运行时系统(RTS)中调用。如果您创建静态库,则您(或您的用户)将需要明确拨打ADA RTS,无论您是否使用
libtest.a
。所以都不是
gprbuild
nor
gcc main_c.c -ltest
将足够;您会得到这样的失败(而且更糟):
gprbuild -P c_main
第二,ADA代码可能(Will!)需要详细说明,在程序启动时完成。当创建库时,添加了函数
$ gcc main.c -Lada/lib -ltest
Undefined symbols for architecture x86_64:
"_ada__calendar__delays__delay_for", referenced from:
_Hello in libtest.a(hello.o)
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
)
第一个问题是创建动态库(在Windows上,Linux和其他Unix系统上的动态库,Mac OS X上的其他UNIX系统)。为此,你说gprbuild
。 (请注意,尽管动态库知道它需要哪些其他库,但它可能不知道在哪里可以找到它们,因此您必须安排它们在加载程序的库搜索路径上)。 第二个问题是创建Adacore称为
standalOnedynamic库的方法,并使其自动初始化。要做到这一点,您需要添加两个属性:
testinit()
指定您希望在图书馆外看到的单位的名称列表。效果是仅在库中包含命名单元的源和
testfinal()
文件;如果唯一的呼叫者来自C,则可能只需要命名一个。
.dll
-我认为这实际上是默认值。
I设置了一个示例(在Mac OS X上,GNAT GPL 2014)。subdirectory
.so
.dylib
hello.ads,
for Library_Kind use "dynamic";
hello.adb,
for Library_Interface use (...);
number.ads,
.ali
和数字
for Library_Auto_Init use "true";
ada
和main.c
library project Prj is
for Languages use ("ada");
for Library_Name use "test";
for Library_Kind use "dynamic";
for Library_Interface use ("hello");
for Library_Auto_Init use "true";
for Library_Src_Dir use "include";
for Library_Dir use "lib";
for Source_Dirs use (".");
for Object_Dir use ".build";
end Prj;
function Hello return Integer;
pragma Export (C, Hello, "Hello");
执行:
with Number;
function Hello return Integer is
begin
delay 0.001; -- so the tasking runtime gets called in
return Number.Value;
end Hello;
要在另一台计算机上向C用户分发库,而没有已经安装的ADA运行时,您需要包装
package Number is
pragma Elaborate_Body;
Value : Integer := 0; -- before elaboration
end Number;
(或
package body Number is
begin
Value := 42; -- after elaboration
end Number;
或
with "ada/prj";
project C_Main is
for Source_Dirs use (".");
for Languages use ("c");
for Main use ("main.c");
for Exec_Dir use ".";
for Object_Dir use ".build";
end C_Main;
),以及所需的ADA共享库。
在一个Unix系统中,您会发现这是您正在寻找的#include <stdio.h>
extern int Hello(void);
int main() {
int hello = Hello();
printf("Hello returned %d.\n", hello);
return 0;
}
和$ gprbuild -p -P c_main
gcc -c main.c
gcc -c -fPIC number.adb
gcc -c -fPIC hello.adb
gprlib test.lexch
gnatbind -n -o b__test.adb -Ltest -a /Users/simon/tmp/crychair/ada/.build/number.ali ...
gcc -c -x ada -gnatA -gnatws b__test.adb -o b__test.o ...
gcc -dynamiclib -shared-libgcc -o /Users/simon/tmp/crychair/ada/lib/libtest.dylib ... /Users/simon/tmp/crychair/ada/.build/number.o ...
ar cr libc_main.a ...
ranlib -c libc_main.a
gcc main.o -o main
$ ./main
Hello returned 42.
输出的对象搜索路径部分的最后一行)中找到这些。通常会有符号链接:
libtest.so
.dylib
链接
.dll
或可能
ldd libtest.so
在操作系统上,可执行的可执行文件可能无法在运行时找到共享库。
绕这是一种方式,就是将装载机已经看起来的库放置在库中,例如(在这种情况下,您不需要libgnat*.so
libgnarl*.so
)。
第三种方法是告诉链接器以将路径保存在可执行文件中:
gnatls -v
Mac OS X上的工作,可能会在Linux上。