Author: brane
Date: Mon Aug  4 10:32:19 2025
New Revision: 1927608

Log:
On the user-defined-authn branch: sync with trunk r1927496.

Added:
   serf/branches/user-defined-authn/build/FindUnbound.cmake
      - copied unchanged from r1927607, serf/trunk/build/FindUnbound.cmake
   serf/branches/user-defined-authn/build/SerfFindPkgConfig.cmake
      - copied unchanged from r1927607, serf/trunk/build/SerfFindPkgConfig.cmake
Deleted:
   serf/branches/user-defined-authn/build/gen_def.py
Modified:
   serf/branches/user-defined-authn/   (props changed)
   serf/branches/user-defined-authn/CMakeLists.txt
   serf/branches/user-defined-authn/SConstruct
   serf/branches/user-defined-authn/build/FindAPR.cmake
   serf/branches/user-defined-authn/build/FindAPRUtil.cmake
   serf/branches/user-defined-authn/build/SerfMacOS.cmake
   serf/branches/user-defined-authn/build/exports.py
   serf/branches/user-defined-authn/build/serf.pc.in

Modified: serf/branches/user-defined-authn/CMakeLists.txt
==============================================================================
--- serf/branches/user-defined-authn/CMakeLists.txt     Mon Aug  4 10:01:39 
2025        (r1927607)
+++ serf/branches/user-defined-authn/CMakeLists.txt     Mon Aug  4 10:32:19 
2025        (r1927608)
@@ -49,6 +49,11 @@ message(WARNING
         "Some features are not supported and the build "
         "has not been tested on many supported platforms.")
 
+# Optional dependency options
+option(USE_BROTLI "Use the Brotli decoding library if available" ON)
+option(USE_GSSAPI "Use GSSAPI authentication if available" ON)
+option(USE_UNBOUND "Use the Unbound async resolver if available" ON)
+
 # Build options
 option(DEBUG "Enable debugging info and strict compile warnings" OFF)
 option(DOT_CLANGD "Generate a .clangd file at the root of the source tree" OFF)
@@ -84,6 +89,7 @@ if(NOT CMAKE_BUILD_TYPE)
 endif()
 
 include(GNUInstallDirs)
+include(SerfFindPkgConfig)
 include(SerfPlatform)
 
 # On the Mac: Use dependencies from Homebrew or MacPorts
@@ -242,11 +248,30 @@ if(EXPAT)
 endif(EXPAT)
 
 # Find required dependencies
-find_package(OpenSSL REQUIRED)
-find_package(ZLIB REQUIRED)
 find_package(APR REQUIRED)
 find_package(APRUtil REQUIRED)
 
+
+SerfFindPkgConfig(OpenSSL_SSL OPENSSL_ROOT_DIR libssl OpenSSL::SSL)
+SerfFindPkgConfig(OpenSSL_Crypto OPENSSL_ROOT_DIR libcrypto OpenSSL::Crypto)
+if(NOT (OpenSSL_SSL_FOUND AND OpenSSL_Crypto_FOUND))
+  find_package(OpenSSL REQUIRED)
+  if(OpenSSL_FOUND)
+    set(OPENSSL_PC_LIBS ${OPENSSL_LIBRARIES})
+  endif()
+else()
+  set(OpenSSL_FOUND TRUE)
+  set(OPENSSL_INCLUDE_DIR ${OPENSSL_SSL_INCLUDE_DIR})
+  set(OPENSSL_PC_REQUIRES ${OPENSSL_SSL_PC_REQUIRES} 
${OPENSSL_CRYPTO_PC_REQUIRES})
+  set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
+endif()
+
+SerfFindPkgConfig(ZLIB ZLIB_ROOT zlib ZLIB::ZLIB)
+if(NOT ZLIB_FOUND)
+  find_package(ZLIB REQUIRED)
+  set(ZLIB_PC_LIBS ${ZLIB_LIBRARIES})
+endif()
+
 # We do not want or need OpenSSL's compatibility macros.
 list(APPEND SERF_C_DEFINES "OPENSSL_NO_DEPRECATED")
 
