【问题标题】:Third Party Audio Library Linker Issues第三方音频库链接器问题
【发布时间】:2021-12-29 08:07:30
【问题描述】:

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

到目前为止我做了什么:

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

到目前为止,完成上述所有操作后,它确实可以编译,所以我已经完成了一半的工作。但是,我收到大量链接器错误,这些错误似乎是指缺少的函数(它们是 C/C++ 函数,而不是 Ada)。尽管我包括了所有相关文件并使它们可见。

这是编译器的结果(我已经从第一行裁剪了它,因为其余的只是同一目标文件中缺少函数定义的延续)。

*

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;

我的猜测是问题是由于链接器开关可能我需要在项目设置下切换,因此它可以将 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 中所示)。这可能是我缺少的“依赖”吗?我已经查看了下面的好心用户和 cmets 中提到的 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”也无效,这看起来很奇怪。

这是链接器错误的截断输出。

\Source\knightmare.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:\gnat\2021\bin\g++.exe main.o b__main.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\al_h.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\alc_h.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\enemy.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\oal_hpp.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\player.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\knightmare.o C:\Users\Amynu\OneDrive\Documents\Knig
htmare\Source\obj\snd.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\sndloop.o C:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\snd4ada.o libknightmare.a -LC:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\ -LC:\Users\Amynu\OneDrive\Documents\Knightmare\Source\obj\ -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 机器(它已经很老了),所以它也被排除在外了。

【问题讨论】:

  • 你的项目文件可能有问题吗?它与库提供的示例相比如何?
  • 嗯。唯一的区别是该示例使用了其他“with”包含。我也试过这个,但我得到了同样的错误。如果有帮助,这就是我的 GPR 文件的样子。
  • 如果您正在查看 github.com/fastrgv/Portable-OpenAL-Sound(示例代码在下载中,而不是在 repo 中!不是好的做法),您将看到 Linux 构建lcmp.sh 中的脚本;您的 GPR 需要反映这一点。查看您的示例 GPR,我完全不确定路径中是​​否有空格 ..External Libs/....。值得一提的是,macOS 构建脚本 ocmp.sh 惨败
  • 是的,我认为这就是问题所在。如何将此文件添加到我当前的 GPR?我不太了解 C 或 C++。难道只是C/P到正确的目录让GPR能找到的情况吗?
  • “macOS 构建脚本 ocmp.sh 惨败” - 因为它说的是 -lc++ 而不是 -lstdc++。谁知道呢。

标签: c++ c ada


【解决方案1】:

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 上使用链接器的注释掉的内容进行测试,请参阅 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/ 目录中,则此方法有效;如果你想将这里的代码用作库,那就有点复杂了,这意味着创建一个库项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-22
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多