[adwaita-icon-theme/wip/nmake] Build: Support Windows/MSVC using NMake



commit 03a5d8b50925db66fbea3adc0745d2fd0efcc3a1
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Mon Feb 15 16:19:05 2016 +0800

    Build: Support Windows/MSVC using NMake
    
    This adds a set of NMake Makefiles, with a set of support files that
    is used to generate the full index.theme file, and to copy the icon/
    cursor files in Windows, under Visual Studio builds.  Note that since
    UNIX-style symlinks are not supported under Windows, we generate a
    .bat script during 'make dist' so that we can copy the real files that
    the symlinks point to, to replace the symlinks on Windows.

 Makefile.am                    |    2 +-
 build/Makefile.am              |    1 +
 build/win32/Makefile.am        |   32 ++++++++
 build/win32/README.txt         |   65 ++++++++++++++++
 build/win32/adwaita-msvc.mak   |  158 ++++++++++++++++++++++++++++++++++++++++
 build/win32/apply_dirs.py      |   21 +++++
 build/win32/detectenv-msvc.mak |   68 +++++++++++++++++
 build/win32/replace.py         |   98 +++++++++++++++++++++++++
 configure.ac                   |    2 +
 9 files changed, 446 insertions(+), 1 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 0314802..3a7ae63 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
 DISTCHECK_CONFIGURE_FLAGS = --disable-icon-mapping
 
