From 5063385d16deae5f63e7f1c062e4d31f9a6d8502 Mon Sep 17 00:00:00 2001
From: stil
Date: Sun, 5 Feb 2017 07:07:05 +0100
Subject: [PATCH] AppVeyor integration (#25)
* Fix minor bugs and improve code formatting of Python build tool
* Prepend $PATH to give it higher priority
* Invoke WiX tools through variable to ensure correct path
* Make build script ensure pacman dependencies are installed
* pacman -Sy causes dependency break on AppVeyor
* Skip deps version check and don't show progress bar
---
NuGet/build.py | 38 +++++++------
NuGet/pybuild/Helper.py | 71 +++++++++++++++++--------
NuGet/pybuild/ProfileBase.py | 15 +++---
NuGet/pybuild/profiles/Glue_Win32.py | 17 +++---
NuGet/pybuild/profiles/Glue_Win64.py | 3 +-
NuGet/pybuild/profiles/GtkSharp.py | 13 ++---
NuGet/pybuild/profiles/GtkSharp_Core.py | 26 ++++-----
NuGet/pybuild/profiles/Gtk_Win32.py | 19 +++----
NuGet/pybuild/profiles/Gtk_Win64.py | 7 ++-
NuGet/pybuild/vsgenext/CoreVSProject.py | 28 +++++-----
configure.ac | 5 +-
msi/Makefile.am | 4 +-
msi/unmanaged/Makefile.am | 4 +-
13 files changed, 145 insertions(+), 105 deletions(-)
diff --git a/NuGet/build.py b/NuGet/build.py
index 3ba9363bb..99b2f7055 100644
--- a/NuGet/build.py
+++ b/NuGet/build.py
@@ -1,12 +1,14 @@
#!/usr/bin/python3
"""Script to build out the .Net dll's and package them into a Nuget Package for gtksharp3"""
-import os, sys
+import sys
from pybuild.profiles.GtkSharp import GtkSharp
from pybuild.profiles.GtkSharp_Core import GtkSharp_Core
from pybuild.profiles.Glue_Win32 import Glue_Win32
from pybuild.profiles.Glue_Win64 import Glue_Win64
from pybuild.profiles.Gtk_Win32 import Gtk_Win32
from pybuild.profiles.Gtk_Win64 import Gtk_Win64
+from pybuild.Helper import Helper
+
# Ideally I'd like to see the GtkSharp Build system redone via the build system of .Net core (dotnet cli tool)
# and using Scons / Cuppa for the glue libraries
@@ -14,24 +16,25 @@ from pybuild.profiles.Gtk_Win64 import Gtk_Win64
# under linux we run this natively, under windows we can use MSYS2
class Build(object):
-
# Clean the Build directory
- def clean(self):
+ @staticmethod
+ def clean():
"""Clean the build dir"""
- helpers.emptydir('./build')
- print ("Clean finished")
+ Helper.emptydir('./build')
+ print("Clean finished")
# Print Usage
- def usage(self):
- print ("Please use GtkSharp3_Build.py where is one of")
- print (" clean to clean the output directory: ./build")
+ @staticmethod
+ def usage():
+ print("Please use GtkSharp3_Build.py where is one of")
+ print(" clean to clean the output directory: ./build")
- print (" gtksharp to build .Net libs for GtkSharp, via .Net 4.5")
- print (" gtksharp_core to build .Net libs for GtkSharp, via .Net 4.5 using the dotnet cli tool")
+ print(" gtksharp to build .Net libs for GtkSharp, via .Net 4.5")
+ print(" gtksharp_core to build .Net libs for GtkSharp, via .Net 4.5 using the dotnet cli tool")
- print (" gtk_win32 to build the Nuget package for GtkSharp.Win32")
- print (" gtk_win64 to build the Nuget package for GtkSharp.Win64")
- print (" all to make all")
+ print(" gtk_win32 to build the Nuget package for GtkSharp.Win32")
+ print(" gtk_win64 to build the Nuget package for GtkSharp.Win64")
+ print(" all to make all")
def main(self):
if len(sys.argv) != 2:
@@ -46,13 +49,15 @@ class Build(object):
self.runbuild(sys.argv[1])
-
def runbuild(self, build_type):
-
+
if build_type == 'clean':
self.clean()
+ return
- elif build_type == 'gtksharp':
+ Helper.install_pacman_deps()
+
+ if build_type == 'gtksharp':
profile = GtkSharp()
profile.clean()
profile.build()
@@ -82,5 +87,6 @@ class Build(object):
profile.build()
profile.build_nuget()
+
if __name__ == "__main__":
Build().main()
diff --git a/NuGet/pybuild/Helper.py b/NuGet/pybuild/Helper.py
index f54e51e85..fa4d69203 100644
--- a/NuGet/pybuild/Helper.py
+++ b/NuGet/pybuild/Helper.py
@@ -1,17 +1,18 @@
#!/usr/bin/python3
"""Helper Functions"""
-import os, subprocess, shutil, sys
+import os
from os.path import join
-from glob import iglob
+
from executor import ExternalCommand
-import ntpath
+
class Helper(object):
-
+ @staticmethod
def emptydir(top):
"""Empty a Directory"""
- if(top == '/' or top == "\\"): return
+ if top == '/' or top == "\\":
+ return
else:
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
@@ -19,44 +20,70 @@ class Helper(object):
for name in dirs:
os.rmdir(os.path.join(root, name))
- def run_cmd(cmdarray, workdir, comms = None):
- """Run a command on the shell"""
+ @staticmethod
+ def run_cmd(cmdarray, workdir):
+ """Run a command on the shell"""
cmd = ExternalCommand(*cmdarray, capture=True, capture_stderr=True, async=True, shell=False, directory=workdir)
cmd.start()
last_out = ''
last_err = ''
while cmd.is_running:
- new_out = cmd.decoded_stdout.replace(last_out, '')
- new_err = cmd.decoded_stderr.replace(last_err, '')
+ new_out = cmd.stdout.decode(cmd.encoding, 'ignore').replace(last_out, '')
+ new_err = cmd.stderr.decode(cmd.encoding, 'ignore').replace(last_err, '')
+
last_out += new_out
last_err += new_err
new_out = new_out.replace(u"\u2018", "'").replace(u"\u2019", "'")
new_err = new_err.replace(u"\u2018", "'").replace(u"\u2019", "'")
- if new_out != '': print(new_out, end='')
- if new_err != '': print(new_err, end='')
+ if new_out != '':
+ print(new_out, end='')
+ if new_err != '':
+ print(new_err, end='')
if cmd.returncode != 0:
raise RuntimeError('Failure to run command')
return cmd
+ @staticmethod
def winpath_to_msyspath(winpath):
"""Convert a Windows path to a Msys type path"""
winpath = '/' + winpath[0] + winpath[2:].replace('\\', '/')
return winpath
+ @staticmethod
def get_gtksharp_version(srcdir):
- """Get the Version of GTK Sharp in use from the source directory"""
- ret = None
- with open(join(srcdir, 'configure.ac')) as f:
- for line in f:
- if line.startswith('AC_INIT'):
- ret = line
- ret = ret.replace('AC_INIT(gtk-sharp,', '')
- ret = ret.replace(' ', '')
- ret = ret.replace(')\n', '')
- break
- return ret
+ """Get the Version of GTK Sharp in use from the source directory"""
+ ret = None
+ with open(join(srcdir, 'configure.ac')) as f:
+ for line in f:
+ if line.startswith('AC_INIT'):
+ ret = line
+ ret = ret.replace('AC_INIT(gtk-sharp,', '')
+ ret = ret.replace(' ', '')
+ ret = ret.replace(')\n', '')
+ break
+ return ret
+ @staticmethod
+ def install_pacman_deps():
+ Helper.run_pacman_cmd(['-Sy'])
+
+ args = ['--needed', '--nodeps', '--noprogressbar', '--noconfirm', '-S']
+ args += 'unzip autoconf automake libtool pkg-config make'.split(' ')
+
+ deps_arch = 'gcc glib2 pango atk gtk3 zlib libiconv'
+ args += ['mingw-w64-i686-{0}'.format(i) for i in deps_arch.split(' ')]
+ args += ['mingw-w64-x86_64-{0}'.format(i) for i in deps_arch.split(' ')]
+
+ Helper.run_pacman_cmd(args)
+
+ @staticmethod
+ def run_pacman_cmd(pacman_args):
+ msyspath = 'C:\\msys64'
+ pacman_path = join(msyspath, 'usr\\bin\\pacman.exe')
+ return Helper.run_cmd([pacman_path] + pacman_args, msyspath)
+
+ @staticmethod
def get_gtk_version_msys(msyspath):
ret = ''
pacman_path = join(msyspath, 'usr\\bin\\pacman.exe')
diff --git a/NuGet/pybuild/ProfileBase.py b/NuGet/pybuild/ProfileBase.py
index 317f3c062..cb64d8cb5 100644
--- a/NuGet/pybuild/ProfileBase.py
+++ b/NuGet/pybuild/ProfileBase.py
@@ -1,13 +1,15 @@
#!/usr/bin/python3
"""Base class for Settings profiles"""
-import os, shutil
+import os
+import shutil
from os.path import abspath, join
from xml.etree import ElementTree as et
+
from pybuild.Helper import Helper
-class ProfileBase(object):
+class ProfileBase(object):
def __init__(self):
"""Class Init"""
self._NuGetPath = 'nuget.exe'
@@ -55,12 +57,11 @@ class ProfileBase(object):
def Version(self):
return self._Version
-
- def clean(self):
+ @staticmethod
+ def clean():
"""Clean the build dir"""
Helper.emptydir('./build')
- print ("Clean finished")
-
+ print("Clean finished")
def build_nuget(self):
"""Package up a nuget file based on the default build"""
@@ -84,4 +85,4 @@ class ProfileBase(object):
nugetfile = join(self.Build_NugetDir, self.NuGet_PackageName + '.' + self.Version + '.nupkg')
os.makedirs(self.PackageDestination, exist_ok=True)
shutil.copy(nugetfile, self.PackageDestination)
- print ('Generation of Nuget package complete - ' + self.NuGet_PackageName)
+ print('Generation of Nuget package complete - ' + self.NuGet_PackageName)
diff --git a/NuGet/pybuild/profiles/Glue_Win32.py b/NuGet/pybuild/profiles/Glue_Win32.py
index 5fa72f141..86117a4d3 100644
--- a/NuGet/pybuild/profiles/Glue_Win32.py
+++ b/NuGet/pybuild/profiles/Glue_Win32.py
@@ -1,14 +1,17 @@
#!/usr/bin/python3
-import os, shutil, ntpath
-from pybuild.ProfileBase import ProfileBase
-from os.path import abspath, join
+import ntpath
+import os
+import shutil
from glob import glob
+from os.path import abspath, join
+
from pybuild.Helper import Helper
+from pybuild.ProfileBase import ProfileBase
from pybuild.profiles.GtkSharp import GtkSharp
-class Glue_Win32(ProfileBase):
+class Glue_Win32(ProfileBase):
def __init__(self):
"""Class Init"""
super().__init__()
@@ -30,8 +33,8 @@ class Glue_Win32(ProfileBase):
"""Package up a nuget file based on the default build"""
if os.name != 'nt':
- print("Skipping Native Nuget package build, as this needs to be run on Windows")
- return
+ print("Skipping Native Nuget package build, as this needs to be run on Windows")
+ return
# Trigger build of gtksharp with specific bash for Mingw32
builder = GtkSharp()
@@ -41,7 +44,7 @@ class Glue_Win32(ProfileBase):
net45_build_dir = join(self.Build_NugetDir, 'build', 'net45')
os.makedirs(net45_build_dir, exist_ok=True)
- print ('Copying Files')
+ print('Copying Files')
dll_list = self.Get_Dlls_GtkSharp_Glue()
for item in dll_list:
diff --git a/NuGet/pybuild/profiles/Glue_Win64.py b/NuGet/pybuild/profiles/Glue_Win64.py
index 74938ac9f..60f741fa9 100644
--- a/NuGet/pybuild/profiles/Glue_Win64.py
+++ b/NuGet/pybuild/profiles/Glue_Win64.py
@@ -1,11 +1,10 @@
#!/usr/bin/python3
-from pybuild.ProfileBase import ProfileBase
from pybuild.Helper import Helper
from pybuild.profiles.Glue_Win32 import Glue_Win32
-class Glue_Win64(Glue_Win32):
+class Glue_Win64(Glue_Win32):
def __init__(self):
"""Class Init"""
super().__init__()
diff --git a/NuGet/pybuild/profiles/GtkSharp.py b/NuGet/pybuild/profiles/GtkSharp.py
index f1a193e75..87c121afb 100644
--- a/NuGet/pybuild/profiles/GtkSharp.py
+++ b/NuGet/pybuild/profiles/GtkSharp.py
@@ -1,11 +1,13 @@
#!/usr/bin/python3
-import os, shutil
-from pybuild.ProfileBase import ProfileBase
+import os
+import shutil
from os.path import abspath, join
+
from pybuild.Helper import Helper
+from pybuild.ProfileBase import ProfileBase
+
class GtkSharp(ProfileBase):
-
def __init__(self):
"""Class Init"""
super().__init__()
@@ -27,8 +29,8 @@ class GtkSharp(ProfileBase):
if os.name == 'nt':
print("Building .Net GtkSharp using MSYS2")
with open(buildfile, 'w') as f:
- f.write('PATH=$PATH:/c/Program\ Files\ \(x86\)/Microsoft\ SDKs/Windows/v10.0A/bin/NETFX\ 4.6\ Tools/\n')
- f.write('PATH=$PATH:/c/Windows/Microsoft.NET/Framework/v4.0.30319/\n')
+ f.write('PATH=/c/Program\ Files\ \(x86\)/Microsoft\ SDKs/Windows/v10.0A/bin/NETFX\ 4.6\ Tools/:$PATH\n')
+ f.write('PATH=/c/Windows/Microsoft.NET/Framework/v4.0.30319/:$PATH\n')
f.write('cd ' + Helper.winpath_to_msyspath(self.SrcDir + '\n'))
f.write('./autogen.sh --prefix=/tmp/install\n')
f.write('make clean\n')
@@ -53,7 +55,6 @@ class GtkSharp(ProfileBase):
cmds = [self.LinuxBashPath, buildfile]
cmd = Helper.run_cmd(cmds, self.SrcDir)
-
def copy(self):
"""Copy the .Net 4.5 dll's to the build dir"""
diff --git a/NuGet/pybuild/profiles/GtkSharp_Core.py b/NuGet/pybuild/profiles/GtkSharp_Core.py
index 078f376e1..18640ecf7 100644
--- a/NuGet/pybuild/profiles/GtkSharp_Core.py
+++ b/NuGet/pybuild/profiles/GtkSharp_Core.py
@@ -1,11 +1,15 @@
#!/usr/bin/python3
-import os, shutil
+import os
+import shutil
+from glob import glob
+from os.path import abspath, join
+
+import vsgen
+
+from pybuild.Helper import Helper
from pybuild.ProfileBase import ProfileBase
from pybuild.vsgenext.CoreVSProject import CoreVSProject
-from os.path import abspath, join
-from pybuild.Helper import Helper
-from glob import glob
-import vsgen
+
# Note at this stage we can't complile GtkSharp using the .Net Core platform libraries, such as netstandard1.6
# https://docs.microsoft.com/en-us/dotnet/articles/standard/library
@@ -19,7 +23,6 @@ import vsgen
# TODO look into package for symbols, via NuGet -symbols
class GtkSharp_Core(ProfileBase):
-
def __init__(self):
"""Class Init"""
super().__init__()
@@ -36,7 +39,6 @@ class GtkSharp_Core(ProfileBase):
def Dotnet_BuildExe(self):
return 'dotnet.exe'
-
def Copy_CS_Files(self, csfiles):
srclist = glob(join(self.SrcDir, csfiles[0]))
destdir = join(self.Build_CoreDir, csfiles[1])
@@ -47,11 +49,11 @@ class GtkSharp_Core(ProfileBase):
def SetupProject(self, projname):
proj = CoreVSProject()
proj.Name = projname
- proj.RootNamespace=projname
+ proj.RootNamespace = projname
proj.FileName = join(self.Build_CoreDir, projname, projname + '.xproj')
proj.Frameworks = {'net461': {}}
proj.Depends = {}
- proj.BuildOptions = { "allowUnsafe": True , "outputName": projname + "-sharp"}
+ proj.BuildOptions = {"allowUnsafe": True, "outputName": projname + "-sharp"}
proj.Version = self._Version
self.Solution.Projects.append(proj)
self.Solution.write()
@@ -64,8 +66,7 @@ class GtkSharp_Core(ProfileBase):
'--configuration', self.BuildConfig,
'--framework', 'net461',
'--output', join(self.Build_CoreDir, 'build')]
- , projdir)
-
+ , projdir)
def build(self):
"""Build the gtksharp binaries for .Net 4.5"""
@@ -133,7 +134,6 @@ class GtkSharp_Core(ProfileBase):
proj.write()
self.Build_Project(proj)
-
def copy_dll(self):
"""Copy the .Net 4.5 dll's to the build dir"""
@@ -152,4 +152,4 @@ class GtkSharp_Core(ProfileBase):
dll_list = ['atk', 'cairo', 'gdk', 'gio', 'glib', 'gtk', 'pango']
for item in dll_list:
if item != 'cairo':
- shutil.copy(join(self.SrcDir, item, item + '-sharp.dll.config'), net45_build_dir)
\ No newline at end of file
+ shutil.copy(join(self.SrcDir, item, item + '-sharp.dll.config'), net45_build_dir)
diff --git a/NuGet/pybuild/profiles/Gtk_Win32.py b/NuGet/pybuild/profiles/Gtk_Win32.py
index 0c4fb1fad..311fb87a2 100644
--- a/NuGet/pybuild/profiles/Gtk_Win32.py
+++ b/NuGet/pybuild/profiles/Gtk_Win32.py
@@ -1,14 +1,17 @@
#!/usr/bin/python3
"""Build of GTK3 into a NuGet package - Windows 32bit"""
-import os, shutil, ntpath
-from pybuild.ProfileBase import ProfileBase
-from os.path import abspath, join
+import ntpath
+import os
+import shutil
from glob import iglob
+from os.path import abspath, join
+
from pybuild.Helper import Helper
+from pybuild.ProfileBase import ProfileBase
+
class Gtk_Win32(ProfileBase):
-
def __init__(self):
"""Class Init"""
super().__init__()
@@ -21,7 +24,6 @@ class Gtk_Win32(ProfileBase):
def MingwBinPath(self):
return abspath(self._MingwBinPath)
-
def Get_Dlls_Native_GTK(self):
ret = []
@@ -74,18 +76,17 @@ class Gtk_Win32(ProfileBase):
ret.append('libbz2-1.dll')
return ret
-
def build(self):
"""Package up a nuget file based on the default build"""
if os.name != 'nt':
- print("Skipping Native Nuget package build, as this needs to be run on Windows")
- return
+ print("Skipping Native Nuget package build, as this needs to be run on Windows")
+ return
net45_build_dir = join(self.Build_NugetDir, 'build', 'net45')
os.makedirs(net45_build_dir, exist_ok=True)
- print ('Copying Files')
+ print('Copying Files')
shutil.copy('./misc/GtkSharp.Native.targets', join(net45_build_dir, 'GtkSharp.' + self.arch + '.targets'))
# Copy dlls
diff --git a/NuGet/pybuild/profiles/Gtk_Win64.py b/NuGet/pybuild/profiles/Gtk_Win64.py
index 998fc8252..97e8fe839 100644
--- a/NuGet/pybuild/profiles/Gtk_Win64.py
+++ b/NuGet/pybuild/profiles/Gtk_Win64.py
@@ -1,14 +1,13 @@
#!/usr/bin/python3
"""Build of GTK3 into a NuGet package - Windows 64bit"""
-import os, shutil
-from pybuild.ProfileBase import ProfileBase
-from os.path import abspath, join
+from os.path import join
+
from pybuild.Helper import Helper
from pybuild.profiles.Gtk_Win32 import Gtk_Win32
-class Gtk_Win64(Gtk_Win32):
+class Gtk_Win64(Gtk_Win32):
def __init__(self):
"""Class Init"""
super().__init__()
diff --git a/NuGet/pybuild/vsgenext/CoreVSProject.py b/NuGet/pybuild/vsgenext/CoreVSProject.py
index 520c0f763..79dcca987 100644
--- a/NuGet/pybuild/vsgenext/CoreVSProject.py
+++ b/NuGet/pybuild/vsgenext/CoreVSProject.py
@@ -1,11 +1,14 @@
#!/usr/bin/python3
-import os, json
-from vsgen.project import VSGProject
-from xml.etree import ElementTree as et
-from yattag import indent
-from os.path import abspath, join
+import json
+import os
from collections import OrderedDict
+from os.path import join
+from xml.etree import ElementTree as et
+
+from vsgen.project import VSGProject
+from yattag import indent
+
class CoreVSProject(VSGProject):
"""
@@ -51,18 +54,18 @@ class CoreVSProject(VSGProject):
data = OrderedDict()
ver = {'version': self.Version}
data.update(ver)
-
+
depends = self.Depends
depends2 = {'dependencies': depends}
data.update(depends2)
-
- if self.Frameworks != None:
+
+ if self.Frameworks is not None:
frameworks = {'frameworks': self.Frameworks}
else:
frameworks = {'frameworks': {'netstandard1.6': {'imports': 'dnxcore50'}}}
data.update(frameworks)
- if self.BuildOptions != None:
+ if self.BuildOptions is not None:
buildopts = {'buildOptions': self.BuildOptions}
data.update(buildopts)
@@ -112,8 +115,7 @@ class CoreVSProject(VSGProject):
etstr = et.tostring(xml_projroot, encoding='utf-8', method='xml').decode('utf-8')
outtxt = indent(etstr)
- return outtxt
-
+ return outtxt
def write(self):
"""
@@ -125,7 +127,7 @@ class CoreVSProject(VSGProject):
projectFileName = os.path.normpath(self.FileName)
projxml = ''
- if self.ProjectXml == None:
+ if self.ProjectXml is None:
projxml = self.get_project_xml()
else:
projxml = self.ProjectXml
@@ -134,7 +136,7 @@ class CoreVSProject(VSGProject):
jsonFileName = join(filepath, 'project.json')
- if self.ProjectJson == None:
+ if self.ProjectJson is None:
projjson = self.get_project_json()
else:
projjson = self.ProjectJson
diff --git a/configure.ac b/configure.ac
index d58243133..eb8162efd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -89,8 +89,9 @@ fi
enable_msi="no"
if test "x$platform_win32" = "xyes"; then
- AC_PATH_PROG(WIX, candle, no)
- if test "x$WIX" != "xno" ; then
+ AC_PATH_PROG(WIX_CANDLE, candle, no)
+ AC_PATH_PROG(WIX_LIGHT, light, no)
+ if test "x$WIX_CANDLE" != "xno" -a "x$WIX_LIGHT" != "xno" ; then
enable_msi="yes"
fi
fi
diff --git a/msi/Makefile.am b/msi/Makefile.am
index bceda3229..11e80b622 100644
--- a/msi/Makefile.am
+++ b/msi/Makefile.am
@@ -26,5 +26,5 @@ gtk-sharp-3.0.msi: gtk-sharp-3.0.wxs
mv binaries/libpangosharpglue-3.dll binaries/pangosharpglue-3.dll
cp $(top_builddir)/sample/GtkDemo/GtkDemo.exe binaries
- candle -ext WixUIExtension gtk-sharp-3.0.wxs
- light -cultures:en-us -ext WixUIExtension -ext WixNetFxExtension -out gtk-sharp-$(VERSION).msi gtk-sharp-3.0.wixobj
+ $(WIX_CANDLE) -ext WixUIExtension gtk-sharp-3.0.wxs
+ $(WIX_LIGHT) -cultures:en-us -ext WixUIExtension -ext WixNetFxExtension -out gtk-sharp-$(VERSION).msi gtk-sharp-3.0.wixobj
diff --git a/msi/unmanaged/Makefile.am b/msi/unmanaged/Makefile.am
index 6afe677d9..433a97e5e 100644
--- a/msi/unmanaged/Makefile.am
+++ b/msi/unmanaged/Makefile.am
@@ -15,10 +15,10 @@ download-stamp: $(DOWNLOADS)
touch download-stamp
unmanaged.wixobj: unmanaged.wxs redirector.exe download-stamp
- candle unmanaged.wxs
+ $(WIX_CANDLE) unmanaged.wxs
unmanaged.msm: unmanaged.wixobj
- light unmanaged.wixobj
+ $(WIX_LIGHT) unmanaged.wixobj
bundle-scanner.exe: bundle-scanner.cs
$(CSC) bundle-scanner.cs