如何从Ada源构建可从C ++代码调用的静态库? [英] How to build a static library from Ada source that's callable from C++ code?

查看:108
本文介绍了如何从Ada源构建可从C ++代码调用的静态库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要用一堆用Ada编写的代码构建一个静态库,可以从用C / C ++编写的代码中调用这些代码。

I need to build a static library with a bunch of code written in Ada that can be called from code written in C/C++.

我已经搜索了互联网,并且对 gnatmake gnatbind gnatlink 有一些了解,但仍然无法正确完成工作。

I've searched through internet and got some knowledge about gnatmake, gnatbind and gnatlink, but still can't get the job done correctly.

此外,我已经阅读了一些依赖某种项目文件的工具。
我对这些都不感兴趣,我只需要一堆命令即可编写 Makefile

Also, I've read there are tools that relies upon some kind of project file. I'm not interested in those, I just need a bunch of commands to write in a Makefile.

推荐答案

此答案假设您使用的是GCC工具链。

This answer assumes you’re using the GCC toolchain.

最大的障碍是Ada代码需要详细说明(大致,相当于在C ++中调用文件级构造函数)。 gnatbind 是执行此操作的工具,您使用标志 -L

The big hurdle is that Ada code needs elaboration (roughly, the equivalent of calling file-level constructors in C++). gnatbind is the tool that does this, and you use the flag -L:

-Lxyz     Library build: adainit/final renamed to xyzinit/final, implies -n
[...]
-n        No Ada main program (foreign main routine)

例如,考虑Ada源 foo.ads

package Foo is
   procedure Impl
   with
     Convention => C,
     Export,
     External_Name => "foo";
end Foo;

,或者,如果在Ada2012之前使用Ada,

or, if using Ada prior to Ada2012,

package Foo is
   procedure Impl;
   pragma Export (Convention => C, Entity => Impl, External_Name => "foo");
end Foo;

foo.adb

with Ada.Text_IO;
package body Foo is
   procedure Impl is
   begin
      Ada.Text_IO.Put_Line ("I am foo");
   end Impl;
begin
   Ada.Text_IO.Put_Line ("foo is elaborated");
end Foo;

和一对类似的文件 bar.ads bar.adb (整个 s / foo / bar / g )。

and a similar pair of files bar.ads, bar.adb (s/foo/bar/g throughout).

编译以下内容:

gnatmake foo bar

绑定:

gnatbind -Lck -o ck.adb foo.ali bar.ali

(这实际上会生成 ck.ads 以及命名为 ck.adb 的代码;这些是进行详细说明的代码。

(this will actually generate ck.ads as well as the named ck.adb; these are the code that does the elaboration).

编译详细代码:

gnatmake ck.adb

生成库:

ar cr libck.a ck.o foo.o bar.o

,您几乎可以滚动了。

C主程序可能看起来像

The C main program might look like

#include <stdio.h>

void ckinit(void);
void ckfinal(void);
void foo(void);
void bar(void);

int main()
{
  ckinit();
  printf("calling foo:\n");
  foo();
  printf("calling bar:\n");
  bar();
  ckfinal();
  return 0;
}

(您的主体是C ++,因此您需要 extern C { ...,当然)。

(your main is in C++, so you’ll need extern "C" {..., of course).

您会认为

gcc main.c libck.a



<可以的。但是, libck 在Ada运行时中调用。在这里(macOS),这意味着我说

would do the trick. However, libck calls in the Ada runtime. Here (macOS), that means I say

gcc main.c libck.a /opt/gnat-gpl-2016/lib/gcc/x86_64-apple-darwin14.5.0/4.9.4/adalib/libgnat.a

(您可以使用 gcc --print-libgcc-file-name

找到该路径,生成的可执行文件将运行:

The resulting executable runs:

$ ./a.out
bar is elaborated
foo is elaborated
calling foo:
I am foo
calling bar:
I am bar

这篇关于如何从Ada源构建可从C ++代码调用的静态库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