-SUBDIRS = src
+SUBDIRS = src build
 
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 
diff --git a/build/Makefile.am b/build/Makefile.am
new file mode 100644
index 0000000..0f81afe
--- /dev/null
+++ b/build/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = win32
diff --git a/build/win32/Makefile.am b/build/win32/Makefile.am
new file mode 100644
index 0000000..a271376
--- /dev/null
+++ b/build/win32/Makefile.am
@@ -0,0 +1,32 @@
+GENERATED_ITEMS = copy-actual.bat
+
+EXTRA_DIST =   \
+       adwaita-msvc.mak        \
+       apply_dirs.py           \
+       detectenv-msvc.mak      \
+       README.txt              \
+       replace.py              \
+       $(GENERATED_ITEMS)
+
+# Windows does not support UNIX-style symlinks, so we need to
+# find out what files are really symlinks, and copy the real files
+# that those symlinks point to, to replace those symlink files
+# during installation, in a batch script.  Also, as file decompressing
+# utilities might mix up symlinks with their targets, we need to work
+# around that by checking the file size in the batch and copy the other
+# way round if needed.
+
+symlinks_cmd := $(shell find $(top_srcdir)/Adwaita -type l)
+tree_top := ../..
+msvc_installpfx := %PREFIX%/share/icons
+copy_cmd := copy^/b^
+
+# I know that this command line is really messy, but any suggestions to
+# break this into more readable parts is really appreciated!
+realfile = $(foreach L,$(symlinks_cmd),for^%%F^in^\($(subst /,\\,$(addprefix $(subst 
$(top_srcdir),$(tree_top),$(dir $(L))),$(shell readlink 
$(L))))\)^do^if^not^\"%%~zF\"^==^\"0\"^\($(copy_cmd)$(subst /,\\,%%F^$(subst 
$(top_srcdir),$(msvc_installpfx),$(L))\))^else^\($(copy_cmd)$(subst /,\\,$(subst 
$(top_srcdir),$(tree_top),$(L))^$(subst $(top_srcdir),$(msvc_installpfx),$(dir $(L))))%%~nxF\))
+
+copy-actual.bat:
+       @echo 'set PREFIX=%1' > $@
+       @for l in $(realfile); do echo $$l | sed -e 's/\^/ /g' >>$@; done
+
+DISTCLEANFILES = $(GENERATED_ITEMS)
diff --git a/build/win32/README.txt b/build/win32/README.txt
new file mode 100644
index 0000000..1962eda
--- /dev/null
+++ b/build/win32/README.txt
@@ -0,0 +1,65 @@
+Please refer to the following GNOME Live! page for more detailed
+instructions on building this package with Visual C++:
+
+https://live.gnome.org/GTK%2B/Win32/MSVCCompilationOfGTKStack
+
+The gsettings-desktop-schemas-msvc.mak is an NMake Makefile that is meant
+to be used to generate the gsettings schema files and an enumeration
+XML file that is to be copied and "installed" on the running system
+by being copied to your gsettings schemas folder and processed by the
+glib-compile-schemas tool, where glib-compile-schemas is a part of the
+GLib package.
+
+The required dependencies are as follows:
+
+-An up-to-date GLib installation that was built with the Visual Studio version that
+ you intend to run gsettings-desktop-schemas-msvc.mak with, in the location pointed
+ to by $(PREFIX), which is <parentdir_of_srcroot>\vs<Visual Studio Version>\$(Platform)
+ unless set as some other paths otherwise, where Platform is Win32 for 32-bit builds
+ and x64 for x86-64 builds.
+
+-The glib-mkenums PERL script, that is found from the GLib sources that you have built
+ and installed above.  Copy gobject\glib-mkenums.in from the GLib source tree to
+ $(PREFIX)\bin\glib-mkenums, and change the
+ @GLIB_VERSION@ in that file to match the version of GLib that you have built and
+ installed, if it is not there yet.
+
+-A working installation of PERL, which could either be built from the sources or obtained
+ from distributions such as Strawberry PERL or ActiveState PERL.
+
+-A working installation of Python 2.7.x+ or 3.x, which could be built from the sources or
+ obtained from the installers from http://www.python.org.
+
+For introspection building, you will also need:
+-An up-to-date gobject-introspection installation that was built with the Visual Studio
+ version that you intend to run gsettings-desktop-schemas-msvc.mak with, including the
+ introspection files that are built with that package, in $(PREFIX).  Currently,
+ for introspection building, Python 2.7.x must be used; Python 3.x is currently not
+ supported.
+
+Run 'nmake /f gsettings-desktop-schemas-msvc.mak' to generate the needed schema files.
+If building the introspection files is desired, run 
+'nmake /f gsettings-desktop-schemas-msvc.mak introspection'.  A 'clean' target is
+provided to remove all the generated files.
+
+Please refer to the README.txt file in $(GLib_src_root)\build\win32\vs<Visual Studio Version>
+on how to build GLib using your version of Visual Studio.  Versions 2008 through 2015 are
+currently supported.
+
+Set up the source tree as follows under some arbitrary top
+folder <root>:
+
+<root>\<this-gsettings-desktop-schemas-source-tree>
+<root>\<Visual Studio Version>\<PlatformName>
+
+*this* file you are now reading is thus located at
+<root>\<this-gsettings-desktop-schemas-source-tree>\build\README.txt
+
+The "install" target will copy build results and headers into their
+appropriate location under <root>\vs<Visual Studio Version>\<PlatformName>.
+For instance, the *.schema.xml and *.enums.xml files will go into
+<root>\vs<Visual Studio Version>\<PlatformName>\share\glib-2.0\schemas,
+the header file goes into
+<root>\vs<Visual Studio Version>\<PlatformName>\include\gsettings-desktop-schemas.
+
+--Chun-wei Fan <fanc999 gmail com>
diff --git a/build/win32/adwaita-msvc.mak b/build/win32/adwaita-msvc.mak
new file mode 100644
index 0000000..601bcfa
--- /dev/null
+++ b/build/win32/adwaita-msvc.mak
@@ -0,0 +1,158 @@
+# NMake Makefile to generate the
+# complete index.theme file and to
+# install the icons
+
+!include detectenv-msvc.mak
+
+!IF "$(SRCROOTDIR)" == ""
+SRCROOTDIR=..\..
+!ENDIF
+
+# Python.exe either needs to be in your PATH or you need to pass
+# in PYTHON=<full-path-to-your-Python-executable> for this to work.
+# Either Python 2.7 or 3.x can be used
+
+!IF "$(PYTHON)" == ""
+PYTHON=python
+!ENDIF
+
+# Prefix of your installation.  Pass in PREFIX=<your-installation-prefix>
+# if needed.  gtk-update-icon-cache need to be found
+# in $(PREFIX)\bin
+!IF "$(PREFIX)" == ""
+PREFIX=$(SRCROOTDIR)\..\vs$(VSVER)\$(PLAT)
+!ENDIF
+
+ERRNUL  = 2>NUL
+_HASH=^#
+NULL=
+ICON_SUBDIR=share\icons\Adwaita
+
+# Generate the NMake Makefile modules for the listing of subdirs for each icon size
+!if [ for /f %s in ('dir /b /on $(SRCROOTDIR)\Adwaita') do @if not "%s" == "cursors" (@echo SIZE_%s_dirs = 
\> %s.mak) & (@for /f %d in ('dir /b $(SRCROOTDIR)\Adwaita\%s') do @echo %s/%d \>> %s.mak) & @echo ^$(NULL) 
%s.mak]
+!endif
+
+# We want underscores instead of dashes in the Makefile varnames
+!if [ren scalable-up-to-32.mak scalable-up-to-32.mak.tmp]
+!endif
+!if [$(PYTHON) replace.py --action=replace-str -i=scalable-up-to-32.mak.tmp -o=scalable-up-to-32.mak 
--instring=SIZE_scalable-up-to-32_dirs --outstring=SIZE_scalable_up_to_32_dirs]
+!endif
+!if [del scalable-up-to-32.mak.tmp]
+!endif
+
+# Include the generated NMake Makefile modules to have the full listing of directories, and then get rid of 
them...
+!include 8x8.mak
+!include 16x16.mak
+!include 22x22.mak
+!include 24x24.mak
+!include 32x32.mak
+!include 48x48.mak
+!include 64x64.mak
+!include 96x96.mak
+!include 256x256.mak
+!include scalable.mak
+!include scalable-up-to-32.mak
+
+!if [ for /f %s in ('dir /b /on $(SRCROOTDIR)\Adwaita') do @if not "%s" == "cursors" del %s.mak]
+!endif
+
+FIXED_ICON_DIRS = \
+       $(SIZE_8x8_dirs)        \
+       $(SIZE_16x16_dirs)      \
+       $(SIZE_22x22_dirs)      \
+       $(SIZE_24x24_dirs)      \
+       $(SIZE_32x32_dirs)      \
+       $(SIZE_48x48_dirs)      \
+       $(SIZE_64x64_dirs)      \
+       $(SIZE_96x96_dirs)
+
+CONTEXT_PYTHON_CMD = $(PYTHON) -c "print('Context=' + '%d'['%d'.rfind('/') + 1:].title())"
+SIZE_256 = 256
+SIZE_256_MIN = 56
+SIZE_SCALABLE = 16
+SIZE_SCALABLE_32_MIN = 16
+SIZE_SCALABLE_32_MAX = 32
+SIZE_SCALABLE_MIN = 8
+SIZE_SCALABLE_MAX = 512
+
+all: index.theme
+
+index.theme: index.theme.tmp
+#      From index.theme.tmp, append then to the file the info for each subdir
+#      under each icon size
+#
+#      The fixed-sized icons...
+       @for %d in ($(FIXED_ICON_DIRS)) do              \
+       @(echo [%d])>>$  tmp &                                  \
+       @($(CONTEXT_PYTHON_CMD))>>$  tmp &              \
+       @($(PYTHON) -c "print('Size=' + '%d'[:'%d'.find('x')])")>>$  tmp &      \
+       @(echo Type=Fixed)>>$  tmp &    \
+       @(echo.)>>$  tmp
+
+#      The 256x256 icons...
+       @for %d in ($(SIZE_256x256_dirs))       do              \
+       @(echo [%d]>>$  tmp) &                                          \
+       @($(CONTEXT_PYTHON_CMD))>>$  tmp &                      \
+       @(echo Size=$(SIZE_256))>>$  tmp &                      \
+       @(echo MinSize=$(SIZE_256_MIN))>>$  tmp &       \
+       @(echo MaxSize=$(SIZE_SCALABLE_MAX))>>$  tmp &  \
+       @(echo Type=Scalable)>>$  tmp &                 \
+       @(echo.)>>$  tmp
+
+#      The scalable icons...
+       @for %d in ($(SIZE_scalable_dirs))      do              \
+       @(echo [%d]>>$  tmp) &                                          \
+       @($(CONTEXT_PYTHON_CMD))>>$  tmp &                      \
+       @(echo Size=$(SIZE_SCALABLE))>>$  tmp & \
+       @(echo MinSize=$(SIZE_SCALABLE_MIN))>>$  tmp &  \
+       @(echo MaxSize=$(SIZE_SCALABLE_MAX))>>$  tmp &  \
+       @(echo Type=Scalable)>>$  tmp &                 \
+       @(echo.)>>$  tmp
+
+#      The scalable-up-to-32 icons...
+       @for %d in ($(SIZE_scalable_up_to_32_dirs))     do      \
+       @(echo [%d]>>$  tmp) &                                          \
+       @($(CONTEXT_PYTHON_CMD))>>$  tmp &                      \
+       @(echo Size=$(SIZE_SCALABLE))>>$  tmp & \
+       @(echo MinSize=$(SIZE_SCALABLE_32_MIN))>>$  tmp &       \
+       @(echo MaxSize=$(SIZE_SCALABLE_32_MAX))>>$  tmp &       \
+       @(echo Type=Scalable)>>$  tmp &                 \
+       @(echo.)>>$  tmp
+
+       @$(PYTHON) replace.py -i=$  tmp -o=$  tmp1 --action=replace-str --instring=App --outstring=Application
+       @$(PYTHON) replace.py -i=$  tmp1 -o=$@ --action=replace-str --instring=Mimetype --outstring=MimeType
+       @del $  tmp1
+
+index.theme.tmp: $(SRCROOTDIR)\index.theme.in dir_list.py
+#      First generate a temporary index.theme.tmp that has @THEME_DIRS@ replaced appropriately
+       @echo Generating index.theme...
+       @$(PYTHON) apply_dirs.py -i=$(SRCROOTDIR)\$(@B).in -o=$@
+
+dir_list.py:
+#      Generate a Python list of subdirs under Adwaita/ for the icons
+       @echo icon_dirs = [>$@
+       @for %d in ($(FIXED_ICON_DIRS) $(SIZE_256x256_dirs) $(SIZE_scalable_dirs) 
$(SIZE_scalable_up_to_32_dirs)) do @echo '%d',>>$@
+       @echo ]>>$@
+
+.SUFFIXES: .svg .png
+
+install: index.theme
+       @-mkdir $(PREFIX)\$(ICON_SUBDIR)
+       copy index.theme $(PREFIX)\$(ICON_SUBDIR)
+       for /f %d in ('dir /b $(SRCROOTDIR)\Adwaita') do                                                      
          \
