Skip to content

fix(Net): export pocoNetworkInitializer when built with clang-cl #5368#5369

Open
pavledragisic wants to merge 2 commits into
mainfrom
5368-net-poconetworkinitializer-not-exported-when-poconetdll-is-built-with-clang-cl
Open

fix(Net): export pocoNetworkInitializer when built with clang-cl #5368#5369
pavledragisic wants to merge 2 commits into
mainfrom
5368-net-poconetworkinitializer-not-exported-when-poconetdll-is-built-with-clang-cl

Conversation

@pavledragisic
Copy link
Copy Markdown
Member

No description provided.

@matejk
Copy link
Copy Markdown
Contributor

matejk commented May 28, 2026

Alternative approach worth considering

The consumer-side /INCLUDE:pocoNetworkInitializer machinery in Net.h exists only to force-reference the pocoNetworkInitializer global so its constructor (NetworkInitializer::NetworkInitializer() in Net.cpp, which calls WSAStartup) runs. For a CMake-managed shared build that is redundant: target_link_libraries(consumer PocoNet) makes PocoNet.dll a load-time dependency, and the Windows loader runs CRT init for the DLL, which invokes that constructor for every consumer regardless of whether the symbol is referenced. Per the MSVC runtime docs, on process attach _DllMainCRTStartup "initializes and calls constructors for static and nonlocal data" (source).

Two small changes would resolve #5368 without the __imp_ ladder:

  1. Foundation/CMakeLists.txt: set POCO_NO_AUTOMATIC_LIBS PUBLIC for every Win32 CMake build, not just clang-cl. There is no MSVC vs clang-cl difference here -- under CMake the build system handles linking either way, and clang-cl is MSVC-ABI compatible and honors __declspec(dllexport) / /EXPORT the same way (Clang MSVC compatibility). The clang-cl-only condition is what currently makes MSVC users still rely on the pragma path.

    if(WIN32)
        target_compile_definitions(Foundation PUBLIC
            POCO_OS_FAMILY_WINDOWS UNICODE _UNICODE POCO_NO_AUTOMATIC_LIBS)
        target_link_libraries(Foundation PUBLIC iphlpapi)
    endif()
  2. Net/include/Poco/Net/Net.h: short-circuit the force-symbol under that flag for the shared consumer:

    #if defined(POCO_NO_AUTOMATIC_LIBS) && defined(POCO_DLL) && !defined(Net_EXPORTS)
        // CMake-managed shared consumer: PocoNet.dll's loader runs
        // NetworkInitializer::NetworkInitializer() automatically.
        #define POCO_NET_FORCE_SYMBOL(s)
    #elif defined(POCO_COMPILER_MINGW) || defined(__clang__)
        // ...existing arms unchanged...

Why this is attractive:

  • No producer-side rework, no __imp_ mangling, one added arm.
  • Aligns MSVC and clang-cl CMake builds on the same well-understood DLL-load path.
  • Static-lib paths keep working: `POCO_DLL` is unset for static builds, so the existing `clang` static-pointer arm still fires. That reference is what pulls `Net.obj` from the archive -- per the MSVC linker docs, `/INCLUDE` "resolves symbol by adding the object that contains the symbol definition to the program ... useful for including a library object that otherwise would not be linked" (source), and the static-pointer trick has the same effect at the source level.

Known limitation: a clang-cl-built `PocoNet.dll` consumed by a non-CMake project without `POCO_NO_AUTOMATIC_LIBS` (e.g. an MSVC solution using the auto-link pragmas) would still hit `LNK2001` because the DLL itself does not export the symbol. This PR also fixes that mixed-toolchain case; the alternative does not. `#pragma comment(linker, "/export:...")` is the documented MSVC way to export and is one of four supported export methods (/EXPORT docs), so PR #5369's producer-side approach is correct on its own merits.

Just sharing as an option.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes automatic Net initialization symbol handling for clang-cl/MSVC-compatible Windows builds by ensuring pocoNetworkInitializer has external C linkage and the correct import/export forcing behavior.

Changes:

  • Exports/imports pocoNetworkInitializer consistently via extern "C" and Net_API.
  • Routes clang-cl through the MSVC linker pragma path instead of the generic Clang/GCC path.
  • Uses the correct /include: target for DLL consumers by referencing __imp_ import symbols.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
Net/src/Net.cpp Updates the initializer definition to match the exported declaration.
Net/include/Poco/Net/Net.h Adjusts compiler detection and linker include paths for static vs DLL Net consumers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Net: pocoNetworkInitializer not exported when PocoNet.dll is built with clang-cl

3 participants