2

I'm trying to link to the OpenAL soft library as compiled with the Media Autobuild Suite, and I'm getting the following error from Visual Studio:

libopenal.a(source.cpp.o) : fatal error LNK1143: invalid or corrupt file: no symbol for COMDAT section 0xA

My application is in C++ and compiled directly in Visual Studio 2019 (however, with the VS2017 toolset). OpenAL soft is written in C++ but exposes a C interface, and the MAB Suite compiles using MinGW/gcc and generates a libopenal.a static library file.

I've read from multiple other questions such as From MinGW static library (.a) to Visual Studio static library (.lib) and How to use libraries compiled with MingW in MSVC? that object files compiled with different compilers are generally not compatible for C++ due to name mangling, but often are compatible with C linkage. Because C does not use name mangling, and because the ABI is (usually) OS-dependent, libraries with a C interface compiled on the same platform are generally compatible.

Nevertheless, I've been running into linker errors, namely the LNK1143 above. I've confirmed that the included headers use extern "C" { to hint C linkage and that the target platform (x64) is the same for both builds. I also linked to libgcc.a as this answer recommends, and did not get any linker errors for it.

Does this mean the claim that C interfaces are generally compatible across compilers is not true? Or is this a special case in which it's not working? If the latter, what could be causing the linking to fail? Would I have better luck if I recompiled as shared libraries (dlls) instead of static libraries (even if I still use MinGW's .a files instead of .lib)?

I cannot change compilers from MSVC for my main app. I intend to use more libraries from the MAB Suite in the future, so I'd prefer to stay with MinGW for those dependencies if possible because I don't want to recompile all 70+ by hand.

Any help is appreciated. Thanks in advance.

TheTrueJard
  • 471
  • 4
  • 18
  • 1
    I think you are out of luck, see: https://social.msdn.microsoft.com/Forums/vstudio/en-US/215c8613-8c33-4f6e-b1f4-8929eaa41a06/fatal-error-lnk1143-invalid-or-corrupt-file?forum=vcgeneral and https://learn.microsoft.com/en-gb/windows/win32/debug/pe-format?redirectedfrom=MSDN#comdat-sections-object-only. That post is rather old, but it looks like nothing has changed. Maybe it is the case that _some_ mingw object files will link but not others. That seems to be the evidence, anyway. – Paul Sanders Jun 13 '21 at 00:06
  • Can you build the library with MSVC ? It seems to be a cmake project and says it started off as a windows-only library . – M.M Jun 13 '21 at 01:21
  • https://stackoverflow.com/questions/2529770/how-to-use-libraries-compiled-with-mingw-in-msvc seems to cover the question asked – M.M Jun 13 '21 at 01:24
  • @M.M I already referenced that question in my question, and my experience conflicts with those answers which is why I'm confused. I'd like to keep using MinGW for the library if possible because the [suite I'm using to compile it](https://github.com/m-ab-s/media-autobuild_suite) also builds 70+ other dependencies that I intend to use in the future and I don't want to rebuild them by hand. Right now it's looking like that might not be possible though – TheTrueJard Jun 13 '21 at 01:35
  • 1
    Yes, with shared libraries it should work (and I'm pretty sure this is what is meant with compatible C interfaces). – ssbssa Jun 14 '21 at 10:33

2 Answers2

1

Mixing compilers is tricky and prone to issues.

In some very simple cases it may work, but there are definitely a number of cases where you will run in to issues, for example:

  • if the different components use different runtime libraries
  • if memory management is being mixed (e.g. forget about freeing memory allocated with malloc() in MSVC using free() in MinGW)
  • when using exception handling in C++

My advice to do it all with the same compiler (and even the same version of this compiler).

Specifically in your case OpenAL can be built with MinGW-w64. So maybe you should look into that instead of downloading some prebuilt version from the web.

Or - somewhat easier - use MSYS2 and use its pacman package manager to get its own MinGW-w64 build of OpenAL.

Brecht Sanders
  • 6,215
  • 1
  • 16
  • 40
0

I figured out what works for me, so I'll share.

I was not able to link a static library between compilers as I originally attempted. My understanding is that the extra info kept in the lib to allow link-time code generation is compiler-specific. Brecht Sanders's answer outlines a few possible reasons why the code wouldn't be compatible.

I was, however, able to link to a shared library, with a few extra steps.

Using the same suite (see the question), I compiled as shared and got libopenal.dll, libopenal.dll.a, and libopenal.def. In my case, the .def file was generated by the suite. Accoding to this answer, you can generate a .def file with gcc using:

gcc -shared -o your_dll.dll your_dll_src.c -Wl,--output-def,your_dll.def

Trying to link to libopenal.dll.a still gave me errors (I don't know exactly why, and I already discarded the logs.) What I did instead was generate a .lib file from the .def file. In Visual Studio's built-in terminal:

lib /machine:x64 /def:libopenal.def

This generated a libopenal.lib file in the working directory. Linking to this file worked perfectly, and I was able to successfully load the dll at runtime.

I've tested this same method with many other MinGW-compiled libraries from the suite, including libavformat, libavcodec, libavutil, libavdevice, swresample, and swscale, and thus far all of them have worked.

Kind of convoluted, but it seems to work well for me, so I hope this helps anyone else with the same problem.

TheTrueJard
  • 471
  • 4
  • 18