--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/harbour-users/3c96ae79-9783-4f31-a99b-93c299362dc5%40googlegroups.com.
This section is a bit raw and I will share a detailed version soon.
Download the latest curl source (curl-8.17.0) from curl.se
Build static packages from source
-------------------->8---------------->8--------------->8--------------->8--------------->8--------------->8--------------->8--------------->8------------- [ pre-built binary available at https://github.com/curl/curl-for-win#binary-package-downloads ]
Building all required libraries (zlib, Brotli, nghttp2, libpsl) as static from source while keeping OpenSSL as a dynamic dependency is a highly effective way to create a portable libcurl-4.dll.
This "hybrid" approach ensures your DLL contains its internal logic but can still be updated for security patches by simply replacing the OpenSSL DLLs.
1. brotli 1.2.0 --- configure
2. cacert 2025-12-02 --- downloaded --- Place cacert.pem in your curl bin directory or point to it via --with-ca-bundle. --with-ca-bundle=FILE - Absolute path to a file containing CA certificates (example: /etc/ca-bundle.crt) or --with-ca-path=DIRECTORY --- check configure --help for additional information
3. curl 8.17.0 --- ok
4. libpsl 0.21.5 --- done -
5. libressl 4.2.1 --- downloaded --with-ssl=/libressl....?
6. libssh2 1.11.1 --- downloaded
7. nghttp2 1.68.0 --- configure
8. nghttp3 1.14.0 --- downloaded
9. ngtcp2 1.19.0 --- downloaded
10. psl 2025-10-16 --- public_suffix_list.dat with a long list of 2LDs
11. trurl 0.16.1 --- downloaded --- for details --- https://github.com/curl/trurl .
12. zlibng 2.3.2 --- configure --- zlib-ng(next generation) is a fork of original zlib and considered to be faster. The original zlib is more portable.
13. zstd 1.5.7 --- downloaded
------------------8<----------------8<----------------8<----------------8<----------------8<----------------8<----------------8<----------------8<------------
Build the Static Dependencies
For each library, ensure you compile with the correct flags to produce clean static archives without dynamic "pollution."
zlib: Use ./configure --static --prefix=/d/HarbourBuild/static_deps/zlib1
Brotli: Use cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=/d/HarbourBuild/static_deps/brotli
nghttp2: Use ./configure --enable-static --disable-shared --prefix=/d/HarbourBuild/static_deps/nghttp2
libpsl: As you have already discovered, building from source is essential to avoid the _imp__ symbol mismatch. Use:
$ ./configure --enable-static --disable-shared --prefix=/d/HarbourBuild/static_deps/libpsl_static CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC"
Configure libcurl for the "Hybrid" Result
To achieve the hybrid DLL (static internal deps + dynamic OpenSSL), you must explicitly tell curl to build a shared library but point it to your static archives.
Suggested configure command:
./configure \
--host=i686-w64-mingw32 \
--enable-shared \
--disable-static --disable-docs \
--with-openssl=/mingw32 \
--with-zlib=/d/HarbourBuild/static_deps/zlib1 \
--with-brotli=/d/HarbourBuild/static_deps/brotli \
--with-nghttp2=/d/HarbourBuild/static_deps/nghttp2 \
--with-libpsl=/d/HarbourBuild/static_deps/libpsl_static \
CPPFLAGS="-DCURL_STATICLIB -DNGHTTP2_STATICLIB -DBROTLI_STATIC_DECLARE -DLIBPSL_STATIC" \
LDFLAGS="-static-libgcc -static-libstdc++" \
CURL_LIBS="/d/HarbourBuild/static_deps/libpsl_static/lib/libpsl.a /d/HarbourBuild/static_deps/zlib1/lib/libz.a /d/HarbourBuild/static_deps/brotli/lib/libbrotlidec.a /d/HarbourBuild/static_deps/nghttp2/lib/libnghttp2.a -lws2_32 -lgdi32 -lcrypt32 -lnormaliz"
Key Benefits of This Strategy
Portability: Your libcurl-4.dll will no longer require zlib1.dll, libbrotli.dll, or libpsl.dll.
Security Maintenance: Since OpenSSL remains dynamic, you can swap libssl-3.dll and libcrypto-3.dll for newer versions if a vulnerability is found, without recompiling curl.
Reduced Conflicts: By building your own static dependencies, you avoid version mismatches with other DLLs in the MSYS2/MinGW environment.
Important Considerations for 2026
The "Pass All" Rule: After running configure, manually check the libtool script. Set deplibs_check_method="pass_all" to prevent the build system from stripping your static libraries out of the DLL.
Symbol Decorations: Always include -DLIBUNISTRING_STATIC and -DIDN2_STATIC in your global CPPFLAGS to avoid the "undefined reference to _imp__..." errors common in 32-bit Windows builds.
Verification: Always use objdump -p libcurl-4.dll | grep "DLL Name" after the build to confirm that only OpenSSL and system DLLs (like WS2_32.dll) remain.
"32-bit Hybrid Build" Checklist:
The "Static-First" Compilation Rule
When building zlib, brotli, nghttp2, and libpsl, always pass these two flags in your CPPFLAGS:
-DLIBUNISTRING_STATIC
-DIDN2_STATIC
(And for Brotli): -DBROTLI_STATIC_DECLARE
This ensures that no library in your chain accidentally "bakes in" a reference to a DLL.
The Linker Strategy
When you reach the final curl build, remember that order matters for static libraries. Your CURL_LIBS should follow this sequence to resolve symbols correctly:
High-level: libpsl.a
Middle-level: libidn2.a, libnghttp2.a, libbrotlidec.a
Low-level: libunistring.a, libiconv.a, libz.a
System: -lws2_32, -lnormaliz, -lbcrypt, -lcrypt32
The "Hybrid" Check
Once you finish the build, run this final test to confirm the result is exactly what you want:
objdump -p lib/.libs/libcurl-4.dll | grep "DLL Name"
Success: You see libssl-3.dll and libcrypto-3.dll.
Success: You do not see zlib1.dll or libpsl.dll.
Good luck with the build tomorrow! I'll be here if you hit any more 32-bit linking puzzles. Enjoy the process!
To build a fully static suite of libraries for your 32-bit libcurl-4.dll hybrid project, you must ensure every component is compiled without dynamic "pollution" (the _imp__ prefix issue).
For 2026 MinGW32 builds, use the following commands for each library. Replace /d/HarbourBuild/static_deps with your actual target directory.
1. zlib-ng (2.3.2) --- did not accept CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC"
Use the zlib-compat mode for maximum compatibility with other libraries.
$ ./configure --static --prefix=/d/HarbourBuild/static_deps/zlib-ng-2.3.2 --zlib-compat
$ make -j$(nproc) && make install
2. Zstd (1.5.7)
cmake worked:
$ cmake -S build/cmake -B build/cmake_build -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release
$ cmake --build build/cmake_build
$ cmake --install build/cmake_build --prefix=/d/HarbourBuild/static_deps/zstd-1.5.7
Original suggestion to use make did not work. Failed.
$ make -j$(nproc) lib-static PREFIX=/d/HarbourBuild/static_deps/zstd
make: *** No rule to make target 'lib-static'. Stop.
Failed attempt:
$ make -j$(nproc) lib-static PREFIX=/d/HarbourBuild/static_deps/zstd
$ make install PREFIX=/d/HarbourBuild/static_deps
3. Brotli (1.2.0)
$ mkdir build && cd build
$ cmake .. -G "MSYS Makefiles" \
-DCMAKE_INSTALL_PREFIX=/d/HarbourBuild/static_deps \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_C_FLAGS="-DBROTLI_STATIC_DECLARE"
modified original command above and added -DLIBUNISTRING_STATIC -DIDN2_STATIC to -DCMAKE_C_FLAGS
cmake .. -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/d/HarbourBuild/static_deps/brotli-1.2.0 -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-DBROTLI_STATIC_DECLARE -DLIBUNISTRING_STATIC -DIDN2_STATIC"
$ make -j$(nproc) install
4. Libpsl (0.21.5)
As established, building this from source with the correct static macros is critical to avoid _imp__ errors.
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/static_deps/libpsl-0.21.5 \
--enable-static --disable-shared \
CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC -I/mingw32/include" \
LDFLAGS="-L/mingw32/lib" \
LIBS="-lunistring -lidn2 -liconv -lintl"
$ make -C src -j$(nproc) install
5. nghttp2 (1.68.0)
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/static_deps/nghttp2-1.68.0 \
--enable-static --disable-shared \
--enable-lib-only CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC -I/mingw32/include"
$ make -j$(nproc) install
6. nghttp3 (1.14.0) & ngtcp2 (1.19.0)
These are required for HTTP/3 support. Build nghttp3 first.
nghttp3
$ ./configure --host=i686-w64-mingw32 --prefix=/d/HarbourBuild/static_deps/nghttp3-1.14.0 --enable-static --disable-shared CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC -I/mingw32/include"
$ make -j$(nproc) install <--- failed wanting arpa/inet.h --- not in mingw32/include --- inet.h is in /usr/include!
but builds "D:\HarbourBuild\static_deps\nghttp3-1.14.0\lib\libnghttp3.a"
7. ngtcp2 (Requires a crypto backend, usually OpenSSL/LibreSSL)
$ ./configure --host=i686-w64-mingw32 --prefix=/d/HarbourBuild/static_deps/ngtcp2-1.19.0 \
--enable-static --disable-shared \
--with-openssl \
PKG_CONFIG_PATH="/mingw32/lib/pkgconfig" CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC -I/mingw32/include"
$ make -j$(nproc) install
8. libssh2 (1.11.1)
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/static_deps/libssh2-1.11.1 \
--enable-static --disable-shared \
--with-libssl-prefix=/mingw32 \
--with-crypto=openssl CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC -I/mingw32/include"
$ make -j$(nproc) install
9. LibreSSL (4.2.1)
If you are using this as your OpenSSL replacement: Built, but we will use OpenSSL.
$ ./configure --host=i686-w64-mingw32 --prefix=/d/HarbourBuild/static_deps/libressl-4.2.1 --enable-static --disable-shared CPPFLAGS="-DLIBUNISTRING_STATIC -DIDN2_STATIC -I/mingw32/include"
$ make -j$(nproc) install
9. trurl (0.16.1)
trurl is a command-line tool but can be built against your static curl.
build this after curl is built.
$ make CURL_CONFIG=/d/HarbourBuild/curl/bin/curl-config LDFLAGS="-static"
10. psl (2025-10-16) & cacert (2025-12-02)
These are data files, not libraries.
psl: Copy public_suffix_list.dat to /d/HarbourBuild/static_deps/share/publicsuffix/.
cacert: Place cacert.pem in your curl bin directory or point to it via --with-ca-bundle.
11. Final Curl (8.17.0) Hybrid Build
Now link everything into your libcurl-4.dll.
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/curl/mingw32/curl_final \
--enable-shared --disable-static --disable-docs \
--with-openssl=/mingw32 --with-ca-bundle=/d/HarbourBuild/static_deps/cacert \
--with-zlib=/d/HarbourBuild/static_deps/zlib-ng-2.3.2 \
--with-brotli=/d/HarbourBuild/static_deps/brotli-1.2.0 \
--with-nghttp2=/d/HarbourBuild/static_deps/nghttp2-1.68.0 \
--with-libssh2=/d/HarbourBuild/static_deps/libssh2-1.11.1 \
--with-libpsl=/d/HarbourBuild/static_deps/libpsl-0.21.5 --with-zstd=/d/HarbourBuild/static_deps/zstd-1.5.7 \
CPPFLAGS="-DCURL_STATICLIB -DNGHTTP2_STATICLIB -DBROTLI_STATIC_DECLARE -DLIBPSL_STATIC -DIDN2_STATIC -DLIBUNISTRING_STATIC" \
CURL_LIBS="/d/HarbourBuild/static_deps/libpsl-0.21.5/lib/libpsl.a /d/HarbourBuild/static_deps/nghttp2-1.11.1/lib/libnghttp2.a /d/HarbourBuild/static_deps/brotli-1.2.0/lib/libbrotlidec.a /d/HarbourBuild/static_deps/libzlib-ng-2.3.2/lib/libz.a /d/HarbourBuild/static_deps/zstd-1.5.7/lib/libzstd.a /mingw32/lib/libidn2.a /mingw32/lib/libunistring.a -lws2_32 -lnormaliz"
configure failed with the error:
checking for psl_builtin in -lpsl... no
configure: error: libpsl libs and/or directories were not found where specified!
Try without libpsl for testing
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/curl/mingw32/curl_final \
--enable-shared --disable-static --disable-docs --without-libpsl \
--with-openssl=/mingw32 --with-ca-bundle=/d/HarbourBuild/static_deps/cacert \
--with-zlib=/d/HarbourBuild/static_deps/zlib-ng-2.3.2 \
--with-brotli=/d/HarbourBuild/static_deps/brotli-1.2.0 \
--with-nghttp2=/d/HarbourBuild/static_deps/nghttp2-1.68.0 \
--with-libssh2=/d/HarbourBuild/static_deps/libssh2-1.11.1 \
--with-zstd=/d/HarbourBuild/static_deps/zstd-1.5.7 \
CPPFLAGS="-DCURL_STATICLIB -DNGHTTP2_STATICLIB -DBROTLI_STATIC_DECLARE -DIDN2_STATIC -DLIBUNISTRING_STATIC" \
CURL_LIBS="/d/HarbourBuild/static_deps/nghttp2-1.11.1/lib/libnghttp2.a /d/HarbourBuild/static_deps/brotli-1.2.0/lib/libbrotlidec.a /d/HarbourBuild/static_deps/libzlib-ng-2.3.2/lib/libz.a /d/HarbourBuild/static_deps/zstd-1.5.7/lib/libzstd.a /mingw32/lib/libidn2.a /mingw32/lib/libunistring.a -lws2_32 -lnormaliz"
Important: Edit libtool to set deplibs_check_method="pass_all" before make or alternatively use export lt_cv_deplibs_check_method=pass_all <--- this is critical
$ make -j$(nproc) install
Generated libcurl-4.dll is 3232KB and has only 3 dependencies --- libcrypto-3.dll and libssl-3.dll (this is what we wanted) and libgcc_s_dw2-1.dll (will have to get rid of this)
Successful build without-libpsl
Try without libpsl and -static-libgcc for testing
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/curl/mingw32/curl_final \
--enable-shared --disable-static --disable-docs --without-libpsl \
--with-openssl=/mingw32 --with-ca-bundle=/d/HarbourBuild/static_deps/cacert \
--with-zlib=/d/HarbourBuild/static_deps/zlib-ng-2.3.2 \
--with-brotli=/d/HarbourBuild/static_deps/brotli-1.2.0 \
--with-nghttp2=/d/HarbourBuild/static_deps/nghttp2-1.68.0 \
--with-libssh2=/d/HarbourBuild/static_deps/libssh2-1.11.1 \
--with-zstd=/d/HarbourBuild/static_deps/zstd-1.5.7 \
CPPFLAGS="-DCURL_STATICLIB -DNGHTTP2_STATICLIB -DBROTLI_STATIC_DECLARE -DIDN2_STATIC -DLIBUNISTRING_STATIC" LDFLAGS="-static-libgcc" \
CURL_LIBS="/d/HarbourBuild/static_deps/nghttp2-1.11.1/lib/libnghttp2.a /d/HarbourBuild/static_deps/brotli-1.2.0/lib/libbrotlidec.a /d/HarbourBuild/static_deps/libzlib-ng-2.3.2/lib/libz.a /d/HarbourBuild/static_deps/zstd-1.5.7/lib/libzstd.a /mingw32/lib/libidn2.a /mingw32/lib/libunistring.a -lws2_32 -lnormaliz"
Generated libcurl-4.dll is 3235KB and has only 2 dependencies --- libcrypto-3.dll and libssl-3.dll as desired.
Verification: Run objdump -p libcurl-4.dll | grep "DLL Name" to confirm only OpenSSL and system DLLs are present.
------------------8<----------------8<----------------8<----------------8<----------------8<----------------8<----------------8<----------------8<------------
Building static curl libcurl-4.dll with winidn instead of libidn2 and libpsl (--with-winidn and --without-libpsl)
# Force libtool to accept static archives in the DLL
$ export lt_cv_deplibs_check_method=pass_all
# Explicitly define the full paths to your static archives
# This prevents the linker from ever looking in /mingw32/lib for them
$ export MY_STATIC_DEPS="/d/HarbourBuild/static_deps/libssh2-1.11.1/lib/libssh2.a \
/d/HarbourBuild/static_deps/nghttp2-1.68.0/lib/libnghttp2.a \
/d/HarbourBuild/static_deps/brotli-1.2.0/lib/libbrotlidec.a \
/d/HarbourBuild/static_deps/zlib-ng-2.3.2/lib/libz.a \
/d/HarbourBuild/static_deps/zstd-1.5.7/lib/libzstd.a"
$ ./configure \
--host=i686-w64-mingw32 \
--prefix=/d/HarbourBuild/curl/mingw32/curl_final \
--enable-shared --disable-static --disable-docs \
--with-openssl=/mingw32 \
--with-winidn \
--without-libpsl \
--with-ca-bundle=/d/HarbourBuild/static_deps/cacert \
--with-zlib=/d/HarbourBuild/static_deps/zlib-ng-2.3.2 \
--with-brotli=/d/HarbourBuild/static_deps/brotli-1.2.0 \
--with-nghttp2=/d/HarbourBuild/static_deps/nghttp2-1.68.0 \
--with-libssh2=/d/HarbourBuild/static_deps/libssh2-1.11.1 \
--with-zstd=/d/HarbourBuild/static_deps/zstd-1.5.7 \
CPPFLAGS="-DCURL_STATICLIB -DNGHTTP2_STATICLIB -DBROTLI_STATIC_DECLARE -DLIBSSH2_STATIC -I/mingw32/include" \
LDFLAGS="-static-libgcc" \
LIBS="$MY_STATIC_DEPS -lssl -lcrypto -lnormaliz -lws2_32 -lcrypt32 -lbcrypt" \
LIBSSH2_LIBS="/d/HarbourBuild/static_deps/libssh2-1.11.1/lib/libssh2.a" \
ZLIB_LIBS="/d/HarbourBuild/static_deps/zlib-ng-2.3.2/lib/libz.a"
$ make -j$(nproc)
$ make install
Thanks and good luck with building static libcurl from source!
JC