Как связать внешнюю библиотеку C с математическими службами среды выполнения Ada по умолчанию (sin, cos и т. Д.)? - PullRequest
2 голосов
/ 07 октября 2019

Мне нужно использовать внешнюю библиотеку C, выполняющую некоторые вычисления с помощью тригонометрических сервисов для моей программы Ada. Я делаю это хорошо, используя stm32 bb runtime (SFP), но при попытке сделать то же самое в родной среде, использующей среду выполнения Ada по умолчанию, я сталкиваюсь с проблемами компоновки. Надеюсь, я смогу найти здесь какую-нибудь помощь.

Я пробовал несколько конфигураций решений для файлов проектов (gpr), и у меня всегда возникает одна и та же ошибка компоновки:

Memory region         Used Size  Region Size  %age Used/opt/gnat/gnat_native/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.3.1/ld: /home/pulsar/repos/pulsar-software/something/lib_c/libC.a(something.o): in function `compute':
(.text+0xa5): undefined reference to `sin'
collect2: error: ld returned 1 exit status

Вот чтоУ меня так далеко.

Последовательность сборки библиотеки C следующая (подтверждено поставщиком библиотеки):

$ gcc -c something.c -o something.o
$ ar -r libsomethingLib.a something.o

Файл gpr библиотеки C something_lib_c.gpr:

library project Something_Lib_C is
   for Languages        use ("C");
   for Externally_Built use "true";
   for Source_Dirs      use ("src_c");
   for Library_Dir      use "lib_c";
   for Library_Name     use "somethingLib";
   for Library_Kind     use "static";
end Geocaging_Lib_C;

В каталоге lib_c у меня есть фактическая библиотека libsomethingLib.a

В каталоге src_c у меня есть API заголовка для использования библиотеки C (что-то .h):

#ifndef _GEOCAGING_H
#define _GEOCAGING_H

typedef struct something_s something_t;

extern void compute(something_t* const self);

#endif // _GEOCAGING_H

Тогда вот файл проекта Ada, который упаковывает библиотеку C something_lib.gpr:

with "something_lib_c.gpr";

project Something_Lib extends "../settings.gpr" is

   for Languages   use ("Ada");
   for Source_Dirs use ("./src_ada");
   for Object_Dir  use "obj" & "/" & Target & "/" & Build;

end Geocaging_Lib;

В каталоге src_ada у меня есть оболочка Ada API (something_api.ads):

with Interfaces;   use Interfaces;
with Interfaces.C; use Interfaces.C;

package Something_API is

   type T_Something is null record;

   procedure Compute (Something : access T_Something);
   with Import => True,
        Convention => C,
        External_Name => "compute";

end Something_API;

И, наконец, я вызываю службу вычислений из моей программы Ada с помощью обёртки Ada API.

Еще раз, при создании / компоновке всего этого для arm-eabitarget, с использованием stm32-full или stm32-sfp среды выполнения Ada, все работает хорошо, и поведение библиотеки проверяется.

Суть в том, что я хотел бы сделать это в родной среде, чтобы запустить на нем CI-тесты, и я не могу найти способ пройти этап соединения.

ПоследнийДело в том, что в универсальном файле проекта Settings.gpr содержатся некоторые общие ключи Ada build / bind / build, которые я могу предоставить при необходимости. Но я не могу понять, как это может работать на руку, а не на родной с теми же опциями. Это ДОЛЖНО быть связано со стандартным средством выполнения Ada ...

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 07 октября 2019

Если бы вы создавали основную программу на C, что бы вы сделали, чтобы добавить математические библиотеки во время компоновки? ... возможно что-то вроде

gcc foo.c -l somethingLib -lm

Что вам нужно сделать, это организовать включение -lm при каждом вызове в something_lib_c.gpr.

Я думаю, что вынужно сделать, это изменить library project Something_Lib_C, чтобы включить строку

for Library_Options use ("-lm");
1 голос
/ 08 октября 2019

ОК, мои ОГРОМНЫЕ извинения всем, кто пытался помочь ... Решение было более очевидным, чем я думал, я был слишком одержим тем, что работает в руках, а не в нативном.

НО, решение было просто добавить переключатель -lm к глобальным компоновщикам. Следовательно:

   Ada_Switches_Linker_Native := (
        "-Wl,--gc-sections"
        ,"-Wl,--verbose"
        ,"-Wl,-lm"
      );

   package Linker is
      case Target is
         when "native" =>
            for Switches ("Ada") use Ada_Switches_Linker_Native;

      ...

      end case;
   end Linker;

В случае, если это может быть интересно для кого-то еще, тот факт, что он работает просто в среде arm, а не в native, заключается в том, что среда выполнения default не включает конкретную математическую библиотеку ивы должны использовать C, предоставленный gcc, связывая через переключатель -lm.

Напротив, при использовании целевой среды выполнения, такой как arm (например, для stm32f4),предоставляются правильные математические библиотеки, которые выбираются и автоматически связываются в зависимости от параметров компиляции (-mhard-float, -msoft-float и т. д.).

Еще раз извините и большое спасибо за потраченное время.

...