#1273·cpr

Add Symbol Visibility for Windows DLLs

Author: stephanlachnitCreated Nov 17, 2025Updated Nov 29, 2025
LabelsFeature :sparkles:Windows :tv:

Is your feature request related to a problem?

Buildings a shared library on Windows will results in a DLL without symbols, since MSVC always hides symbols and cpr has no explicit symbol visibility markers. See also https://github.com/mesonbuild/wrapdb/pull/2436. Unfortunately, MSVC can't be teached to make all symbols public by default, so this is something which needs to be fixed in the project.

Possible Solution

Functions and classes which are part of the public ABI should have a symbol visibility marker.

This requires the following definitions

cpp
#if defined _WIN32 || defined __CYGWIN__
#define CPR_DLL_EXPORT __declspec(dllexport)
#define CPR_DLL_IMPORT __declspec(dllimport)
#define CPR_DLL_LOCAL
#else
#define CPR_DLL_EXPORT [[gnu::visibility("default")]]
#define CPR_DLL_IMPORT [[gnu::visibility("default")]]
#define CPR_DLL_LOCAL [[gnu::visibility("hidden")]]
#endif

#ifndef CPR_STATIC
#ifdef CPR_BUILDLIB
#define CPR_PUBLIC CPR_DLL_EXPORT
#define CPR_PRIVATE CPR_DLL_LOCAL
#else
#define CPR_PUBLIC CPR_DLL_IMPORT
#define CPR_PRIVATE CPR_DLL_LOCAL
#endif
#else
#define CPR_PUBLIC
#define CPR_PRIVATE
#endif

During building CPR_BUILDLIB needs to be defined, and if a static library is built, CPR_STATIC needs to be defined as well. For usage, CPR_STATIC needs to be defined if the static library is linked, otherwise no definitions are required.

This code snippet introduces two macros:

  • CPR_PUBLIC for the public API
  • CPR_PRIVATE to explicitly hide a symbol

In practice this looks something like:

cpp
CPR_PUBLIC void some_public_function();

class CPR_PUBLIC some_class {
public:
    void some_public_function();
private:
    CPR_PRIVATE void some_function_only_used_in_cpp();
private:
    int some_member;
};

One advantage of doing this is that this can reduce the size of the shared library since it now only exports the symbols which are actually part of the public API (requires -fvisibility=hidden on GCC & clang).

Alternatives

Only support static library builds on Windows.

Additional Context