Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C/Ada代码的CMake文件中集成gnatmake/gnatbind/gnatlink? 我用几种语言编写了代码(C,C++,forTr77,forTrn90),我可以用CGULE编译它而不出现任何问题。它运行得很好_C_Cmake_Ada_Gnat - Fatal编程技术网

如何在C/Ada代码的CMake文件中集成gnatmake/gnatbind/gnatlink? 我用几种语言编写了代码(C,C++,forTr77,forTrn90),我可以用CGULE编译它而不出现任何问题。它运行得很好

如何在C/Ada代码的CMake文件中集成gnatmake/gnatbind/gnatlink? 我用几种语言编写了代码(C,C++,forTr77,forTrn90),我可以用CGULE编译它而不出现任何问题。它运行得很好,c,cmake,ada,gnat,C,Cmake,Ada,Gnat,现在,我想在main()中添加一些Ada函数,它是用C编写的,我想用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

现在,我想在main()中添加一些Ada函数,它是用C编写的,我想用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---

---lib_test.ads---

1°测试:如果使用以下命令编译:

gcc -c main.c
gnatmake -c lib_test.adb
gnatbind -n lib_test.ali
gnatlink lib_test.ali main.o -o exe
然后运行
/exe
,得到
3和4之和为: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
我运行
cmake
make
得到

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~.ad{s,b}
source
gnatbind
生成您需要编译和链接的文件,如其他人所述

到目前为止,在C中嵌入Ada最干净的方法是创建一个封装的库。如果您的实际问题是只有一个Ada函数,那么这可能没有意义,但它确实适用于较大的Ada块。封装的库将是一个共享库,其中烘焙了GNAT的运行时。作为一个共享库,它可以在库加载期间隐式处理初始化,因此您不再需要
adainit()
/
adafinal()

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

项目ada_代码为
对于库名称,请使用“mylib”;
对于库目录,使用“lib”;
对于图书馆类,使用“可重新定位”;
对于库_独立使用“封装”;
对于库自动初始化,请使用“true”;
对于库_接口使用(“所有”、“包”、“您的”、“Ada.Code”);
供来源地使用(“adasrc”);
结束ada_代码;
在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()

相关的所有内容。我认为CMake不直接支持Ada,因此您必须手动运行这些命令,或者使用提供CMake Ada支持的第三方软件,如,链接包含adainit和friends的对象。这是由gnatbind自动生成的Ada源代码。使用类似于b~.ads/adb的名称,您可以在任何文本编辑器中检查它。您需要说服Cmake将其与其他Ada源代码一起编译,并链接生成的对象。我从来没有用过Cmake,所以我没办法。或者,您可以使用gnatlink将Fortran等中的.o文件链接到可执行文件中。@squareskittles我已经尝试过这种支持,非常好。我只使用ADA代码对它进行了测试,效果很好,但是,当我在“混合语言”代码中扩展它时,并没有得到同样好的结果。可能是我的错误,但我无法将C main函数中的ADA函数与该支持链接)@SimonWright你是对的,很抱歉拼写错误了ADA。我会更加注意使用正确的名字。谢谢你的澄清!我将用Ada编辑我的评论。您可以
添加自定义目标
+
添加自定义命令
而不是
查找库
,并在cmake中构建库。我不认为
ar-rc-lib_-test.a
会在没有太多工作的情况下工作。我认为最简单的方法是在调用
project()
之前,在
cmake
like
set(cmake\u C\u LINK\u EXECUTABLE gnatlink)
中将链接器更改为
gnatlink
。我想你可以让它工作-但是从Ada创建一个静态C库需要更多的工作。我真的很想感谢你!经过几次测试和一点实验,我用你发布的方法解决了我的问题。
gnatmake lib_test.adb
ar rc lib_test.a
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
# 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)