+       @(echo Copying files for %d...) &                                                                     
                          \
+       @(mkdir $(PREFIX)\$(ICON_SUBDIR)\%d) &                                                                
                  \
+       @(if not "%d" == "cursors"                                                                            
                                  \
+               (for /f %f in ('dir /b /on $(SRCROOTDIR)\Adwaita\%d') do                                      
  \
+                (mkdir $(PREFIX)\$(ICON_SUBDIR)\%d\%f) &                                                     
                  \
+                (copy /b $(SRCROOTDIR)\Adwaita\%d\%f\* $(PREFIX)\$(ICON_SUBDIR)\%d\%f))        \
+        else (copy /b $(SRCROOTDIR)\Adwaita\%d\* $(PREFIX)\$(ICON_SUBDIR)\%d))
+       call copy-actual.bat $(PREFIX)
+       $(PREFIX)\bin\gtk-update-icon-cache -q $(PREFIX)\$(ICON_SUBDIR)
+
+clean:
+       @-del index.theme
+       @-del index.theme.tmp
+       @-del dir_list.py
+       @-for %a in (*.pyc) do @del *.pyc
+       @-if exist __pycache__ rmdir /s /q __pycache__
diff --git a/build/win32/apply_dirs.py b/build/win32/apply_dirs.py
new file mode 100644
index 0000000..af8a22e
--- /dev/null
+++ b/build/win32/apply_dirs.py
@@ -0,0 +1,21 @@
+# Script to replace @THEME_DIRS@ with the directories for the icons
+
+import os
+import sys
+import argparse
+
+from replace import replace, check_required_args
+from dir_list import icon_dirs
+
+def main(argv):
+    parser = argparse.ArgumentParser(description='Replace @THEME_DIRS@')
+    parser.add_argument('-i', '--input', help='Input file')
+    parser.add_argument('-o', '--output', help='Output file')
+    args = parser.parse_args()
+
+    check_required_args(args, ['input','output'])
+
+    replace(args.input, args.output, '@THEME_DIRS@', ','.join(icon_dirs) + ',')
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
\ No newline at end of file
diff --git a/build/win32/detectenv-msvc.mak b/build/win32/detectenv-msvc.mak
new file mode 100644
index 0000000..975e11d
--- /dev/null
+++ b/build/win32/detectenv-msvc.mak
@@ -0,0 +1,68 @@
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+!if !defined(VCINSTALLDIR) && !defined(WINDOWSSDKDIR)
+MSG = ^
+This Makefile is only for Visual Studio 2008 and later.^
+You need to ensure that the Visual Studio Environment is properly set up^
+before running this Makefile.
+!error $(MSG)
+!endif
+
+ERRNUL  = 2>NUL
+_HASH=^#
+
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+    && ![echo PLAT=Win32 >> vercl.x] \
+    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+    && ![echo PLAT=x64 >> vercl.x] \
+    && ![echo $(_HASH)endif >> vercl.x] \
+    && ![cl -nologo -TC -P vercl.x $(ERRNUL)]
+!include vercl.i
+!if ![echo VCVER= ^\> vercl.vc] \
+    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!endif
+!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+!if $(VCVERSION) > 1499 && $(VCVERSION) < 1600
+VSVER = 9
+!elseif $(VCVERSION) > 1599 && $(VCVERSION) < 1700
+VSVER = 10
+!elseif $(VCVERSION) > 1699 && $(VCVERSION) < 1800
+VSVER = 11
+!elseif $(VCVERSION) > 1799 && $(VCVERSION) < 1900
+VSVER = 12
+!elseif $(VCVERSION) > 1899 && $(VCVERSION) < 2000
+VSVER = 14
+!else
+VSVER = 0
+!endif
+
+!if "$(VSVER)" == "0"
+MSG = ^
+This NMake Makefile set supports Visual Studio^
+9 (2008) through 14 (2015).  Your Visual Studio^
+version is not supported.  Note that there is no^
+Visual Studio 13.
+!error $(MSG)
+!endif
+
+VALID_CFGSET = FALSE
+!if "$(CFG)" == "release" || "$(CFG)" == "debug"
+VALID_CFGSET = TRUE
+!endif
+
+!if "$(CFG)" == "release"
+CFLAGS_ADD = /MD /O2
+!else
+CFLAGS_ADD = /MDd /Od /Zi
+!endif
+
+!if "$(PLAT)" == "x64"
+LDFLAGS_ARCH = /machine:x64
+!else
+LDFLAGS_ARCH = /machine:x86
+!endif
diff --git a/build/win32/replace.py b/build/win32/replace.py
new file mode 100644
index 0000000..ea75daf
--- /dev/null
+++ b/build/win32/replace.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+#
+# Simple utility script to manipulate
+# certain types of strings in a file
+#
+# Author: Fan, Chun-wei
+# Date: September 03, 2014
+
+import os
+import sys
+import re
+import string
+import argparse
+
+valid_actions = ['remove-prefix',
+                 'replace-var',
+                 'replace-str',
+                 'remove-str']
+
+def replace(src, dest, instring, outstring):
+    with open(src, 'r') as s:
+        with open(dest, 'w') as d:
+            for line in s:
+                i = line.replace(instring, outstring)
+                d.write(i)
+
+def check_required_args(args, params):
+    for param in params:
+        if getattr(args, param, None) is None:
+            raise SystemExit('%s: error: --%s argument is required' % (__file__, param))
+
+def warn_ignored_args(args, params):
+    for param in params:
+        if getattr(args, param, None) is not None:
+            print('%s: warning: --%s argument is ignored' % (__file__, param))
+
+def main(argv):
+
+    parser = argparse.ArgumentParser(description='Process strings in a file.')
+    parser.add_argument('-a',
+                        '--action',
+                        help='Action to carry out.  Can be one of:\n'
+                             'remove-prefix\n'
+                             'replace-var\n'
+                             'replace-str\n'
+                             'remove-str',
+                        choices=valid_actions)
+    parser.add_argument('-i', '--input', help='Input file')
+    parser.add_argument('-o', '--output', help='Output file')
+    parser.add_argument('--instring', help='String to replace or remove')
+    parser.add_argument('--var', help='Autotools variable name to replace')
+    parser.add_argument('--outstring',
+                        help='New String to replace specified string or variable')
+    parser.add_argument('--removeprefix', help='Prefix of string to remove')
+
+    args = parser.parse_args()
+
+    input_string = ''
+    output_string = ''
+
+    # We must have action, input, output for all operations
+    check_required_args(args, ['action','input','output'])
+
+    # Build the arguments by the operation that is to be done,
+    # to be fed into replace()
+
+    # Get rid of prefixes from a string
+    if args.action == 'remove-prefix':
+        check_required_args(args, ['instring','removeprefix'])
+        warn_ignored_args(args, ['outstring','var'])
+        input_string = args.removeprefix + args.instring
+        output_string = args.instring
+
+    # Replace an m4-style variable (those surrounded by @...@)
+    if args.action == 'replace-var':
+        check_required_args(args, ['var','outstring'])
+        warn_ignored_args(args, ['instring','removeprefix'])
+        input_string = '@' + args.var + '@'
+        output_string = args.outstring
+
+    # Replace a string
+    if args.action == 'replace-str':
+        check_required_args(args, ['instring','outstring'])
+        warn_ignored_args(args, ['var','removeprefix'])
+        input_string = args.instring
+        output_string = args.outstring
+
+    # Remove a string
+    if args.action == 'remove-str':
+        check_required_args(args, ['instring'])
+        warn_ignored_args(args, ['var','outstring','removeprefix'])
+        input_string = args.instring
+        output_string = ''
+
+    replace(args.input, args.output, input_string, output_string)
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/configure.ac b/configure.ac
index 76c8905..359311f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -84,6 +84,8 @@ src/Makefile
 src/fullcolor/Makefile
 src/symbolic/Makefile
 src/spinner/Makefile
+build/Makefile
+build/win32/Makefile
 ])
 
 AC_OUTPUT


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]