Author: brane Date: Mon Aug 4 05:26:05 2025 New Revision: 1927602 Log: Build system improvements.
* SConstruct: - Better default values for dependency and install locations. - Generate a valid pkg-config file on Windows, and add importand build definitions to it (inherited from APR). - Use the common exports generator, retire gen-def.py. * CMakeLists.txt: - Properly install debug info files in multi-config builds. - Update pkg-config generation to match SConstruct. - Show the pkg-config location in the summary. * build/gen_def.py: Removed. * build/serf.pc.in (@REQUIRES@): Renamed from @PC_REQUIRES@. (@CFLAGS@): New placeholdsr. Deleted: serf/trunk/build/gen_def.py Modified: serf/trunk/CMakeLists.txt serf/trunk/SConstruct serf/trunk/build/exports.py serf/trunk/build/serf.pc.in Modified: serf/trunk/CMakeLists.txt ============================================================================== --- serf/trunk/CMakeLists.txt Mon Aug 4 04:42:25 2025 (r1927601) +++ serf/trunk/CMakeLists.txt Mon Aug 4 05:26:05 2025 (r1927602) @@ -454,11 +454,14 @@ 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}") + # string(TOLOWER "${CMAKE_BUILD_TYPE}" config) + # if(NOT "${config}" STREQUAL "release") + # install(FILES $<TARGET_PDB_FILE:serf_shared> + # DESTINATION "${SERF_INSTALL_RUNTIME}") + # endif() endif() endif() @@ -511,11 +514,14 @@ function(make_pkgconfig) set(LIBDIR \${prefix}/${SERF_INSTALL_LIBRARIES}) set(VERSION ${SERF_VERSION}) set(MAJOR ${SERF_MAJOR_VERSION}) - set(PC_REQUIRES + set(REQUIRES "libssl" "libcrypto" ${UNBOUND_PC_REQUIRES} ) + set(CFLAGS + ${APR_CFLAGS} + ) set(LIBS ${APR_LDFLAGS} ${APR_LIBRARIES} @@ -523,14 +529,17 @@ function(make_pkgconfig) ${APRUTIL_LDFLAGS} ${APRUTIL_LIBRARIES} ${APRUTIL_EXTRALIBS} + ${ZLIB_LIBRARIES} ${BROTLI_COMMON_LIBRARY} ${BROTLI_DECODE_LIBRARY} ${GSSAPI_LIBRARIES} ${UNBOUND_PC_LIBS} - ${ZLIB_LIBRARIES} + ${SERF_STANDARD_LIBRARIES} ) - list(REMOVE_DUPLICATES PC_REQUIRES) - list(JOIN PC_REQUIRES " " PC_REQUIRES) + 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) @@ -615,6 +624,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/trunk/SConstruct ============================================================================== --- serf/trunk/SConstruct Mon Aug 4 04:42:25 2025 (r1927601) +++ serf/trunk/SConstruct Mon Aug 4 05:26:05 2025 (r1927602) @@ -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' @@ -227,14 +227,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: @@ -318,6 +310,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. @@ -416,12 +409,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 +429,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 +481,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 +539,19 @@ 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') + + env.Append(LIBS=win_std_libs) else: if CALLOUT_OKAY: @@ -574,17 +583,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 +610,11 @@ 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') # Check for OpenSSL functions which are only available in some of # the versions we support. Also handles forks like LibreSSL. @@ -655,6 +666,7 @@ 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']) @@ -695,9 +707,12 @@ for d in env['LIBPATH']: env.Append(RPATH=[':'+d]) # Set up the construction of serf-*.pc -PC_REQUIRES = ['libssl', 'libcrypto'] # TODO: Add dependency modules -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 = { @@ -705,11 +720,10 @@ pkgconfig = env.Textfile('serf-%d.pc' % '@PREFIX@': unsubstable('${pcfiledir}/' + pkgprefix), '@LIBDIR@': unsubstable('${prefix}/' + pkglibdir), '@INCLUDE_SUBDIR@': 'serf-%d' % (MAJOR,), - '@PC_REQUIRES@': ' '.join(PC_REQUIRES), + '@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) @@ -734,11 +748,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/trunk/build/exports.py ============================================================================== --- serf/trunk/build/exports.py Mon Aug 4 04:42:25 2025 (r1927601) +++ serf/trunk/build/exports.py Mon Aug 4 05:26:05 2025 (r1927602) @@ -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/trunk/build/serf.pc.in ============================================================================== --- serf/trunk/build/serf.pc.in Mon Aug 4 04:42:25 2025 (r1927601) +++ serf/trunk/build/serf.pc.in Mon Aug 4 05:26:05 2025 (r1927602) @@ -7,7 +7,7 @@ includedir=${prefix}/include/@INCLUDE_SU Name: serf Description: HTTP client library Version: @VERSION@ -Requires.private: @PC_REQUIRES@ +Requires.private: @REQUIRES@ Libs: -L${libdir} -lserf-${SERF_MAJOR_VERSION} Libs.private: @LIBS@ -Cflags: -I${includedir} +Cflags: @CFLAGS@ -I${includedir}