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



commit e2f54856106ab1deeff0c2decb7bafdae9009188
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.

 Makefile.am                    |    2 +-
 build/Makefile.am              |    1 +
 build/win32/Makefile.am        |    6 ++
 build/win32/README.txt         |   65 +++++++++++++++
 build/win32/adwaita-msvc.mak   |  174 ++++++++++++++++++++++++++++++++++++++++
 build/win32/apply_dirs.py      |   21 +++++
 build/win32/detectenv-msvc.mak |   68 ++++++++++++++++
 build/win32/replace.py         |   98 ++++++++++++++++++++++
 configure.ac                   |    2 +
 9 files changed, 436 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..990d1d1
--- /dev/null
+++ b/build/win32/Makefile.am
@@ -0,0 +1,6 @@
+EXTRA_DIST =   \
+       adwaita-msvc.mak        \
+       apply_dirs.py           \
+       detectenv-msvc.mak      \
+       README.txt              \
+       replace.py
diff --git a/build/win32/README.txt b/build/win32/README.txt
new file mode 100644
index 0000000..6a26cf7
--- /dev/null
+++ b/build/win32/README.txt
@@ -0,0 +1,65 @@
+As some file decompression utilities have problems resolving UNIX symlink files,
+please check whether there are any 0-size files in Adwaita/scalable and/or
+Adwaita/cursors.  If there are, there is a good chance that you are affected by
+this problem.  Delete the whole folder tree and try again, note that the following
+utilities are known to work correctly:
+- Latest stable version of 7-zip (version 15.14 at time of writing)
+- Using the latest tar/xz as provided by MSYS2, by calling 'tar -Jxvh'.
+
+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 adwaita-msvc.mak is an NMake Makefile that is meant to be used to generate
+the index.theme file that is needed for installation of this icon theme
+package, as well as copying and processing the icon files so that they
+will be ready for use for GTK+ applications.
+
+The required dependencies are as follows:
+
+-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 optimal results, you will also need:
+-The gtk-update-icon-cache tool, which can be found by building the latest GTK+
+ 2.24+/3.18+ package.  If Visual Studio projects were not provided to build it,
+ one can still build it manually after building GTK+ itself by running in
+ $(GTK_srcroot)\gtk, $(PREFIX) is the prefix where the other parts of the GTK+
+ stack reside:
+ 'cl /MD /O2 /W3 /GL /FImsvc_recommended_pragmas.h /I.. /I$(PREFIX)\include\gdk-pixbuf-2.0 
/I$(PREFIX)\include\glib-2.0 /I$(PREFIX)\lib\glib-2.0\include /I$(PREFIX)\include updateiconcache.c /link 
/libpath:$(PREFIX)\lib gdk_pixbuf-2.0.lib gio-2.0.lib gobject-2.0.lib glib-2.0.lib intl.lib /DEBUG 
/out:gtk-update-icon-cache.exe /LTCG /opt:ref'
+ (Embed the generated .exe.manifest or copy it if on Visual Studio 2008 using
+  mt.exe)
+ The tool should be placed in $(PREFIX)\bin.
+
+-PNG versions of the SVG symbolic icons are generated in 16x16, 24x24, 32x32,
+ 48x48, 64x64 and 96x96 sizes if the gtk-encode-symbolic-svg tool is found in
+ $(PREFIX)\bin, and the SVG GDK-Pixbuf loader is properly installed, which is
+ obtained by building GDK-Pixbuf and libRSVG.  The PNG versions of the symbolic
+ icons are necessary if your app is a GTK-3.x app and you are not intending to
+ ship the SVG GDK-Pixbuf loader nor the libRSVG DLL (which are both required
+ otherwise).
+
+Run 'nmake /f adwaita-msvc.mak' to generate the needed index.theme file.
+PYTHON=xxx can be specified on the command line if your Python interpretor is
+not in your PATH.  Run 'nmake /f adwaita-msvc.mak install' to copy the
+generated index.theme, as well as all the icon and cursor files into
+$(PREFIX)\share\icons, and process them if the optional tools are found, so
+that the icons will be ready for use by GTK+-using applications.
+A 'clean' target is provided to remove all the generated files-to uninstall
+the installed icons, simply delete the $(PREFIX)\share\icons\Adwaita folder.
+
+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-adwaita-icon-theme-source-tree>
+<root>\<Visual Studio Version>\<PlatformName>
+
+*this* file you are now reading is thus located at
+<root>\<this-adwaita-icon-theme-source-tree>\build\README.txt
+
+--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..90b789d
--- /dev/null
+++ b/build/win32/adwaita-msvc.mak
@@ -0,0 +1,174 @@
+# 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
+GDK_PIXBUF_MOD_VERSION=2.10.0
+
+# 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
+
+# Copy the icon and cursor files, and convert the SVG symbolic icons if:
+# -The gtk-encode-symbolic-svg tool is found in $(PREFIX)\bin -AND-
+# -The SVG GDK-Pixbuf loader can be found in $(PREFIX)\lib\gdk-pixbuf-2.0\2.10.0\loaders
+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))
+       @if exist $(PREFIX)\bin\gtk-encode-symbolic-svg.exe                                                   
          \
+       if exist $(PREFIX)\lib\gdk-pixbuf-2.0\$(GDK_PIXBUF_MOD_VERSION)\loaders\libpixbufloader-svg.dll       
          \
+       if exist $(PREFIX)\lib\gdk-pixbuf-2.0\$(GDK_PIXBUF_MOD_VERSION)\loaders.cache                         
          \
+               @(echo Converting symbolic SVG icons to PNG...) &                                             
          \
+               @(for %z in (16x16 24x24 32x32 48x48 64x64 96x96) do                                          
          \
+                       @(echo Converting symbolic SVG icons to %z PNG...) &                                  
          \
+                       @(for /f %d in ('dir /b /on $(SRCROOTDIR)\Adwaita\scalable') do                       
          \
+                               @(for /f %f in ('dir /b /on $(SRCROOTDIR)\Adwaita\scalable\%d') do            
          \
+                                       @($(PREFIX)\bin\gtk-encode-symbolic-svg 
$(SRCROOTDIR)\Adwaita\scalable\%d\%f    \
+                                        %z -o $(PREFIX)\$(ICON_SUBDIR)\%z\%d))))
+       @if exist $(PREFIX)\bin\gtk-update-icon-cache.exe                                                     
          \
+       @(echo Update icon cache...) &                                                                        
          \
+       @($(PREFIX)\bin\gtk-update-icon-cache -q $(PREFIX)\$(ICON_SUBDIR))
+       @echo Adwaita icon theme install complete.
+
+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]