0

I have a compiled static library of raylib : raylib.lib. I compiled this library myself with Librarian > General > Additional Dependencies: winmm.lib

This library has a C function like the following:

void CloseWindow(void);

And I also have my very basic C++ project that uses raylib:

// main.cpp
#include "raylib.h"

int main()
{
    InitWindow(100, 100, "");
    while (!WindowShouldClose())
    {
        BeginDrawing();
        ClearBackground(RAYWHITE);
        EndDrawing();
    }
    CloseWindow();
    return 0;
}

Now, when I compile my project with Linker > Additional Dependencies set to:

  • raylib.lib; user32.lib; shell32.lib; gdi32.lib

It compiles and links without any warning.

But when I swap the order of raylib.lib and user32.lib:

  • user32.lib; raylib.lib; shell32.lib; gdi32.lib

Then I get a linker error:

Link:
  D:\Visual Studio Community 2019\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe 
  /ERRORREPORT:QUEUE /OUT:"bin\MyProject.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:bin 
  user32.lib raylib.lib shell32.lib gdi32.lib winmm.lib /MANIFEST 
  /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FULL 
  /PDB:"bin\MyProject.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE
  /NXCOMPAT /IMPLIB:"bin\MyProject.lib" /MACHINE:X64 obj\Release\MyProject\main.obj
raylib.lib(core.obj) : error LNK2005: CloseWindow already defined in user32.lib(USER32.dll) [D:\example\MyProject.vcxproj]
bin\MyProject.exe : fatal error LNK1169: one or more multiply defined symbols found [D:\example\MyProject.vcxproj]

So how is this possible that it's already defined? Why does the linking order matter?

UPDATE

When I compiled raylib with Librarian > General > Additional Dependencies: winmm.lib; user32.lib then I get this warning (when compiling the library):

Lib:
  D:\Visual Studio Community 2019\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\Lib.exe /OUT:"bin\raylib.lib" winmm.lib user32.lib /NOLOGO /MACHINE:X64 obj\Release\raylib\core.obj
  obj\Release\raylib\models.obj
  obj\Release\raylib\raudio.obj
  obj\Release\raylib\rglfw.obj
  obj\Release\raylib\shapes.obj
  obj\Release\raylib\text.obj
  obj\Release\raylib\textures.obj
  obj\Release\raylib\utils.obj
user32.lib(USER32.dll) : warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in winmm.lib(WINMM.dll); second definition ignored [D:\example\raylib.vcxproj]
raudio.obj : warning LNK4006: PlaySound already defined in winmm.lib(WINMM.dll); second definition ignored [D:\example\raylib.vcxproj]
core.obj : warning LNK4006: CloseWindow already defined in user32.lib(USER32.dll); second definition ignored [D:\example\raylib.vcxproj]
core.obj : warning LNK4006: ShowCursor already defined in user32.lib(USER32.dll); second definition ignored [D:\example\raylib.vcxproj]

Having raylib compiled this way MyProject does not need to link with user32.lib and it works.

What is the best way to use raylib in this situation? Should I always compile raylib with it's dependencies (user32.lib etc.) and get those warnings or maybe I should link with them later when MyProject is compiled (then I need to make sure that raylib is linked before it's dependencies)?

Kyriet
  • 401
  • 5
  • 8
  • 1
    Both version of `CloseWindow` are `extern "C"` or just straight C so there is no overloading on parameters and both have the same exported name. If it ever links it's 50-50 which is actually function is called. This is an example of breaking the ODR rule. – Richard Critten Aug 18 '21 at 20:17
  • You can ask the linker for verbose output and trace the fixe-up through. Breaking the ODR _"...The compiler is not required to diagnose this violation, but the behavior of the program that violates it is undefined...."_ https://en.cppreference.com/w/cpp/language/definition – Richard Critten Aug 18 '21 at 20:21
  • (This is MSVC-specific) Duplicate *import* symbols (symbols pointing to a DLL) are allowed, but duplicate static symbols are not. Once a symbol is resolved, subsequent *import* symbols with the same name are ignored. With that said, using an export name that conflicts with a WinAPI name is a recipe for a headache. – rustyx Aug 18 '21 at 20:36
  • As you are compiling your own version of __raylib__ I suggest you edit it and change the name of it's `CloseWindow` function. – Richard Critten Aug 18 '21 at 20:45

0 Answers0