Author: brane Date: Sun Jun 8 00:17:52 2025 New Revision: 1926222 URL: http://svn.apache.org/viewvc?rev=1926222&view=rev Log: Make the SCons build work with SCons versions earlier than 4.7.0. Tested with 4.4.0 and our baseline 2.3.0 (with Python 2.7.18).
* LICENSE, NOTICE: Add the SCons license, because we now reuse some code from SCons 4.7.0. * SConstruct: Add StringIO compatibility for Python 2.7, needed for Scons 2.3.0. Replace Conftest.CheckFunc with our own version for SCons < 4.7. Add our extra check functions to every instance of Configuration. (CheckGnuCC): Move to the new build.scons_extras module. * build/__init__.py: New. * build/scons_extras.py: New. (CheckGnuCC): Moved here from SConstruct. (CheckFunc): Replacement test for older versions of SCons, copied essentially unchanged from SCons 4.7.0. Added: serf/trunk/build/__init__.py (with props) serf/trunk/build/scons_extras.py (with props) Modified: serf/trunk/LICENSE serf/trunk/NOTICE serf/trunk/SConstruct Modified: serf/trunk/LICENSE URL: http://svn.apache.org/viewvc/serf/trunk/LICENSE?rev=1926222&r1=1926221&r2=1926222&view=diff ============================================================================== --- serf/trunk/LICENSE (original) +++ serf/trunk/LICENSE Sun Jun 8 00:17:52 2025 @@ -200,3 +200,34 @@ 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. + + +ADDITIONAL LICENSES: + +For parts of the configuration code in build/scons_extras.py: + + +I. MIT License + + Copyright The SCons Foundation + Copyright (c) 2003 Stichting NLnet Labs + Copyright (c) 2001, 2002, 2003 Steven Knight + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Modified: serf/trunk/NOTICE URL: http://svn.apache.org/viewvc/serf/trunk/NOTICE?rev=1926222&r1=1926221&r2=1926222&view=diff ============================================================================== --- serf/trunk/NOTICE (original) +++ serf/trunk/NOTICE Sun Jun 8 00:17:52 2025 @@ -5,3 +5,6 @@ This product includes software developed under Contributor License Agreements to The Apache Software Foundation (http://www.apache.org/). See the revision logs for an exact contribution history. + +This product includes software developed by the SCons Foundation under the +MIT license, see LICENSE. Modified: serf/trunk/SConstruct URL: http://svn.apache.org/viewvc/serf/trunk/SConstruct?rev=1926222&r1=1926221&r2=1926222&view=diff ============================================================================== --- serf/trunk/SConstruct (original) +++ serf/trunk/SConstruct Sun Jun 8 00:17:52 2025 @@ -21,25 +21,41 @@ # import sys -import io import os import re EnsureSConsVersion(2,3,0) -# SCons 4.7 introduced the argument list parameter to CheckFunc. -# Of course, GetSConsVersion() was added in 4.8, it's more fun that way. -have_check_func = False + +# Compatibility with old versions of SCons +try: + # Python 2 / SCons 2.3.0 etc. + from cStringIO import StringIO + print("warning: replaced StringIO() for Python version < 3.") +except ImportError: + # Python 3 + from io import StringIO + +# Set up our additional config tests. +src_dir = File('SConstruct').rfile().get_dir().abspath +sys.path.insert(0, src_dir) +import build.scons_extras + +custom_tests = {'CheckGnuCC': build.scons_extras.CheckGnuCC} + +# SCons 4.7 introduced the function argument list parameter to CheckFunc. try: - if GetSConsVersion() >= (4, 7): - def CheckFunc(conf, name, code, lang='C', args=''): - return conf.CheckFunc(name, code, lang, args) - have_check_func = True -except NameError: + import SCons.Conftest as _conftest + _conftest.CheckFunc(None, 'clock', '#include <time.h>', 'C', '') +except AttributeError: + # This comes from the 'None' context argument, above. It's fine, we just + # proved that CheckFunc has the funcargs parameter, so we don't have to + # replace it with our own implementation. pass -if not have_check_func: - def CheckFunc(conf, name, code, lang='C', _=''): - return conf.CheckFunc(name, code, lang) +except TypeError: + # We have version < 4.7 without funcargs, use our replacement CheckFunc. + custom_tests['CheckFunc'] = build.scons_extras.CheckFunc + print('warning: replaced Conftest.CheckFunc() for SCons version < 4.7.') HEADER_FILES = ['serf.h', @@ -292,7 +308,7 @@ if sys.platform != 'win32': context.Result(result) return result - conf = Configure(env, custom_tests = dict(CheckGnuCC=CheckGnuCC)) + conf = Configure(env, custom_tests=custom_tests) have_gcc = conf.CheckGnuCC() env = conf.Finish() @@ -440,7 +456,7 @@ if sys.platform == 'win32': else: env.Append(CPPPATH=['$OPENSSL/inc32'], LIBPATH=['$OPENSSL/out32dll']) - conf = Configure(env) + conf = Configure(env, custom_tests=custom_tests) if conf.CheckLib('libcrypto'): # OpenSSL 1.1.0+ env.Append(LIBS=['libcrypto.lib', 'libssl.lib']) @@ -523,38 +539,38 @@ else: # Check for OpenSSL functions which are only available in some of # the versions we support. Also handles forks like LibreSSL. -with io.StringIO(env.File('buckets/ssl_buckets.c') - .rfile().get_text_contents()) as stream: - ssl_include_rx = re.compile(r'^\s*#\s*include\s+<openssl/[^>]+>') - ssl_include_list = [] - for line in stream.readlines(): - if ssl_include_rx.match(line): - ssl_include_list.append(line.rstrip()) +ssl_include_rx = re.compile(r'^\s*#\s*include\s+<openssl/[^>]+>') +ssl_include_list = [] +stream = StringIO(env.File('buckets/ssl_buckets.c') + .rfile().get_text_contents()) +for line in stream.readlines(): + if ssl_include_rx.match(line): + ssl_include_list.append(line.rstrip()) ssl_includes = '\n'.join(ssl_include_list) -conf = Configure(env) -if not CheckFunc(conf, 'BIO_set_init', ssl_includes, 'C', 'NULL, 0'): +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']) -if not CheckFunc(conf, 'X509_STORE_get0_param', ssl_includes, 'C', 'NULL'): +if not conf.CheckFunc('X509_STORE_get0_param', ssl_includes, 'C', 'NULL'): env.Append(CPPDEFINES=['SERF_NO_SSL_X509_STORE_WRAPPERS']) -if not CheckFunc(conf, 'X509_get0_notBefore', ssl_includes, 'C', 'NULL'): +if not conf.CheckFunc('X509_get0_notBefore', ssl_includes, 'C', 'NULL'): env.Append(CPPDEFINES=['SERF_NO_SSL_X509_GET0_NOTBEFORE']) -if not CheckFunc(conf, 'X509_get0_notAfter', ssl_includes, 'C', 'NULL'): +if not conf.CheckFunc('X509_get0_notAfter', ssl_includes, 'C', 'NULL'): env.Append(CPPDEFINES=['SERF_NO_SSL_X509_GET0_NOTAFTER']) -if not CheckFunc(conf, 'X509_STORE_CTX_get0_chain', ssl_includes, 'C', 'NULL'): +if not conf.CheckFunc('X509_STORE_CTX_get0_chain', ssl_includes, 'C', 'NULL'): env.Append(CPPDEFINES=['SERF_NO_SSL_X509_GET0_CHAIN']) -if not CheckFunc(conf, 'ASN1_STRING_get0_data', ssl_includes, 'C', 'NULL'): +if not conf.CheckFunc('ASN1_STRING_get0_data', ssl_includes, 'C', 'NULL'): env.Append(CPPDEFINES=['SERF_NO_SSL_ASN1_STRING_GET0_DATA']) -if CheckFunc(conf, 'CRYPTO_set_locking_callback', ssl_includes, 'C', 'NULL'): +if conf.CheckFunc('CRYPTO_set_locking_callback', ssl_includes, 'C', 'NULL'): env.Append(CPPDEFINES=['SERF_HAVE_SSL_LOCKING_CALLBACKS']) -if CheckFunc(conf, 'OPENSSL_malloc_init', ssl_includes): +if conf.CheckFunc('OPENSSL_malloc_init', ssl_includes): env.Append(CPPDEFINES=['SERF_HAVE_OPENSSL_MALLOC_INIT']) -if CheckFunc(conf, 'SSL_library_init', ssl_includes): +if conf.CheckFunc('SSL_library_init', ssl_includes): env.Append(CPPDEFINES=['SERF_HAVE_OPENSSL_SSL_LIBRARY_INIT']) -if CheckFunc(conf, 'OpenSSL_version_num', ssl_includes): +if conf.CheckFunc('OpenSSL_version_num', ssl_includes): env.Append(CPPDEFINES=['SERF_HAVE_OPENSSL_VERSION_NUM']) -if CheckFunc(conf, 'SSL_set_alpn_protos', ssl_includes, 'C', 'NULL, NULL, 0'): +if conf.CheckFunc('SSL_set_alpn_protos', ssl_includes, 'C', 'NULL, NULL, 0'): env.Append(CPPDEFINES=['SERF_HAVE_OPENSSL_ALPN']) if conf.CheckType('OSSL_HANDSHAKE_STATE', ssl_includes): env.Append(CPPDEFINES=['SERF_HAVE_OSSL_HANDSHAKE_STATE']) @@ -572,11 +588,11 @@ if sys.platform == 'win32': env.Append(CPPDEFINES=['SERF_HAVE_SSPI']) if brotli and CALLOUT_OKAY: - conf = Configure(env) + conf = Configure(env, custom_tests=custom_tests) if conf.CheckCHeader('brotli/decode.h') and \ - CheckFunc(conf, 'BrotliDecoderTakeOutput', - '#include <brotli/decode.h>', - 'C', 'NULL, NULL'): + 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')) @@ -610,7 +626,7 @@ pkgconfig = env.Textfile('serf-%d.pc' % env.Default(lib_static, lib_shared, pkgconfig) if CALLOUT_OKAY: - conf = Configure(env) + conf = Configure(env, custom_tests=custom_tests) ### some configuration stuffs if conf.CheckCHeader('stdbool.h'): @@ -672,7 +688,6 @@ else: check_script = env.File('build/check.py').rstr() test_dir = env.File('test/test_all.c').rfile().get_dir() -src_dir = env.File('serf.h').rfile().get_dir() test_app = ("%s %s %s %s") % (sys.executable, check_script, test_dir, 'test') # Set the library search path for the test programs Added: serf/trunk/build/__init__.py URL: http://svn.apache.org/viewvc/serf/trunk/build/__init__.py?rev=1926222&view=auto ============================================================================== (empty) Propchange: serf/trunk/build/__init__.py ------------------------------------------------------------------------------ svn:eol-style = native Added: serf/trunk/build/scons_extras.py URL: http://svn.apache.org/viewvc/serf/trunk/build/scons_extras.py?rev=1926222&view=auto ============================================================================== --- serf/trunk/build/scons_extras.py (added) +++ serf/trunk/build/scons_extras.py Sun Jun 8 00:17:52 2025 @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +# scons_extras.py : SCons extensions and compatibility functinos. +# +# =================================================================== +# 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. +# =================================================================== + + +def CheckGnuCC(context): + '''Check if the compiler is compatible with gcc.''' + + src = ''' +#ifndef __GNUC__ +oh noes! +#endif +''' + + context.Display('Checking for GNU-compatible C compiler... ') + result = context.TryCompile(src, '.c') + context.Result(result) + return result + + +# +# The following code is derived from SCons, version 4.7.0. +# +# =================================================================== +# +# MIT License +# +# Copyright The SCons Foundation +# Copyright (c) 2003 Stichting NLnet Labs +# Copyright (c) 2001, 2002, 2003 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# =================================================================== + + +from SCons.Conftest import _YesNoResult, _lang2suffix + + +def CheckFunc(context, function_name, header=None, language=None, funcargs=''): + if context.headerfilename: + includetext = '#include "%s"' % context.headerfilename + else: + includetext = '' + if not header: + header = ''' +#ifdef __cplusplus +extern "C" +#endif +char %s(void);''' % function_name + + lang, suffix, msg = _lang2suffix(language) + if msg: + context.Display('Cannot check for %s(): %s\\n' % (function_name, msg)) + return msg + + text = ''' +%(include)s +#include <assert.h> +%(hdr)s + +#if _MSC_VER && !__INTEL_COMPILER + #pragma function(%(name)s) +#endif + +int main(void) { +#if defined (__stub_%(name)s) || defined (__stub___%(name)s) + #error "%(name)s has a GNU stub, cannot check" +#else + %(name)s(%(args)s); +#endif + + return 0; +} +''' % { 'name': function_name, + 'include': includetext, + 'hdr': header, + 'args': funcargs } + + context.Display('Checking for %s function %s()... ' % (lang, function_name)) + ret = context.BuildProg(text, suffix) + comment = "Define to 1 if the system has the function `%s'." % function_name + _YesNoResult(context, ret, 'HAVE_' + function_name, text, comment) + + # This is different than in SCons.Conftest -- it's how SCons.SConf + # tweaks the result int its wrappers. + context.did_show_result = 1 + return not ret Propchange: serf/trunk/build/scons_extras.py ------------------------------------------------------------------------------ svn:eol-style = native