@@ -254,9 +279,26 @@ list(APPEND SERF_C_DEFINES "OPENSSL_NO_D
 list(APPEND SERF_C_DEFINES "OPENSSL_NO_STDIO")
 
 # Find optional dependencies
-find_package(Brotli)
+if(USE_BROTLI)
+  SerfFindPkgConfig(Brotli Brotli_ROOT libbrotlidec Brotli::Decode)
+  if(NOT Brotli_FOUND)
+    find_package(Brotli)
+    if(Brotli_FOUND)
+      set(BROTLI_PC_LIBS ${BROTLI_DECODE_LIBRARY})
+    endif()
+  endif()
+endif()
+
 if(NOT SERF_WINDOWS)
-  find_package(GSSAPI)
+  if(USE_GSSAPI)
+    SerfFindPkgConfig(GSSAPI GSSAPI_ROOT krb5-gssapi KRB5::GSSAPI)
+    if(NOT GSSAPI_FOUND)
+      find_package(GSSAPI)
+      if(GSSAPI_FOUND)
+        set(GSSAPI_PC_LIBS ${GSSAPI_LIBRARIES})
+      endif()
+    endif()
+  endif()
 else()
   # We use SSPI on Windows and there's no Kerberos/GSSAPI port there.
   set(GSSAPI_FOUND FALSE)
@@ -265,36 +307,17 @@ else()
   endif()
 endif()
 
-
-# FIXME: VERYTEMPORARY, figure out FindUnbound.cmake first.
-set(Unbound_FOUND FALSE)
-if (Unbound_FOUND)
-  set(UNBOUND_INCLUDE_DIR "/opt/homebrew/opt/unbound/include")
-  set(UNBOUND_LIBRARIES "/opt/homebrew/opt/unbound/lib/libunbound.dylib")
-  # set(UNBOUND_LIBRARIES "/usr/lib/aarch64-linux-gnu/libunbound.so")
-  # set(UNBOUND_LIBRARIES "/usr/lib64/libunbound.so")
-  add_library(Unbound::Unbound UNKNOWN IMPORTED)
-  set_target_properties(Unbound::Unbound PROPERTIES
-    INTERFACE_INCLUDE_DIRECTORIES "${UNBOUND_INCLUDE_DIR}")
-  set_target_properties(Unbound::Unbound PROPERTIES
-    IMPORTED_LOCATION "${UNBOUND_LIBRARIES}")
-endif(Unbound_FOUND)
-
-# Calculate the set of private and public targets
-set(SERF_PRIVATE_TARGETS OpenSSL::Crypto OpenSSL::SSL ZLIB::ZLIB)
-if(Brotli_FOUND)
-  list(APPEND SERF_PRIVATE_TARGETS Brotli::Decode)
-endif()
-if(GSSAPI_FOUND)
-  list(APPEND SERF_C_DEFINES "SERF_HAVE_GSSAPI")
-  list(APPEND SERF_PRIVATE_TARGETS KRB5::GSSAPI)
-endif()
-if(Unbound_FOUND)
-  list(APPEND SERF_C_DEFINES "SERF_HAVE_ASYNC_RESOLVER=1")
-  list(APPEND SERF_C_DEFINES "SERF_HAVE_UNBOUND")
-  list(APPEND SERF_PRIVATE_TARGETS Unbound::Unbound)
+if(USE_UNBOUND)
+  SerfFindPkgConfig(Unbound Unbound_ROOT libunbound Unbound::Unbound)
+  if(NOT Unbound_FOUND)
+    find_package(Unbound)
+    if(Unbound_FOUND)
+      set(UNBOUND_PC_LIBS "${UNBOUND_LIBRARY}")
+    endif()
+  endif()
 endif()
 
+# Calculate the set of private and public targets
 if(APR_STATIC)
   if(SERF_WINDOWS)
     list(APPEND SERF_PUBLIC_TARGETS APR::APR_static)
@@ -311,6 +334,20 @@ else(APR_STATIC)
   endif()
 endif(APR_STATIC)
 
+list(APPEND SERF_PRIVATE_TARGETS OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
+if(Brotli_FOUND)
+  list(APPEND SERF_PRIVATE_TARGETS Brotli::Decode)
+endif()
+if(GSSAPI_FOUND)
+  list(APPEND SERF_C_DEFINES "SERF_HAVE_GSSAPI")
+  list(APPEND SERF_PRIVATE_TARGETS KRB5::GSSAPI)
+endif()
+if(Unbound_FOUND)
+  list(APPEND SERF_C_DEFINES "SERF_HAVE_ASYNC_RESOLVER=1")
+  list(APPEND SERF_C_DEFINES "SERF_HAVE_UNBOUND=1")
+  list(APPEND SERF_PRIVATE_TARGETS Unbound::Unbound)
+endif()
+
 # Feature tests
 include(SerfChecks)
 CheckNotFunction("BIO_set_init" "NULL, 0" "SERF_NO_SSL_BIO_WRAPPERS"
@@ -458,11 +495,9 @@ if(NOT SKIP_SHARED)
   list(APPEND SERF_TARGETS serf_shared)
 
   if(SERF_WINDOWS)
-    string(TOLOWER "${CMAKE_BUILD_TYPE}" config)
-    if(NOT "${config}" STREQUAL "release")
-      install(FILES $<TARGET_PDB_FILE:serf_shared>
-              DESTINATION "${SERF_INSTALL_RUNTIME}")
-    endif()
+    install(FILES $<TARGET_PDB_FILE:serf_shared>
+            CONFIGURATIONS Debug RelWithDebinfo
+            DESTINATION "${SERF_INSTALL_RUNTIME}")
   endif()
 endif()
 
@@ -498,41 +533,59 @@ install(TARGETS ${SERF_TARGETS}
 install(FILES ${HEADERS} DESTINATION "${SERF_INSTALL_HEADERS}")
 
 # Generate the pkg-config module file.
-if(NOT SERF_WINDOWS)
-  set(SERF_PC_FILE "serf-${SERF_MAJOR_VERSION}.pc")
+set(SERF_PC_FILE "serf-${SERF_MAJOR_VERSION}.pc")
 
-  # Use a separate variable scope for the substitutions in serf.pc.in.
-  function(make_pkgconfig)
-    # Use a relative prefix to create a relocatable PC file.
+# Use a separate variable scope for the substitutions in serf.pc.in.
+function(make_pkgconfig)
+  # Use a relative prefix to create a relocatable PC file.
+  if(SERF_WINDOWS)
+    file(RELATIVE_PATH relfragment "X:\\${SERF_INSTALL_PKGCONFIG}" "X:\\")
+  else()
     file(RELATIVE_PATH relfragment "/${SERF_INSTALL_PKGCONFIG}" "/")
-    file(TO_CMAKE_PATH "\${pcfiledir}/${relfragment}" relprefix)
+  endif()
+  file(TO_CMAKE_PATH "\${pcfiledir}/${relfragment}" relprefix)
 
-    set(PREFIX ${relprefix})
-    set(INCLUDE_SUBDIR ${SERF_INCLUDE_SUBDIR})
-    set(LIBDIR \${prefix}/${SERF_INSTALL_LIBRARIES})
-    set(VERSION ${SERF_VERSION})
-    set(MAJOR ${SERF_MAJOR_VERSION})
-    set(LIBS
-      ${APR_LDFLAGS}
-      ${APR_LIBRARIES}
-      ${APR_EXTRALIBS}
-      ${APRUTIL_LDFLAGS}
-      ${APRUTIL_LIBRARIES}
-      ${APRUTIL_EXTRALIBS}
-      ${BROTLI_COMMON_LIBRARY}
-      ${BROTLI_DECODE_LIBRARY}
-      ${GSSAPI_LIBRARIES}
-      ${ZLIB_LIBRARIES}
-      )
-    list(REMOVE_DUPLICATES LIBS)
-    list(JOIN LIBS " " LIBS)
-    configure_file("build/serf.pc.in" "${SERF_PC_FILE}" @ONLY)
-  endfunction()
-
-  make_pkgconfig()
-  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${SERF_PC_FILE}"
-          DESTINATION "${SERF_INSTALL_PKGCONFIG}")
-endif()
+  set(PREFIX ${relprefix})
+  set(INCLUDE_SUBDIR ${SERF_INCLUDE_SUBDIR})
+  set(LIBDIR \${prefix}/${SERF_INSTALL_LIBRARIES})
+  set(VERSION ${SERF_VERSION})
+  set(MAJOR ${SERF_MAJOR_VERSION})
+  set(REQUIRES
+    ${OPENSSL_PC_REQUIRES}
+    ${ZLIB_PC_REQUIRES}
+    ${BROTLI_PC_REQUIRES}
+    ${GSSAPI_PC_REQUIRES}
+    ${UNBOUND_PC_REQUIRES}
+  )
+  set(CFLAGS
+    ${APR_CFLAGS}
+  )
+  set(LIBS
+    ${APR_LDFLAGS}
+    ${APR_LIBRARIES}
+    ${APR_EXTRALIBS}
+    ${APRUTIL_LDFLAGS}
+    ${APRUTIL_LIBRARIES}
+    ${APRUTIL_EXTRALIBS}
+    ${OPENSSL_PC_LIBS}
+    ${ZLIB_PC_LIBS}
+    ${BROTLI_PC_LIBS}
+    ${GSSAPI_PC_LIBS}
+    ${UNBOUND_PC_LIBS}
+    ${SERF_STANDARD_LIBRARIES}
+  )
+  list(REMOVE_DUPLICATES REQUIRES)
+  list(JOIN REQUIRES " " REQUIRES)
+  list(REMOVE_DUPLICATES CFLAGS)
+  list(JOIN CFLAGS " " CFLAGS)
+  list(REMOVE_DUPLICATES LIBS)
+  list(JOIN LIBS " " LIBS)
+  configure_file("build/serf.pc.in" "${SERF_PC_FILE}" @ONLY)
+endfunction()
+
+make_pkgconfig()
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${SERF_PC_FILE}"
+        DESTINATION "${SERF_INSTALL_PKGCONFIG}")
 
 
 if(NOT SKIP_TESTS)
@@ -583,7 +636,7 @@ endif()
 if("SERF_HAVE_SSPI" IN_LIST SERF_C_DEFINES)
   set(_have_sspi ON)
 endif()
-if ("SERF_HAVE_UNBOUND" IN_LIST SERF_C_DEFINES)
+if ("SERF_HAVE_UNBOUND=1" IN_LIST SERF_C_DEFINES)
   set(_have_unbound "EXPERIMENTAL")
 endif()
 
@@ -609,6 +662,5 @@ message(STATUS "    headers: ...........
 message(STATUS "    libraries: .............. : ${SERF_INSTALL_LIBRARIES}")
 if(SERF_WINDOWS)
 message(STATUS "    dynamic libraries: ...... : ${SERF_INSTALL_RUNTIME}")
-else()
-message(STATUS "    pkg-config file: ........ : ${SERF_INSTALL_PKGCONFIG}")
 endif()
+message(STATUS "    pkg-config file: ........ : ${SERF_INSTALL_PKGCONFIG}")

Modified: serf/branches/user-defined-authn/SConstruct
==============================================================================
--- serf/branches/user-defined-authn/SConstruct Mon Aug  4 10:01:39 2025        
(r1927607)
+++ serf/branches/user-defined-authn/SConstruct Mon Aug  4 10:32:19 2025        
(r1927608)
@@ -110,9 +110,9 @@ def unsubstable(string):
 
 # default directories
 if sys.platform == 'win32':
-  default_incdir='..'
-  default_libdir='..'
-  default_prefix='Debug'
+  default_incdir='$PREFIX'
+  default_libdir='$PREFIX/lib'
+  default_prefix='./install'
 else:
   default_incdir='/usr'
   default_libdir='$PREFIX/lib'
@@ -156,6 +156,10 @@ opts.AddVariables(
                "Path to Brotli's install area",
                None,
                PathVariable.PathIsDir),
+  PathVariable('UNBOUND',
+               "Path to libunbound's install area",
+               None,
+               PathVariable.PathIsDir),
   BoolVariable('DEBUG',
                "Enable debugging info and strict compile warnings",
                False),
@@ -227,14 +231,6 @@ env = Environment(variables=opts,
                   CPPPATH=['.', ],
                   )
 
-# "Legacy" .def file builder
-gen_def_script = env.File('build/gen_def.py').rstr()
-env.Append(BUILDERS = {
-    'GenDef' :
-      Builder(action = '"%s" "%s" $SOURCES > $TARGET' % (sys.executable, 
gen_def_script,),
-              suffix='.def', src_suffix='.h')
-  })
-
 # Export symbol generator (for Windows DLL, Mach-O and ELF)
 export_generator = build.exports.ExportGenerator()
 if export_generator.target is None:
@@ -298,6 +294,7 @@ zlib = str(env['ZLIB'])
 expat = env.get('EXPAT', None)
 gssapi = env.get('GSSAPI', None)
 brotli = env.get('BROTLI', None)
+unbound = env.get('UNBOUND', None)
 
 if gssapi and os.path.isdir(gssapi):
   krb5_config = os.path.join(gssapi, 'bin', 'krb5-config')
@@ -318,6 +315,7 @@ opts.Save(SAVED_CONFIG, env)
 thisdir = os.getcwd()
 libdir = '$LIBDIR'
 incdir = '$PREFIX/include/serf-$MAJOR'
+pkgdir = '$LIBDIR/pkgconfig'
 
 # This version string is used in the dynamic library name, and for Mac OS X 
also
 # for the compatibility_version option in the .dylib.
@@ -393,6 +391,9 @@ if sys.platform != 'win32':
   if brotli:
     env.Append(LIBS=['brotlicommon', 'brotlidec'])
 
+  if unbound:
+    env.Append(LIBS=['unbound'])
+
 else:
   # Warning level 4, no unused argument warnings
   env.Append(CCFLAGS=['/W4',
@@ -416,12 +417,7 @@ else:
 # PLAN THE BUILD
 SHARED_SOURCES = []
 if sys.platform == 'win32':
-  env.GenDef(target=[export_filter], source=HEADER_FILES)
-  SHARED_SOURCES.append([export_filter])
-  dll_res = env.RES(['serf.rc'])
-  SHARED_SOURCES.append(dll_res)
-  # TODO: Use GenExports instead.
-  export_filter = None
+  SHARED_SOURCES.append(env.RES(['serf.rc']))
 
 SOURCES = Glob('src/*.c') + Glob('buckets/*.c') + Glob('auth/*.c') + \
           Glob('protocols/*.c')
@@ -441,9 +437,16 @@ env.Append(CPPDEFINES=['OPENSSL_NO_STDIO
 if aprstatic:
   env.Append(CPPDEFINES=['APR_DECLARE_STATIC', 'APU_DECLARE_STATIC'])
 
+# Prepare lists for the pkg-config file
+pc_requires = ['libssl', 'libcrypto']
+pc_cppflags = []
+pc_private_libs = []
+win_std_libs = []
+
 if sys.platform == 'win32':
-  env.Append(LIBS=['user32.lib', 'advapi32.lib', 'gdi32.lib', 'ws2_32.lib',
-                   'crypt32.lib', 'mswsock.lib', 'rpcrt4.lib', 'secur32.lib'])
+  source_layout = env.get('SOURCE_LAYOUT', None)
+  win_std_libs = ['crypt32.lib', 'mswsock.lib', 'rpcrt4.lib',
+                  'secur32.lib', 'ws2_32.lib']
 
   # Get apr/apu information into our build
   env.Append(CPPDEFINES=['WIN32','WIN32_LEAN_AND_MEAN','NOUSER',
@@ -486,37 +489,48 @@ if sys.platform == 'win32':
   if aprstatic:
     apr_libs='apr-1.lib'
     apu_libs='aprutil-1.lib'
-    env.Append(LIBS=['shell32.lib', expat_lib_name])
+    win_std_libs.append('shell32.lib')
   else:
     apr_libs='libapr-1.lib'
     apu_libs='libaprutil-1.lib'
 
-  env.Append(LIBS=[apr_libs, apu_libs])
-  if expat and aprstatic:
-    env.Append(LIBPATH=[expat])
-
-  if not env.get('SOURCE_LAYOUT', None):
-    env.Append(LIBPATH=['$APR/lib', '$APU/lib'],
-               CPPPATH=['$APR/include', '$APR/include/apr-1',
+  if not source_layout:
+    apr_libdir = '$APR/lib'
+    apu_libdir = '$APU/lib'
+    env.Append(CPPPATH=['$APR/include', '$APR/include/apr-1',
                         '$APU/include', '$APU/include/apr-1'])
   elif aprstatic:
-    env.Append(LIBPATH=['$APR/LibR','$APU/LibR'],
-               CPPPATH=['$APR/include', '$APU/include'])
-  else:
-    env.Append(LIBPATH=['$APR/Release','$APU/Release'],
-               CPPPATH=['$APR/include', '$APU/include'])
+    apr_libdir = '$APR/LibR'
+    apu_libdir = '$APU/LibR'
+    env.Append(CPPPATH=['$APR/include', '$APU/include'])
+  else:
+    apr_libdir = '$APR/Release'
+    apu_libdir = '$APU/Release'
+    env.Append(CPPPATH=['$APR/include', '$APU/include'])
+
+  env.Append(LIBPATH=[apr_libdir, apu_libdir],
+             LIBS=[apr_libs, apu_libs])
+  pc_private_libs.append('/'.join([apr_libdir, apr_libs]))
+  pc_private_libs.append('/'.join([apu_libdir, apu_libs]))
+
+  if expat and aprstatic:
+    env.Append(LIBPATH=[expat],
+               LIBS=[expat_lib_name])
+    pc_private_libs.append('/'.join([expat, expat_lib_name]))
 
   # zlib
   env.Append(LIBS=['zlib.lib'])
-  if not env.get('SOURCE_LAYOUT', None):
+  if not source_layout:
     env.Append(CPPPATH=['$ZLIB/include'],
                LIBPATH=['$ZLIB/lib'])
+    pc_private_libs.append('$ZLIB/lib/zlib.lib')
   else:
     env.Append(CPPPATH=['$ZLIB'],
                LIBPATH=['$ZLIB'])
+    pc_private_libs.append('$ZLIB/zlib.lib')
 
   # openssl
-  if not env.get('SOURCE_LAYOUT', None):
+  if not source_layout:
     env.Append(CPPPATH=['$OPENSSL/include'],
                LIBPATH=['$OPENSSL/lib'])
   else:
@@ -533,16 +547,26 @@ if sys.platform == 'win32':
 
   # brotli
   if brotli:
-    brotli_libs = 'brotlicommon.lib brotlidec.lib'
     env.Append(LIBS=['brotlicommon.lib', 'brotlidec.lib'])
-    if not env.get('SOURCE_LAYOUT', None):
+    if not source_layout:
       env.Append(CPPPATH=['$BROTLI/include'],
                  LIBPATH=['$BROTLI/lib'])
+      pc_private_libs.append('$BROTLI/lib/brotlicommon.lib')
+      pc_private_libs.append('$BROTLI/lib/brotlidec.lib')
     else:
       env.Append(CPPPATH=['$BROTLI/include'],
                  LIBPATH=['$BROTLI/Release'])
-  else:
-    brotli_libs = ''
+      pc_private_libs.append('$BROTLI/Release/brotlicommon.lib')
+      pc_private_libs.append('$BROTLI/Release/brotlidec.lib')
+
+  # unbound
+  if unbound:
+    env.Append(CPPPATH=['$UNBOUND/include'],
+               LIBPATH=['$UNBOUND/lib'],
+               LIBS=['unbound.lib'])
+    pc_private_libs.append('$UNBOUND/lib/unbound.lib')
+
+  env.Append(LIBS=win_std_libs)
 
 else:
   if CALLOUT_OKAY:
@@ -574,17 +598,19 @@ else:
 
     ### there is probably a better way to run/capture output.
     ### env.ParseConfig() may be handy for getting this stuff into the build
-    apr_libs = os.popen(env.subst('$APR --link-libtool --libs')).read().strip()
+    apr_defs = os.popen(env.subst('$APR --cppflags')).read().strip()
+    apr_libs = os.popen(env.subst('$APR --link-ld --libs')).read().strip()
+    pc_cppflags.append(apr_defs)
+    pc_private_libs.append(apr_libs)
     if apr_major < 2:
-      apu_libs = os.popen(env.subst('$APU --link-libtool 
--libs')).read().strip()
-    else:
-      apu_libs = ''
-  else:
-    apr_libs = ''
-    apu_libs = ''
+      apu_libs = os.popen(env.subst('$APU --link-ld --libs')).read().strip()
+      pc_private_libs.append(apu_libs)
 
   env.Append(CPPPATH=['$ZLIB/include'])
   env.Append(LIBPATH=['$ZLIB/lib'])
+  if env.subst('$ZLIB') not in ('', '/usr'):
+    pc_private_libs.append('-L$ZLIB/lib')
+  pc_private_libs.append('-lz')
 
   # MacOS ships ancient OpenSSL libraries, but no headers, so we can
   # assume we're building with an OpenSSL installed outside the
@@ -599,11 +625,18 @@ else:
     env.Append(LIBPATH=['$OPENSSL/lib'])
 
   if brotli:
-    brotli_libs = '-lbrotlicommon -lbrotlidec'
     env.Append(CPPPATH=['$BROTLI/include'],
                LIBPATH=['$BROTLI/lib'])
-  else:
-    brotli_libs = ''
+    if env.subst('$BROTLI') not in ('', '/usr'):
+      pc_private_libs.append('-L$BROTLI/lib')
+    pc_private_libs.append('-lbrotlicommon -lbrotlidec')
+
+  if unbound:
+    env.Append(CPPPATH=['$UNBOUND/include'],
+               LIBPATH=['$UNBOUND/lib'])
+    if env.subst('$UNBOUND') not in ('', '/usr'):
+      pc_private_libs.append('-L$UNBOUND/lib')
+    pc_private_libs.append('-lunbound')
 
 # Check for OpenSSL functions which are only available in some of
 # the versions we support. Also handles forks like LibreSSL.
@@ -616,7 +649,6 @@ for line in stream.readlines():
     ssl_include_list.append(line.rstrip())
 ssl_includes = '\n'.join(ssl_include_list)
 
-
 conf = Configure(env, custom_tests=custom_tests)
 if not conf.CheckFunc('BIO_set_init', ssl_includes, 'C', 'NULL, 0'):
   env.Append(CPPDEFINES=['SERF_NO_SSL_BIO_WRAPPERS'])
@@ -655,21 +687,40 @@ if gssapi and CALLOUT_OKAY:
         return env.MergeFlags(cmd, unique)
     env.ParseConfig('$GSSAPI --libs gssapi', parse_libs)
     env.Append(CPPDEFINES=['SERF_HAVE_GSSAPI'])
+    pc_private_libs.append(env['GSSAPI_LIBS'])
 if sys.platform == 'win32':
   env.Append(CPPDEFINES=['SERF_HAVE_SSPI'])
 
 if brotli and CALLOUT_OKAY:
   conf = Configure(env, custom_tests=custom_tests)
-  if conf.CheckCHeader('brotli/decode.h') and \
-     conf.CheckFunc('BrotliDecoderTakeOutput',
-                    '#include <brotli/decode.h>',
-                    'C', 'NULL, NULL'):
+  if (conf.CheckCHeader('brotli/decode.h')
+      and conf.CheckFunc('BrotliDecoderTakeOutput',
+                         '#include <brotli/decode.h>',
+                         'C', 'NULL, NULL')):
     env.Append(CPPDEFINES=['SERF_HAVE_BROTLI'])
   else:
     print("Cannot find Brotli library >= 1.0.0 in '%s'." % env.get('BROTLI'))
     Exit(1)
   env = conf.Finish()
 
+if unbound and CALLOUT_OKAY:
+  print(custom_tests)
+  conf = Configure(env, custom_tests=custom_tests)
+  if (conf.CheckCHeader('unbound.h')
+      and conf.CheckFunc('ub_ctx_create',
+                         '#include <unbound.h>',
+                         'C', '')
+      and conf.CheckFunc('ub_resolve_async',
+                         '#include <stddef.h>\n'
+                         '#include <unbound.h>',
+                         'C', 'NULL, NULL, 0, 0, NULL, NULL, NULL')):
+    env.Append(CPPDEFINES=['SERF_HAVE_ASYNC_RESOLVER=1',
+                           'SERF_HAVE_UNBOUND=1'])
+  else:
+    print("Cannot find Unbound library in '%s'." % env.get('UNBOUND'))
+    Exit(1)
+  env = conf.Finish()
+
 if CALLOUT_OKAY:
   conf = Configure(env, custom_tests=custom_tests)
 
@@ -695,8 +746,12 @@ for d in env['LIBPATH']:
   env.Append(RPATH=[':'+d])
 
 # Set up the construction of serf-*.pc
-pkgprefix = os.path.relpath(env.subst('$PREFIX'), 
env.subst('$LIBDIR/pkgconfig'))
-pkglibdir = os.path.relpath(env.subst('$LIBDIR'), env.subst('$PREFIX'))
+pkgprefix = os.path.relpath(env.subst('$PREFIX'), env.subst(pkgdir)
+                            ).replace(os.path.sep, '/')
+pkglibdir = os.path.relpath(env.subst('$LIBDIR'), env.subst('$PREFIX')
+                            ).replace(os.path.sep, '/')
+pkglibs = env.subst(' '.join(pc_private_libs + win_std_libs)
+                    ).replace(os.path.sep, '/')
 pkgconfig = env.Textfile('serf-%d.pc' % (MAJOR,),
                          env.File('build/serf.pc.in'),
                          SUBST_DICT = {
@@ -704,10 +759,10 @@ pkgconfig = env.Textfile('serf-%d.pc' %
                            '@PREFIX@': unsubstable('${pcfiledir}/' + 
pkgprefix),
                            '@LIBDIR@': unsubstable('${prefix}/' + pkglibdir),
                            '@INCLUDE_SUBDIR@': 'serf-%d' % (MAJOR,),
+                           '@REQUIRES@': ' '.join(pc_requires),
                            '@VERSION@': '%d.%d.%d' % (MAJOR, MINOR, PATCH),
-                           '@LIBS@': '%s %s %s %s -lz' % (apu_libs, apr_libs,
-                                                          
env.get('GSSAPI_LIBS', ''),
-                                                          brotli_libs),
+                           '@CFLAGS@': unsubstable(' '.join(pc_cppflags)),
+                           '@LIBS@': unsubstable(pkglibs),
                            })
 
 env.Default(lib_static, lib_shared, pkgconfig)
@@ -732,11 +787,9 @@ if sys.platform == 'darwin':
                                      % (target_install_shared_path,
                                         install_shared_path)))
 
-env.Alias('install-lib', [install_static, install_shared,
-                          ])
+env.Alias('install-lib', [install_static, install_shared])
 env.Alias('install-inc', env.Install(incdir, HEADER_FILES))
-env.Alias('install-pc', env.Install(os.path.join(libdir, 'pkgconfig'),
-                                    pkgconfig))
+env.Alias('install-pc', env.Install(pkgdir, pkgconfig))
 env.Alias('install', ['install-lib', 'install-inc', 'install-pc', ])
 
 

Modified: serf/branches/user-defined-authn/build/FindAPR.cmake
==============================================================================
--- serf/branches/user-defined-authn/build/FindAPR.cmake        Mon Aug  4 
10:01:39 2025        (r1927607)
+++ serf/branches/user-defined-authn/build/FindAPR.cmake        Mon Aug  4 
10:32:19 2025        (r1927608)
@@ -232,7 +232,7 @@ if(NOT _apru_include_only_utilities)
     _apr_invoke(APR_CFLAGS      "(^| )-[gOW][^ ]*" --cppflags --cflags)
     _apr_invoke(APR_INCLUDE_DIR ""                 --includedir)
     _apr_invoke(APR_LIBRARIES   ""                 --link-ld)
-    _apr_invoke(APR_EXTRALIBS   ""                 --libs)
+    _apr_invoke(APR_EXTRALIBS   ""                 --ldflags --libs)
     _apr_invoke(APR_VERSION     ""                 --version)
     string(REGEX REPLACE "^([0-9]+)\\..*$" "\\1" _apr_major "${APR_VERSION}")
 

Modified: serf/branches/user-defined-authn/build/FindAPRUtil.cmake
==============================================================================
--- serf/branches/user-defined-authn/build/FindAPRUtil.cmake    Mon Aug  4 
10:01:39 2025        (r1927607)
+++ serf/branches/user-defined-authn/build/FindAPRUtil.cmake    Mon Aug  4 
10:32:19 2025        (r1927608)
@@ -123,7 +123,7 @@ else(APR_CONTAINS_APRUTIL)
     endmacro(_apu_invoke)
 
     _apu_invoke(APRUTIL_INCLUDE_DIR  ""  --includedir)
-    _apu_invoke(APRUTIL_EXTRALIBS    ""  --libs)
+    _apu_invoke(APRUTIL_EXTRALIBS    ""  --ldflags --libs)
     _apu_invoke(APRUTIL_LIBRARIES    ""  --link-ld)
     _apu_invoke(APRUTIL_VERSION      ""  --version)
 

Copied: serf/branches/user-defined-authn/build/FindUnbound.cmake (from 
r1927607, serf/trunk/build/FindUnbound.cmake)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ serf/branches/user-defined-authn/build/FindUnbound.cmake    Mon Aug  4 
10:32:19 2025        (r1927608, copy of r1927607, 
serf/trunk/build/FindUnbound.cmake)
@@ -0,0 +1,103 @@
+# ===================================================================
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+# ===================================================================
+
+cmake_minimum_required(VERSION 3.12)
+
+#.rst:
+# FindUnbound
+# -----------
+#
+# Find the Unbound library and headers.
+#
+# IMPORTED Targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines :prop_tgt:`IMPORTED` target ``Unbound::Unbound``, if
+# libunbound has been found.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following variables:
+#
+# ::
+#
+#   Unbound_FOUND        - True if libunbound was found.
+#   UNBOUND_VERSION      - The version of libunbound found (x.y.z).
+#   UNBOUND_INCLUDE_DIR  - Where to find unbound.h.
+#   UNBOUND_LIBRARY      - Linker switches to use with ld to link the library.
+#
+# Hints
+# ^^^^^
+#
+# A user may set ``Unbound_ROOT`` to tell this module where to look.
+
+include(FindPackageHandleStandardArgs)
+include(GNUInstallDirs)
+
+set(Unbound_FOUND FALSE)
+if(DEFINED Unbound_ROOT)
+  # Search in the provided root path
+  set(_root_search PATHS ${Unbound_ROOT} NO_DEFAULT_PATH)
+  list(APPEND _unbound_searches _root_search)
+endif()
+
+# Search in default paths
+set(_default_search)
+list(APPEND _unbound_searches _default_search)
+
+# Try each search configuration
+foreach(search ${_unbound_searches})
+  find_path(UNBOUND_INCLUDE_DIR NAMES "unbound.h" ${${search}}
+            PATH_SUFFIXES "include" "${CMAKE_INSTALL_INCLUDEDIR}")
+  if(UNBOUND_INCLUDE_DIR AND EXISTS "${UNBOUND_INCLUDE_DIR}/unbound.h")
+    # Use the first successful search to find the libraries
+    if(NOT DEFINED libsearch)
+      set(libsearch ${search})
+    endif()
+  endif()
+endforeach()
+
+find_library(UNBOUND_LIBRARY NAMES "unbound" NAMES_PER_DIR ${${libsearch}}
+             PATH_SUFFIXES "lib" "${CMAKE_INSTALL_LIBDIR}")
+
+# Extract the version number from the header
+if(UNBOUND_INCLUDE_DIR AND EXISTS "${UNBOUND_INCLUDE_DIR}/unbound.h")
+  file(STRINGS "${UNBOUND_INCLUDE_DIR}/unbound.h" _major
+    REGEX "^ *# *define +UNBOUND_VERSION_MAJOR +[0-9]+.*$")
+  file(STRINGS "${UNBOUND_INCLUDE_DIR}/unbound.h" _minor
+    REGEX "^ *# *define +UNBOUND_VERSION_MINOR +[0-9]+.*$")
+  file(STRINGS "${UNBOUND_INCLUDE_DIR}/unbound.h" _micro
+    REGEX "^ *# *define +UNBOUND_VERSION_MICRO +[0-9]+.*$")
+  string(REGEX REPLACE "^[^0-9]+([0-9]+).*$" "\\1" _major ${_major})
+  string(REGEX REPLACE "^[^0-9]+([0-9]+).*$" "\\1" _minor ${_minor})
+  string(REGEX REPLACE "^[^0-9]+([0-9]+).*$" "\\1" _micro ${_micro})
+  set(UNBOUND_VERSION "${_major}.${_minor}.${_micro}")
+endif()
+
+find_package_handle_standard_args(Unbound
+  REQUIRED_VARS UNBOUND_LIBRARY UNBOUND_INCLUDE_DIR
+  VERSION_VAR UNBOUND_VERSION)
+if(Unbound_FOUND)
+  add_library(Unbound::Unbound UNKNOWN IMPORTED)
+  set_target_properties(Unbound::Unbound PROPERTIES
+    INTERFACE_INCLUDE_DIRECTORIES "${UNBOUND_INCLUDE_DIR}"
+    IMPORTED_LOCATION "${UNBOUND_LIBRARY}")
+  set(UNBOUND_PC_LIBS "${UNBOUND_LIBRARY}")
+endif()

Copied: serf/branches/user-defined-authn/build/SerfFindPkgConfig.cmake (from 
r1927607, serf/trunk/build/SerfFindPkgConfig.cmake)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ serf/branches/user-defined-authn/build/SerfFindPkgConfig.cmake      Mon Aug 
 4 10:32:19 2025        (r1927608, copy of r1927607, 
serf/trunk/build/SerfFindPkgConfig.cmake)
@@ -0,0 +1,64 @@
+# ===================================================================
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+# ===================================================================
+
+include(FindPackageHandleStandardArgs)
+include(GNUInstallDirs)
+find_package(PkgConfig QUIET)
+
+# Generate list of symbols to export from shared libraries..
+function(SerfFindPkgConfig name root pkgname target_alias)
+  set(${name}_FOUND FALSE PARENT_SCOPE)
+  if(PKG_CONFIG_FOUND)
+    # Save the PKG_CONFIG_PATH environment variable
+    set(pkg_config_path $ENV{PKG_CONFIG_PATH})
+
+    if(DEFINED ${root})
+      # Set the PKG_CONFIG_PATH environment variable for the search
+      find_path(_${name}_pcdir NAMES "${pkgname}.pc"
+                PATHS ${${root}} NO_DEFAULT_PATH
+                PATH_SUFFIXES
+                "lib/pkgconfig"
+                "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
+                "share/pkgconfig"
+                "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig")
+      if(_${name}_pcdir AND EXISTS "${_${name}_pcdir}/${pkgname}.pc")
+        set(ENV{PKG_CONFIG_PATH} ${_${name}_pcdir})
+      endif()
+    endif()
+
+    string(TOUPPER "${name}" NAME)
+    pkg_search_module(${NAME} QUIET IMPORTED_TARGET ${pkgname})
+    if(${NAME}_FOUND)
+      find_package_handle_standard_args(${name}
+        REQUIRED_VARS ${NAME}_LINK_LIBRARIES ${NAME}_INCLUDEDIR
+        VERSION_VAR ${NAME}_VERSION)
+      if(${name}_FOUND)
+        add_library(${target_alias} ALIAS PkgConfig::${NAME})
+        set(${name}_FOUND ${${name}_FOUND} PARENT_SCOPE)
+        set(${NAME}_INCLUDE_DIR ${${NAME}_INCLUDEDIR} PARENT_SCOPE)
+        set(${NAME}_LIBRARY ${${NAME}_LINK_LIBRARIES} PARENT_SCOPE)
+        set(${NAME}_VERSION ${${NAME}_VERSION} PARENT_SCOPE)
+        set(${NAME}_PC_REQUIRES ${pkgname} PARENT_SCOPE)
+      endif()
+    endif()
+
+    # Restore the PKG_CONFIG_PATH environment variable
+    set(ENV{PKG_CONFIG_PATH} ${pkg_config_path})
+  endif()
+endfunction(SerfFindPkgConfig)

Modified: serf/branches/user-defined-authn/build/SerfMacOS.cmake
==============================================================================
--- serf/branches/user-defined-authn/build/SerfMacOS.cmake      Mon Aug  4 
10:01:39 2025        (r1927607)
+++ serf/branches/user-defined-authn/build/SerfMacOS.cmake      Mon Aug  4 
10:32:19 2025        (r1927608)
@@ -52,6 +52,7 @@ function(serf_macos_find_packages)
   endif()
   _serf_macos__find_package("brotli" Brotli_ROOT "Path to Brotli's install 
area")
   _serf_macos__find_package("gssapi" GSSAPI_ROOT "Path to GSSAPI's install 
area")
+  _serf_macos__find_package("unbound" Unbound_ROOT "Path to Unbound's install 
area")
 endfunction()
 
 #

Modified: serf/branches/user-defined-authn/build/exports.py
==============================================================================
--- serf/branches/user-defined-authn/build/exports.py   Mon Aug  4 10:01:39 
2025        (r1927607)
+++ serf/branches/user-defined-authn/build/exports.py   Mon Aug  4 10:32:19 
2025        (r1927608)
@@ -108,15 +108,6 @@ class ExportGenerator(object):
       return TARGET_WINDLL
     if sys.platform == 'darwin':
       return TARGET_MACHO
-    # FIXME: SConstruct checks for ELF, these should probably be removed.
-    # if sys.platform.startswith('linux'):
-    #   return TARGET_ELF
-    # if (sys.platform.startswith('freebsd') and int(sys.platform[7:]) >= 4):
-    #   return TARGET_ELF
-    # if (sys.platform.startswith('openbsd') and int(sys.platform[7:]) >= 6):
-    #   return TARGET_ELF
-    # if (sys.platform.startswith('netbsd') and int(sys.platform[6:]) >= 2):
-    #   return TARGET_ELF
     return None
 
   def _gen_win_def(self, stream, symbols):

Modified: serf/branches/user-defined-authn/build/serf.pc.in
==============================================================================
--- serf/branches/user-defined-authn/build/serf.pc.in   Mon Aug  4 10:01:39 
2025        (r1927607)
+++ serf/branches/user-defined-authn/build/serf.pc.in   Mon Aug  4 10:32:19 
2025        (r1927608)
@@ -7,7 +7,7 @@ includedir=${prefix}/include/@INCLUDE_SU
 Name: serf
 Description: HTTP client library
 Version: @VERSION@
-Requires.private: libssl libcrypto
+Requires.private: @REQUIRES@
 Libs: -L${libdir} -lserf-${SERF_MAJOR_VERSION}
 Libs.private: @LIBS@
-Cflags: -I${includedir}
+Cflags: @CFLAGS@ -I${includedir}

Reply via email to