gpt4 book ai didi

c - 如何在 CMake 文件中为 C/Ada 代码集成 gnatmake/gnatbind/gnatlink?

转载 作者:行者123 更新时间:2023-12-03 23:07:35 26 4
gpt4 key购买 nike

我用几种语言(C、C++、Fortran77、Fortran90)编写了一个代码,我可以使用 CMake 编译它而没有任何问题。它完美无缺。

现在,我想在用 C 编写的 main() 中添加一些 Ada 函数,我想用 CMake 编译它。鉴于我无法使用 CMake 将我的 Ada 函数链接到主要函数,我得到

main.c:(.text.startup+0x16a): undefined reference to adainit
main.c:(.text.startup+0x179): undefined reference to adafunction
main.c:(.text.startup+0x190): undefined reference to adafinal

我通过使用 main 函数(用 C 编写)调用我编码的唯一 Ada 函数进行了另一个简化测试,并使用
gcc -c main.c
gnatmake -c lib_ada.ali
gnatbind -n lib_ada.ali
gnatlink lib_ada.ali main.o -o exe

它奏效了。您知道我如何将这种方法集成到 CMakeList.txt 中吗?

注意:我认为(也许我错了)我不能使用唯一的 gnatlink,因为我需要链接我已经拥有的所有其他功能。

这里报告了一个最小的可重现示例。

--- main.c ---
#include <stdio.h>

extern int adainit();
extern int adafinal();
extern int Add(int,int);

int main()
{
adainit();
printf ("Sum of 3 and 4 is: %d\n", Add (3,4));
adafinal();

return 0;
}

--- lib_test.adb ---
package body Lib_Test is
function Ada_Add (A, B : Integer) return Integer is
begin
return A + B;
end Ada_Add;
end Lib_Test;

--- lib_test.ads ---
package Lib_Test is
function Ada_Add (A, B : Integer) return Integer;
pragma Export (C, Ada_Add, "Add");
end Lib_Test;

1°测试:如果您使用以下命令进行编译:
gcc -c main.c
gnatmake -c lib_test.adb
gnatbind -n lib_test.ali
gnatlink lib_test.ali main.o -o exe

并运行 ./exe你得到 Sum of 3 and 4 is: 7 .

2° 测试:我尝试使用以下 CMake 文件 (CMakeLists.txt) 链接 *.a
cmake_minimum_required(VERSION 2.6)
project(Ada2C)

enable_language(C)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -m64")

find_library(TEST_lib lib_test.a PATHS ${CMAKE_CURRENT_SOURCE_DIR})
message(STATUS "Finding library: ${TEST_lib}")
add_executable(TEST_release ${CMAKE_CURRENT_SOURCE_DIR}/main.c)
target_link_libraries(TEST_release ${TEST_lib})

我为 Ada 函数生成库 lib_test.a
gnatmake lib_test.adb
ar rc lib_test.a

我运行 cmakemake我得到
main.c:(.text.startup+0x16a): undefined reference to adainit
main.c:(.text.startup+0x179): undefined reference to adafunction
main.c:(.text.startup+0x190): undefined reference to adafinal

最佳答案

更多的是评论而不是答案,但评论太长了,所以这里是:

将 Ada 代码编译为二进制文件意味着您的二进制文件需要访问 GNAT 运行时。这是一回事gnatlink当您使用它链接最终的可执行文件时会这样做。另一件事是b~<something>.ad{s,b}来源gnatbind生成你需要编译和链接的其他人提到的。

到目前为止,我见过的将 Ada 嵌入到 C 中的最简洁方法是创建一个封装库。如果您的实际问题仅与一个 Ada 函数有关,这可能没有意义,但对于更大的 Ada 块,这可能没有意义。封装的库将是一个包含 GNAT 运行时的共享库。作为一个共享库,它可以在库加载期间隐式处理初始化,因此您不需要 adainit()/adafinal()了。

创建封装库的最简单方法是使用 ada_code.gpr文件:

project ada_code is
for Library_Name use "mylib";
for Library_Dir use "lib";
for Library_Kind use "relocatable";
for Library_Standalone use "encapsulated";
for Library_Auto_Init use "true";
for Library_Interface use ("All", "Packages", "In.Your", "Ada.Code");
for Source_Dirs use ("adasrc");
end ada_code;

在 CMake 中,您可以执行以下操作:
# tell CMake how to call `gprbuild` on the `.gpr` file.
# you may need to replace `gprbuild` with the absolute path to it
# or write code that finds it on your system.
add_custom_target(compile_mylib
COMMAND gprbuild -P ada_code.gpr)

# copy the library file generated by gprbuild to CMake's build tree
# (you may skip this and just link against the file in the source tree)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mylib.so
DEPENDS compile_mylib
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/lib/mylib.so
${CMAKE_CURRENT_BINARY_DIR}/mylib.so)

# ... snip ...

# link to the copied library
# I am not 100% sure this adds the correct dependency to the custom command.
# You may need to experiment a bit yourself
target_link_libraries(TEST_release ${CMAKE_CURRENT_BINARY_DIR}/mylib.so)

在您的 C 文件中,您可以删除与 adainit() 相关的所有内容。和 adafinal() .

关于c - 如何在 CMake 文件中为 C/Ada 代码集成 gnatmake/gnatbind/gnatlink?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61389071/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com