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
This commit is contained in:
stil 2017-02-05 07:07:05 +01:00 committed by MIkkel Kruse Johnsen
parent af3956b2dd
commit 5063385d16
13 changed files with 145 additions and 105 deletions

View file

@ -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 <target> where <target> is one of")
print (" clean to clean the output directory: ./build")
@staticmethod
def usage():
print("Please use GtkSharp3_Build.py <target> where <target> 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()

View file

@ -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')

View file

@ -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)

View file

@ -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:

View file

@ -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__()

View file

@ -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"""

View file

@ -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)
shutil.copy(join(self.SrcDir, item, item + '-sharp.dll.config'), net45_build_dir)

View file

@ -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

View file

@ -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__()

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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