Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

v10: MinGW DLL build behavior change

Aperta
#967 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
42/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Ferma
Stack tecnologico
cpp
Ambito
build-system

Direzione di ricerca

Start from the export macro block in the public header and the _WIN32/_MSC_VER condition changed by commit cc4c1df7; the reproduction in the issue (a link_test.h with LINK_TEST_API) shows the pattern. Build the library as a DLL with MinGW and compare exported symbols with Dependencies or objdump -p. Done means public classes are exported again on MinGW while non-API classes stay hidden, and the MSVC output is unchanged. The maintainer has not replied, so confirm the intended fix before writing a patch.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

The commit https://github.com/leethomason/tinyxml2/commit/cc4c1df7ec28101eaacc6388cd8a0a857bffd297 caused a huge change in how DLLs are built on MinGW.

Previously, #ifdef _WIN32 was used to check for Windows, and then __declspec(dllexport) and __declspec(dllimport) were used to declare the public API as exported / imported from DLLs. GCC/MinGW also supports those attributes, and everything worked fine.

That specific commit (without any explanation why this was broken before) now changed that to detect just MSVC, and not any Windows system. This is problematic, because

  • There are other compilers than MSVC and MinGW on Windows, and to my knowledge all support the __declspec Syntax for DLLs.
  • MinGW now uses __attribute__((visibility("default"))), which as no effect at all.

This means that on MinGW after this change no public APIs are marked as exported in the DLL.

Now due to a quirk of GCC this doesn't mean the DLL doesn't work at all, because if GCC compiles a DLL that contains no symbols that are exported, it will assume that all symbols are exported. But this also means that symbols that were not explicitly marked as exported are now exported on MinGW (while they aren't on MSVC).

To demonstrate the behavior, I've created the following test program:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(link_test VERSION 1.0)

set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)

option(NO_DECLSPEC_MINGW "Don't use __declspec(dllimport/dllexport) on MinGW" OFF)

add_library(link_test link_test.cpp link_test.h)
target_compile_definitions(link_test
    PUBLIC $<$<BOOL:${NO_DECLSPEC_MINGW}>:NO_DECLSPEC_MINGW>
    INTERFACE $<$<BOOL:${BUILD_SHARED_LIBS}>:LINK_TEST_IMPORT>
)
set_target_properties(link_test PROPERTIES DEFINE_SYMBOL "LINK_TEST_EXPORT")

link_test.h:

#ifndef LINK_TEST_H
#define LINK_TEST_H

#if defined(_WIN32) && (!defined(__GNUC__) || !defined(NO_DECLSPEC_MINGW))
#  if defined(LINK_TEST_IMPORT)
#    define   LINK_TEST_API     __declspec(dllimport)
#  elif defined(LINK_TEST_EXPORT)
#    define   LINK_TEST_API     __declspec(dllexport)
#  else
#    define   LINK_TEST_API
#  endif
#elif __GNUC__ >= 4
#  if defined(LINK_TEST_IMPORT) || defined(LINK_TEST_EXPORT)
#    define   LINK_TEST_API     __attribute__((visibility("default")))
#  else
#    define   LINK_TEST_API
#  endif
#else
#  define   LINK_TEST_API
#endif

class LINK_TEST_API DemoClass {
public:
    int getFoo();
};

class NonExportedClass {
public:
    int getBar();
};

#endif // LINK_TEST_H

link_test.cpp:

#include "link_test.h"

int DemoClass::getFoo()
{
    return 42;
}

int NonExportedClass::getBar()
{
    return 23;
}

The DLL compiled with __declspec(dllexport) exports the following symbols (using https://github.com/lucasg/Dependencies):
image

The DLL compiled with __attribute__((visibility("default"))) exports the following symbols:
image

In the future this could be even more problematic: if GCC decides to stop exporting all symbols in DLLs without an explicit dllexport marking at some point in the future (don't know if that's planned at all or why GCC behaves like this currently, but it could happen), then the current logic would mean that tinyxml2's DLL would then export no symbols at all.

In my eyes the previous check #ifdef _WIN32 was correct, and I have compiled tinyxml2 on MinGW as a DLL for a couple of years now, without any issues. I think this change should therefore be reverted.

Lingua principale
C++
Stelle
5.8k
Fork
2k
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di leethomason/tinyxml2

Tutte le issue di leethomason/tinyxml2

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.