Q: Multiple definitions when linking to exe with MinGW When linking an exe directly to a dll with MinGW everything is fine. But when it is otherwise (linking dll directly to an executable), I get multiple definitions errors:
FAILED: liblib.dll liblib.dll.a 
cmd.exe /C "cd . && C:\msys64\mingw64\bin\c++.exe -g   -shared -o liblib.dll -Wl,--out-implib,liblib.dll.a -Wl,--major-image-version,0,--minor-image-version,0 CMakeFiles/lib.dir/lib.cpp.obj  app.exe  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe: in function `atexit':
C:/_/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:420: multiple definition of `atexit'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:C:/_/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtdll.c:205: first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:cygming-crtbegin.c:(.text+0x520): multiple definition of `__gcc_register_frame'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/crtbegin.o:cygming-crtbegin.c:(.text+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:cygming-crtbegin.c:(.text+0x530): multiple definition of `__gcc_deregister_frame'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/crtbegin.o:cygming-crtbegin.c:(.text+0x10): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x400): multiple definition of `.refptr.__native_startup_state'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__native_startup_state[.refptr.__native_startup_state]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:C:/_/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:424: multiple definition of `__mingw_module_is_dll'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:C:/_/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtdll.c:209: first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x430): multiple definition of `.refptr.__xi_a'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__xi_a[.refptr.__xi_a]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x3f0): multiple definition of `.refptr.__native_startup_lock'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__native_startup_lock[.refptr.__native_startup_lock]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x380): multiple definition of `.refptr.__dyn_tls_init_callback'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__dyn_tls_init_callback[.refptr.__dyn_tls_init_callback]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x4b0): multiple definition of `.refptr.mingw_app_type'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.mingw_app_type[.refptr.mingw_app_type]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:crtexe.c:(.idata+0x310): multiple definition of `__imp__ZSt4cout'; app.exe:crtexe.c:(.idata+0x310): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x410): multiple definition of `.refptr.__xc_a'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__xc_a[.refptr.__xc_a]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x440): multiple definition of `.refptr.__xi_z'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__xi_z[.refptr.__xi_z]+0x0): first defined here
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: app.exe:main.cpp:(.rdata+0x420): multiple definition of `.refptr.__xc_z'; C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o:crtdll.c:(.rdata$.refptr.__xc_z[.refptr.__xc_z]+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

// app.h

#pragma once

void printHello();

template <typename T>
T sum(const T& a, const T&b)
{
    return a + b;
}

extern template int sum(const int& a, const int& b);

// main.cpp

#include "app.h"

#include <iostream>

void printHello()
{
    std::cout << "hello" << std::endl;
}

template int sum(const int& a, const int& b);

int main()
{
    return 0;
}

// lib.cpp

#include "app.h"

static void internal_function()
{
    printHello();
    int a = sum(4, 8);
}

# CMakeLists.txt

add_library(lib SHARED lib.cpp)
add_executable(app main.cpp)
target_link_libraries(lib PRIVATE $<TARGET_FILE:app>)

How can I fix it?

The reason for this question is the strange behavior of MinGW with inlined member functions: it does not export any symbols to a static library when the above code is compiled (given that __declspec(dllexport) is added). I have already asked a question on that part.
In that case cmake would be:
# CMakeLists.txt

add_library(lib SHARED lib.cpp)
add_executable(app main.cpp)
set_target_properties(app PROPERTIES ENABLE_EXPORTS 1)
target_link_libraries(lib PRIVATE app)

But this is not what this question is about.

Yet another reason to link against an executable directly comes from a bug in MinGW linker. When linking to a MSVC compiled static library with exported symbols (importing C functions), the linker might create an empty import table. When implementing a Node JS addon you have to link against an executable (node js core.exe), this question describes the topic. The solution would be to link against an executable directly.
