From c35775882472110c7f00accb6adac71e0a8e61bb Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Tue, 22 Jan 2019 11:36:30 +0000 Subject: [PATCH] Incorporate user-customized configuration. --- ChangeLog | 12 ++ Makefile.comm | 12 +- mingwrt/ChangeLog | 14 ++ mingwrt/include/_mingw.h.in | 32 +++- mingwrt/tests/Makefile.in | 10 +- var/features.lua | 445 ++++++++++++++++++++++++++++++++++++++++++++ w32api/ChangeLog | 7 + w32api/tests/Makefile.in | 10 +- 8 files changed, 531 insertions(+), 11 deletions(-) create mode 100644 var/features.lua diff --git a/ChangeLog b/ChangeLog index e71ff54..4d47e53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2019-01-22 Keith Marshall + + Incorporate user-customized configuration. + + * Makefile.comm (_mingw.h): Add prerequisite dependency on... + (features.h): ...this; add rule to create a build-time stub, an empty + file, yielding the default fall-back configuration. + + * var/features.lua: New direcctory/file; this implements the mingw-get + post-install action, which is required to integrate management of user + maintained configuration alongside project updates. + 2018-12-23 Keith Marshall Adjust repository version following WSL-5.2 release. diff --git a/Makefile.comm b/Makefile.comm index af83ded..d8dcb7c 100644 --- a/Makefile.comm +++ b/Makefile.comm @@ -5,8 +5,8 @@ # # $Id$ # -# Written by Keith Marshall -# Copyright (C) 2017, MinGW.org Project +# Written by Keith Marshall +# Copyright (C) 2017, 2019, MinGW.org Project # # # Permission is hereby granted, free of charge, to any person obtaining a @@ -82,6 +82,14 @@ vpath %.h.in ${mingwrt_srcdir}/include ${w32api_srcdir}/include _mingw.h w32api.h: %.h: %.h.in VERSION.m4 $(PACKAGE_VERSION_SCRIPT) $< > $@ +# _mingw.h wants to include , which is nominally a user +# supplied header; for our build-time requirements, an empty file is +# sufficient, as _mingw.h provides suitable fall-back definitions. +# +_mingw.h: features.h +features.h: + > $@ + PACKAGE_VERSION_SCRIPT = sed \ -e s"`$(call PACKAGE_VERSION_FORMAT,LONG,%d,$$3+1000*($$2+1000*$$1))`" \ -e s"`$(call PACKAGE_VERSION_FORMAT,MAJOR,%7d,$$1)`" \ diff --git a/mingwrt/ChangeLog b/mingwrt/ChangeLog index 81a3946..df4517c 100644 --- a/mingwrt/ChangeLog +++ b/mingwrt/ChangeLog @@ -1,3 +1,17 @@ +2019-01-22 Keith Marshall + + Incorporate user-customized configuration. + + * include/_mingw.h: Include , or... + [_MINGW_FEATURES_HEADER]: ...nominated alternative header. + [!defined __MINGW_FEATURES__]: Provide fall-back definition. + (__MINGW_FEATURES_BEGIN__, __MINGW_FEATURES_ENABLE__) + (__MINGW_FEATURES_IGNORE__, __MINGW_FEATURES_UNSET__) + (__MINGW_FEATURES_END__): New macros; define them. + + * tests/Makefile.in (install-mingwrt): Create stub; this + is an empty file, yielding the default fall-back configuration. + 2019-01-21 Keith Marshall Handle another GCC compile-time warning. diff --git a/mingwrt/include/_mingw.h.in b/mingwrt/include/_mingw.h.in index d7621b0..b72b853 100644 --- a/mingwrt/include/_mingw.h.in +++ b/mingwrt/include/_mingw.h.in @@ -7,7 +7,7 @@ * $Id$ * * Written by Mumit Khan - * Copyright (C) 1999, 2001-2011, 2014-2018, MinGW.org Project + * Copyright (C) 1999, 2001-2011, 2014-2019, MinGW.org Project * * * Permission is hereby granted, free of charge, to any person obtaining a @@ -161,6 +161,36 @@ #define __CRT_GLOB_ESCAPE_CHAR__ (char)(127) +/* Load any user-customized features configuration... + */ +#ifdef _MINGW_FEATURES_HEADER +/* ...from a user-specified, or project-specified alternative file... + */ +#include _MINGW_FEATURES_HEADER +#else +/* ...or fall back to the default configuration file, (which may, + * or may not have been customized). + */ +#include +#endif + +#ifndef __MINGW_FEATURES__ +/* Regardless of how the preceding features configuration header was + * identified, we normally expect that will have defined this, but we + * supply this fall-back, just in case it is needed. + */ +#define __MINGW_FEATURES__ 0ULL +#endif + +/* Define macros to facilitate the user-specified configuration. + */ +#define __MINGW_FEATURE_ENABLE__(__FEATURE__) | (__FEATURE__) +#define __MINGW_FEATURE_IGNORE__(__FEATURE__) + +#define __MINGW_FEATURES_BEGIN__ 0x0000000000000000ULL +#define __MINGW_FEATURES_UNSET__ 0x0000000000000000ULL +#define __MINGW_FEATURES_END__ + /* Manifest definitions identifying the flag bits, controlling activation * of MinGW features, as specified by the user in __MINGW_FEATURES__. */ diff --git a/mingwrt/tests/Makefile.in b/mingwrt/tests/Makefile.in index 2bdf904..5951eac 100644 --- a/mingwrt/tests/Makefile.in +++ b/mingwrt/tests/Makefile.in @@ -5,7 +5,7 @@ # $Id$ # # Written by Keith Marshall -# Copyright (C) 2016, 2017, MinGW.org Project +# Copyright (C) 2016, 2017, 2019, MinGW.org Project # # # Permission is hereby granted, free of charge, to any person obtaining a @@ -130,14 +130,16 @@ $(info ) endef # Install a local copy of the package components to be tested; we need -# the full mingwrt package, and also the w32api headers, to ensure that -# we are testing what we've built, and not those which were installed -# with whatever compiler we are using for the build. +# the full mingwrt package, including a stub, and also the +# w32api headers, to ensure that we are testing what we've built, and +# not those which were installed with whatever compiler we are using +# for the build. # testsuite.install: install-mingwrt install-w32api-headers install-mingwrt: $(MAKE) -C .. --no-print-directory prefix=${CURDIR} $@ + >> include/features.h chkconfig = ($1/config.status --version | grep $2) 2>&1 > /dev/null install-w32api-headers: diff --git a/var/features.lua b/var/features.lua new file mode 100644 index 0000000..0ce3c64 --- /dev/null +++ b/var/features.lua @@ -0,0 +1,445 @@ +-- +-- features.lua +-- +-- $Id$ +-- +-- Lua 5.2 module providing a mingw-get setup hook for configuration of +-- the user's MinGW GCC compiler preferences. +-- +-- Written by Keith Marshall +-- Copyright (C) 2019, MinGW.org Project +-- +-- +-- 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. +-- +-- +-- We begin by initializing a container, for construction of a Lua module +-- to encapsulate the content of this source file. +-- + local M = {} +-- +-- mingw-get passes the MinGW installation root directory path, in the +-- $MINGW32_SYSROOT environment variable; from this, we deduce the path +-- name for the working copy of the features.h file... +-- + local function syspath( varname ) +-- +-- ...using this local helper function to ensure that the path name +-- string, returned from the environment, is free from insignificant +-- trailing directory name separators, and that all internal sequences +-- of directory name separators are normalized to a single '/'. +-- + local pathname = os.getenv( varname ) + if pathname + then + pathname = string.gsub( pathname, "[/\\]+", "/" ) + pathname = string.match( pathname, "(.*[^/])/*$" ) + end + return pathname + end + local sysroot = syspath( "MINGW32_SYSROOT" ) + if not sysroot + then + error( "environment variable MINGW32_SYSROOT may not be set", 0 ) + end + local config_file_name = sysroot .. "/include/features.h" +-- +-- Define a template, whence the default features configuration may be +-- deduced when writing the initial content of the file. +-- + local config_default = + { '/*', + ' * features.h', + ' *', + ' * Features configuration for MinGW.org GCC implementation; users may', + ' * customize this file, to establish their preferred default behaviour.', + ' * Projects may provide an alternative, package-specific configuration,', + ' * either by placing their own customized in the package', + ' * -I path, ahead of the system default, or by assignment of their', + ' * preferred alternative to the _MINGW_FEATURES_HEADER macro.', + ' *', + ' *', + ' * $'..'Id$', + ' *', + ' * Template written by Keith Marshall ', + ' * Copyright (C) 2019, MinGW.org Project.', + ' *', + ' *', + ' * 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, this permission notice, and the following', + ' * disclaimer 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 OF OR OTHER', + ' * DEALINGS IN THE SOFTWARE.', + ' *', + ' */', + '#ifndef __MINGW_FEATURES__', + '#pragma GCC system_header', + '', + '/* Users are expected to customize this header, but it remains subject to', + ' * automatic updates by system software. To ensure that any customisation', + ' * is not ovewritten, during such updates, it MUST observe the following:', + ' *', + ' * This header MUST define __MINGW_FEATURES__; the definition MUST begin', + ' * with "#define __MINGW_FEATURES__ (__MINGW_FEATURES_BEGIN__) \\"; it MUST', + ' * extend over multiple lines, and terminate with "__MINGW_FEATURES_END__";', + ' * intervening lines may enumerate any defined features, one per line, and', + ' * each specified as an argument to either the __MINGW_FEATURE_ENABLE__(),', + ' * or the __MINGW_FEATURE_IGNORE__() macro, (ensuring that at least one', + ' * space separates either of these macro names from its parenthesized', + ' * argument name).', + ' *', + ' * CAUTION:', + ' * If customizing this features configuration, ALWAYS refer to features', + ' * using their designated symbolic constant names; NEVER usurp the use of', + ' * these symbolic constants for any other purpose, and NEVER assume that', + ' * any such constant has a specific value ... their definitions may vary', + ' * between distinct MinGW Runtime Library software releases!', + ' */', + '#define __MINGW_FEATURES__ (__MINGW_FEATURES_BEGIN__) \\', + ' __MINGW_FEATURE_IGNORE__ (__MINGW_ANSI_STDIO__) \\', + ' __MINGW_FEATURE_IGNORE__ (__MINGW_LC_MESSAGES__) \\', + ' __MINGW_FEATURE_IGNORE__ (__MINGW_LC_ENVVARS__) \\', + ' __MINGW_FEATURES_END__', + '', + '#endif /* !__MINGW_FEATURES__: $'..'RCSfile$: end of file */' + } +-- + local function defines( name ) +-- +-- A local helper function, to generate a string.match +-- pattern for identification of any C #define statement, +-- which defines a specified symbol "name" +-- + return "^%s*#%s*define%s+" .. name + end +-- + local function feature( value ) +-- +-- A local helper function, to generate a string.match +-- pattern for identification of a specified parenthesized +-- value field, within a C #define statement. +-- + return "%s+%(%s*" .. value .. "%s*%)%s*" + end +-- + local function begins_definition( line, name, value ) +-- +-- A local helper function to check whether any input "line" +-- represents the first of a multiline C #define for the "name" +-- symbol, with its initial field matching the parenthesized +-- "value" token (default: "__MINGW_FEATURES_BEGIN__"). +-- + if not value then value = "__MINGW_FEATURES_BEGIN__" end + return string.match( line, defines( name ) .. feature( value ) .. "\\$" ) + end +-- +-- In the event that a features configuration has already been +-- specified for this installation, capture this into internal +-- "as built" configuration tables... +-- + local current_config, current_features + local config = io.open( config_file_name ) + if config + then +-- ...always starting collection into table "current_config"... +-- + current_config = {} + local active_list = current_config +-- +-- ...reading the existing configuration file, line by line... +-- + for line in config:lines() + do if active_list == current_features + and string.match( line, "^%s*__MINGW_FEATURES_END__%s*$" ) + then +-- ...noting that actual configuration options will have +-- been diverted to the "current_features" table; when all +-- such options have been captured, redirect any residual +-- content to the "current_config" table. +-- + active_list = current_config + end +-- +-- Capture the current configuration record, into whichever +-- diversion is currently active. +-- + table.insert( active_list, line ) +-- + if begins_definition( line, "__MINGW_FEATURES__" ) + then +-- When we find the first line of a (possibly) well-formed +-- features configuration, divert capture of its subsequent +-- lines to a new "current_features" table. +-- + current_features = {} + active_list = current_features + end + end +-- +-- When capture is complete, ensure that the input stream file +-- is closed; (we may want to reopen it later, to rewrite it). +-- + io.close( config ) +-- +-- Before we go any further, check for well-formedness of the +-- configuration which we have just captured; effectively... +-- + if not current_features + or active_list == current_features + then +-- ...when no "current_features" diversion has been created, +-- or such a diversion remains open for capture, then an error +-- has occurred, and the configuration is not well-formed. +-- + local function config_error( reason ) + error( config_file_name .." ".. reason, 0 ) + end + for ref, line in next, current_config + do if string.match( line, defines( "__MINGW_FEATURES__" ) ) + then +-- In this case, a "__MINGW_FEATURES__" definition is +-- present, but it is not well-formed; (note that, here, +-- we rescan the "current_config" table, using a less +-- rigorous criterion for detection of a definition of +-- of "__MINGW_FEATURES__" than that which is required +-- to open the "current_features" diversion)... +-- + config_error( "has malformed __MINGW_FEATURES__ definition" ) + end + end +-- ...while in this case, no "__MINGW_FEATURES__" definition +-- was found, (well-formed, or otherwise). +-- + config_error( "does not define __MINGW_FEATURES__" ) + end + end +-- +-- + local function update_configuration( stream_file, template, current ) +-- +-- A function to write a features configuration to a designated output +-- stream, based on a specified template, reproducing and encapsulating +-- any existing configuration which may also have been specified... +-- + local function stream_file_writeln( line ) +-- +-- ...using this helper function to write each line. +-- + stream_file:write( line .. "\n" ) + end +-- + if current + then +-- An existing configuration header is to be updated. An image of +-- its original content has already been loaded into "current"; copy +-- it back to the original file, line by line... +-- + for ref, line in next, current + do if begins_definition( line, "__MINGW_FEATURES__" ) + then +-- ...until we reach the first active configuration record. +-- We now wish to merge any new configuration options from the +-- template, into the existing configuration; work through the +-- template, line by line, ignoring all lines... +-- + local merge = false + for ref, sub in next, template + do if begins_definition( sub, "__MINGW_FEATURES__" ) + then +-- ...until we find the first line of a (possibly) +-- well-formed features configuration record; when we +-- find this, we decompose and reassemble it, so that +-- we may preserve a tabulation format matching the +-- longer of the template and actual configuration +-- records. +-- + local def = string.match( sub, "^[^(]*" ) + local usr = string.match( line, "^[^(]*" ) + if string.len( usr ) > string.len( def ) + then + def = usr + end + usr = string.match( line, "%(.*" ) + sub = string.match( sub, "%(.*" ) + if string.len( usr ) > string.len( sub ) + then + sub = usr + end +-- +-- Write out the reassembled features configuration +-- start record, and activate the features merge. +-- + stream_file_writeln( def .. sub ) + merge = true +-- +-- During the merge operation, when we find the record +-- terminator within the template... +-- + elseif string.match( sub, "^%s*__MINGW_FEATURES_END__%s*$" ) + then +-- ...we immediately write out any additional option +-- specifications, which remain in the user specified +-- configuration... +-- + for ref, sub in next, current_features + do + stream_file_writeln( sub ) + end +-- +-- ...and break out of the merge cycle. +-- + break +-- + elseif merge + then +-- While we remain within the merge cycle, we extract +-- the identification of each configuration option from +-- the template, comparing it with all entries in the +-- "current_features" table... +-- + tag = string.match( sub, "%(.*%)" ) + for ref, usr in next, current_features + do if string.match( usr, tag ) + then +-- +-- ...and, when we find a match, we favour the +-- existing configuration record over that from +-- the template... +-- + sub = usr +-- +-- ...remove the corresponding entry from the +-- "current_features" table, and break out of +-- the inner matching loop, before... +-- + table.remove( current_features, ref ) + break + end + end +-- +-- ...in either event, writing out a copy of each +-- selected configuration record. +-- + stream_file_writeln( sub ) + end + end + else +-- +-- For every line in the existing configuration file, outside +-- the scope of the "__MINGW_FEATURES__" definition itself, we +-- simply write out a verbatim copy of each line. +-- + stream_file_writeln( line ) + end + end + else +-- +-- There is no existing configuration header, so we simply reproduce +-- the template, processing it line by line... +-- + for ref, line in next, template + do +-- ...and writing out each line individually. +-- + stream_file_writeln( line ) + end + end + end +-- +-- + function M.pathname( suffix ) +-- +-- An exported utility function, to facilitate identification of +-- the full MS-Windows path name for the features.h configuration +-- file, as appropriate to the current installation... +-- + if suffix + then +-- ...appending any suffix which may have been specified, (e.g. +-- to specify a reference to the features.h.sample file)... +-- + return config_file_name .. suffix + end +-- +-- ...otherwise, specifying a reference to features.h itself. +-- + return config_file_name + end +-- +-- + function M.initialize( stream_file ) +-- +-- Primary initialization function; overwrites any existing features +-- configuration header, opened for writing as "stream_file"... +-- + if not stream_file + then +-- ...or falling back to "io.stderr", in the event that no output +-- stream file has been opened... +-- + stream_file = io.stdout + end +-- +-- ...replacing any existing configuration with an exact copy of the +-- "config_default" content specified within this module. +-- + update_configuration( stream_file, config_default ) + end +-- +-- + function M.update( stream_file ) +-- +-- Primary API function, exported for use by mingw-get (or any other +-- client); overwrites any existing configuration header file, which +-- has been opened for writing as "stream_file"... +-- + if not stream_file + then +-- ...or falling back to "io.stderr", in the event that no output +-- stream file has been opened... +-- + stream_file = io.stdout + end +-- +-- ...preserving any existing configuration, with the addition of +-- any configuration options which have been included in the default +-- template, but which do not yet appear in the existing header. +-- + update_configuration( stream_file, config_default, current_config ) + end +-- +-- Since this source file is intended to be loaded as a Lua module, we +-- must ultimately return a reference handle for it. +-- + return M +-- +-- $RCSfile$: end of file */ diff --git a/w32api/ChangeLog b/w32api/ChangeLog index 18d590d..f926e4f 100644 --- a/w32api/ChangeLog +++ b/w32api/ChangeLog @@ -1,3 +1,10 @@ +2019-01-22 Keith Marshall + + Incorporate user-customized configuration. + + * tests/Makefile.in (install-mingwrt-headers): Create + stub; this is an empty file, yielding the default configuration. + 2018-12-23 Keith Marshall Prepare and publish MinGW.org WSL-5.2 release. diff --git a/w32api/tests/Makefile.in b/w32api/tests/Makefile.in index 347ec78..f57f129 100644 --- a/w32api/tests/Makefile.in +++ b/w32api/tests/Makefile.in @@ -5,7 +5,7 @@ # $Id$ # # Written by Keith Marshall -# Copyright (C) 2017, MinGW.org Project +# Copyright (C) 2017, 2019, MinGW.org Project # # # Permission is hereby granted, free of charge, to any person obtaining a @@ -131,9 +131,10 @@ $(info ) endef # Install a local copy of the package components to be tested; we need -# the full w32api package, and also the mingwrt headers, to ensure that -# we are testing what we've built, and not those which were installed -# with whatever compiler we are using for the build. +# the full w32api package, and also the mingwrt headers, including a stub +# for , to ensure that we are testing what we've built, and +# not those which were installed with whatever compiler we are using +# for the build. # testsuite.install: install-w32api install-mingwrt-headers @@ -142,6 +143,7 @@ install-w32api: chkconfig = ($1/config.status --version | grep $2) 2>&1 > /dev/null install-mingwrt-headers: + >> include/features.h @for dir in ../../mingwrt*; do \ if $(call chkconfig,$$dir,'MinGW C Runtime'); then \ $(MAKE) -C $$dir --no-print-directory prefix=${CURDIR} $@; break; \ -- 2.11.0