第三方音频库链接器问题



这完全是在黑暗中拍摄的,询问可能是浪费时间,但你永远不会知道。我正在使用GNAT Studio Community 2021(Ada2012(,并试图让一个音频库发挥作用。我很清楚没有专门用Ada编写的音频库,所以它当然是C、C++和一些Ada示例代码的混合。

到目前为止我所做的:

包括我需要的所有目录。勾选";语言;"框下";项目属性";以包括C和C++文件的使用,使它们可见。C/P所需的DLL(包括在音频库文件夹中(到";src";我项目的目录。

到目前为止,完成了上面的所有工作,它确实进行了编译,所以我已经完成了一半。然而,我收到了大量Linker错误,这些错误似乎指的是丢失的函数(它们是C/C++函数,而不是Ada函数(。尽管我将所有相关文件都包括在内,并使其可见,但情况依然如此。

以下是编译器的结果(我从第一行截取了它,因为剩下的只是同一个对象文件中缺少函数defs的延续(。

*

Compile
[Ada]          main.adb
Bind
[gprbind]      main.bexch
[Ada]          main.ali
Link
[link]         main.adb
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe:
libamos.a(oal.o):oal.cpp:(.text+0x10): undefined reference to
`__imp_alcOpenDevice'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe:
libamos.a(oal.o):oal.cpp:(.text+0x4c): undefined reference to
`__imp_alcCreateContext’

以下是我为测试是否一切正常而编写的代码。

with al_h;
with alc_h;
with snd;
with snd4ada;
with sndloop;

procedure Main is
begin
null;
end Main;

以下是库附带的工作代码,供参考。

with text_io; use text_io;
with snd4ada;
with interfaces.c;
with interfaces.c.strings;
with ada.command_line;
procedure one is
-- plays WAV file given on command line
subtype glint is interfaces.c.int;
linestr: string(1..80);
last: natural;
music: glint;
begin
if ada.command_line.argument_count = 1 then
declare
title : string := Ada.Command_Line.Argument(1);
begin --declare

snd4ada.initSnds;
music:=snd4ada.initLoop( 
interfaces.c.Strings.New_string(title));

put_line("Hit <enter> to begin");
get_line(linestr,last);
snd4ada.playLoop(music);
put_line("hit <enter> to end");
get_line(linestr,last);
snd4ada.stopLoop(music);
snd4ada.termSnds;
end; --declare
end if;
end one;

我的猜测是,这个问题是由于Linker开关造成的,也许我需要在项目设置下切换,这样它就可以将C、C++和Ada代码绑定在一起。

我只是在为一个失败的事业而战吗?我很想让它发挥作用,似乎我唯一的问题是告诉链接器声明在哪里(尽管我已经将所有相关文件都包含在项目路径中(。

如果有人能帮忙,我会非常高兴。如果我知道如何为Ada编写自己的音频库,但第三方似乎是唯一的选择。顺便说一句,我确实试着让BASS工作,但那是不可能的。这是最接近工作的一个,它很烦人,因为示例代码生成了一个确实可以工作的.exe。所以这一定是我对林克做的不对。

编辑

这是我的GPR文件的内容。

project Amos is
for Source_Dirs use ("src", "External Libs/adaOal19oct21/adaOpenAL", "External Libs/adaOal19oct21/adaOpenAL/OalBinding", "External Libs/adaOal19oct21/adaOpenAL/OalBinding/incoal");
for Object_Dir use "obj";
for Main use ("main.adb");
for Languages use ("Ada", "C", "C++");
end Amos;

大家好。是的,我仍在争取Ada Open AL参与GNAT 2021社区版的工作。我一直在摆弄一些东西,但运气不好。我的一个朋友是Ada开发人员,他说他可以让它在使用Windows NT的旧IDE上工作吗?

我不断地更改我的GPR文件。同样,所有的东西都通过了编译器,但在链接器上失败了,因为它找不到对象文件,即使我已经添加了所有的开关。这是我当前的GPR文件。

project Knightmare is
for Source_Dirs use ("src", "../Libs/adaOpenAL", "../Libs/adaOpenAL/OalBinding", "../Libs/adaOpenAL/OalBinding/incoal");
for Object_Dir use "obj";
for Main use ("main.adb");
for Languages use ("Ada", "C", "C++");
package Linker is
for Switches ("c++") use ("g++", "-c", "-fdump-ada-spec", "-C", "oal.hpp", "-Iincoal");
end Linker;
package Compiler is
for Switches ("c++") use ("g++", "-c", "../OalBinding/oal.cpp", "/-std=c++11", "/-fpermissive",
"/-I..", "/-I../OalBinding", "/-I../OalBinding/incoal");
end Compiler;
end Knightmare;

在";项目属性";是Ada、C和C++。所有必需的文件夹都包含在内(如GPR中所示(。它可能是一个";依赖关系";我失踪了?我已经看过下面和评论中好心用户提到的SH(shell脚本(,但我无法将shell脚本添加到项目中,因为它说我没有编译器来处理它。然而,我今天确实找到了这个文件,这可能是问题所在。

rm *.o
rm obj/*

g++ -c ../OalBinding/oal.cpp 
-std=c++11 
-fpermissive 
-I.. 
-I../OalBinding 
-I../OalBinding/incoal

gnatmake $1 
-D obj 
-I.. -I../OalBinding 
-largs 
-lc++ 
oal.o 

-framework CoreAudio 
-framework AudioUnit 
-framework AudioToolBox 
-framework OpenAL 
-pthread 

这就是链接器想要绑定的内容吗?如果是,我该如何告诉Ada/C/C++链接器这样做?哦,出于某种原因-pthread";也无效,这似乎很奇怪。

以下是链接器错误的剪切输出。

Sourceknightmare.gpr
Bind
[gprbind]      main.bexch
[Ada]          main.ali
Link
[link]         main.adb
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x10): undefined reference to `__imp_alcOpenDevice'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x4c): undefined reference to `__imp_alcCreateContext'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x6c): undefined reference to `__imp_alcMakeContextCurrent'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x88): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x9d): undefined reference to `__imp_alGenBuffers'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0xa6): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x113): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x13c): undefined reference to `__imp_alBufferData'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x145): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x1a8): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x1bd): undefined reference to `__imp_alGenSources'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x1c6): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x22b): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x245): undefined reference to `__imp_alSourcei'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x24e): undefined reference to `__imp_alGetError'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x2be): undefined reference to `__imp_alDeleteSources'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x2d3): undefined reference to `__imp_alDeleteBuffers'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x2f7): undefined reference to `__imp_alcDestroyContext'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x307): undefined reference to `__imp_alcCloseDevice'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x325): undefined reference to `__imp_alSourceStop'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x343): undefined reference to `__imp_alSourcePlay'
c:/gnat/2021/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.1/ld.exe: libknightmare.a(oal.o):oal.cpp:(.text+0x36d): undefined reference to `__imp_alGetSourcei'
collect2.exe: error: ld returned 1 exit status
gprbuild: link of main.adb failed
gprbuild: failed command was: c:gnat2021bing++.exe main.o b__main.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjal_h.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjalc_h.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjenemy.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjoal_hpp.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjplayer.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjknightmare.o C:UsersAmynuOneDriveDocumentsKnig
htmareSourceobjsnd.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjsndloop.o C:UsersAmynuOneDriveDocumentsKnightmareSourceobjsnd4ada.o libknightmare.a -LC:UsersAmynuOneDriveDocumentsKnightmareSourceobj -LC:UsersAmynuOneDriveDocumentsKnightmareSourceobj -LC:/gnat/2021/lib/gcc/x86_64-w64-mingw32/10.3.1/adalib/ C:/gnat/2021/lib/gcc/x86_64-w64-mingw32/10.3.1/adalib/libgnarl.a C:/gnat/2021/lib/gcc/x86_64-w64-mingw32/10.3.1/adalib/libgnat.a -Xlinker --stack=0x200000
,0x1000 -mthreads -shared-libgcc -o main.exe
[2021-11-24 10:53:20] process exited with status 4, 100% (11/11), elapsed time: 01.42s
Could not execute "debug set line breakpoint"

我知道我快要把它发挥作用了。我甚至给Ada Open Al的创作者发了电子邮件,但已经三天没有人回复我了。在GNAT 2021社区下,关于如何让它发挥作用的youtube视频为零,而网络上的少量信息非常稀少,毫无帮助。

如果有人能给我一个可能的解决方案,我会永远为它感到高兴。顺便说一句,我知道Ada有一个SDL绑定,但它只适用于Win32机器(它很旧(,所以这也是不可能的。

lcmp.sh包含

rm *.o
rm obj/*

# first, create oal.o:
g++ ../OalBinding/oal.cpp -c 
-D obj 
-I.. 
-I../OalBinding 
-I../OalBinding/incoal

gnatmake $1 -o $1_gnu 
-D obj 
-O3 -gnat12 -I.. -I../OalBinding 
-largs 
oal.o 
-lstdc++ 
-lopenal -lpthread

所以我希望你的GPR使用gprbuild -P sample:包含这一点(在macOS上测试,使用包Linker的注释内容,请参阅ocmp.sh(

project Sample is
for Languages use ("ada", "c++");
for Object_Dir use "obj";
for Create_Missing_Dirs use "true";
for Source_Dirs use (".", "..", "../OalBinding");
for Main use ("one.adb", "two.adb");
for Exec_Dir use ".";  -- unless you want the executables in Object_Dir!
package Compiler is
for Default_Switches ("ada") use ("-O3", "-gnat12");
--  You'd have thought that these switches should be "-I..",
--  "-I../OalBinding" etc; sadly, the compilation is run from
--  the Object_Dir, ./obj, so the include directories are one
--  more level up.
--
--  Someone put me right if there's a better way to do this!
for Default_Switches ("c++") use
("-I../..", "-I../../OalBinding", "-I../../OalBinding/incoal");
end Compiler;
package Linker is
for Default_Switches ("ada") use
("-lstdc++", "-lopenal", "-lpthread");
-- These are the linker switches for macOS, see ocmp.sh.
-- for Default_Switches ("ada") use
--   ("-lstdc++",
--    "-framework", "CoreAudio",
--    "-framework", "AudioUnit",
--    "-framework", "AudioToolBox",
--    "-framework", "OpenAL");
end Linker;
end Sample;

如果您的测试程序位于adaExample/目录中,则此操作有效;如果您想将这里的代码用作库,这意味着要创建一个库项目,那么它会变得有点复杂。

最新更新