Added some code for trying out the build of Gtksharp using dotnet cli from .Net core

This commit is contained in:
grbd 2016-10-17 20:09:26 +01:00
parent c45e3558b6
commit 9c00e25617
8 changed files with 331 additions and 16 deletions

View file

@ -25,7 +25,7 @@ pacman -S mingw-w64-x86_64-pango mingw-w64-x86_64-atk mingw-w64-x86_64-gtk3
And installed the executor python module And installed the executor python module
``` ```
C:\Python35\Scripts\pip.exe install executor C:\Python35\Scripts\pip.exe install executor yattag vsgen
``` ```
### Running Build ### Running Build
@ -48,7 +48,7 @@ sudo apt-get install libglib2.0-dev libpango1.0-dev libatk1.0-dev libgtk-3-dev
Then install the executor python module Then install the executor python module
``` ```
pip3 install executor pip3 install executor yattag vsgen
``` ```
The version of Nuget needs to be the latest for linux The version of Nuget needs to be the latest for linux

View file

@ -2,12 +2,14 @@
"""Script to build out the .Net dll's and package them into a Nuget Package for gtksharp3""" """Script to build out the .Net dll's and package them into a Nuget Package for gtksharp3"""
import os, sys import os, sys
from pybuild.profiles.GtkSharp import GtkSharp 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_Win32 import Glue_Win32
from pybuild.profiles.Glue_Win64 import Glue_Win64 from pybuild.profiles.Glue_Win64 import Glue_Win64
from pybuild.profiles.Gtk_Win32 import Gtk_Win32 from pybuild.profiles.Gtk_Win32 import Gtk_Win32
from pybuild.profiles.Gtk_Win64 import Gtk_Win64 from pybuild.profiles.Gtk_Win64 import Gtk_Win64
# Ideally I'd like to see the GtkSharp Build system redone via .Net Core or something other than make # 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
# For now though we rely on the use of make to build the .Net dll's # For now though we rely on the use of make to build the .Net dll's
# under linux we run this natively, under windows we can use MSYS2 # under linux we run this natively, under windows we can use MSYS2
@ -24,9 +26,8 @@ class Build(object):
print ("Please use GtkSharp3_Build.py <target> where <target> is one of") print ("Please use GtkSharp3_Build.py <target> where <target> is one of")
print (" clean to clean the output directory: ./build") print (" clean to clean the output directory: ./build")
# print (" gtksharp_all to build .Net libs for GtkSharp, via .Net 4.5 and .Net Core") print (" gtksharp to build .Net libs for GtkSharp, via .Net 4.5")
print (" gtksharp_net45 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_core to build .Net libs for GtkSharp, via .Net Core")
print (" gtk_win32 to build the Nuget package for GtkSharp.Win32") print (" gtk_win32 to build the Nuget package for GtkSharp.Win32")
print (" gtk_win64 to build the Nuget package for GtkSharp.Win64") print (" gtk_win64 to build the Nuget package for GtkSharp.Win64")
@ -38,7 +39,7 @@ class Build(object):
return return
if sys.argv[1] == 'all': if sys.argv[1] == 'all':
self.runbuild('gtksharp_net45') self.runbuild('gtksharp')
self.runbuild('gtk_win32') self.runbuild('gtk_win32')
self.runbuild('gtk_win64') self.runbuild('gtk_win64')
return return
@ -51,11 +52,18 @@ class Build(object):
if build_type == 'clean': if build_type == 'clean':
self.clean() self.clean()
elif build_type == 'gtksharp_net45': elif build_type == 'gtksharp':
profile = GtkSharp() profile = GtkSharp()
profile.clean() profile.clean()
profile.build_net45() profile.build()
profile.copy_net45() profile.copy()
profile.build_nuget()
elif build_type == 'gtksharp_core':
profile = GtkSharp_Core()
profile.clean()
profile.build()
profile.copy_dll()
profile.build_nuget() profile.build_nuget()
elif build_type == 'gtk_win32': elif build_type == 'gtk_win32':

View file

@ -36,7 +36,7 @@ class Glue_Win32(ProfileBase):
# Trigger build of gtksharp with specific bash for Mingw32 # Trigger build of gtksharp with specific bash for Mingw32
builder = GtkSharp() builder = GtkSharp()
builder.MSYSTEM = self.MSYSTEM builder.MSYSTEM = self.MSYSTEM
builder.build_net45() builder.build()
net45_build_dir = join(self.Build_NugetDir, 'build', 'net45') net45_build_dir = join(self.Build_NugetDir, 'build', 'net45')
os.makedirs(net45_build_dir, exist_ok=True) os.makedirs(net45_build_dir, exist_ok=True)

View file

@ -4,8 +4,6 @@ from pybuild.ProfileBase import ProfileBase
from os.path import abspath, join from os.path import abspath, join
from pybuild.Helper import Helper from pybuild.Helper import Helper
# TODO Add .Net Core generation
class GtkSharp(ProfileBase): class GtkSharp(ProfileBase):
def __init__(self): def __init__(self):
@ -19,7 +17,7 @@ class GtkSharp(ProfileBase):
def Build_ScriptDir(self): def Build_ScriptDir(self):
return abspath(join(self._BuildDir, 'scripts')) return abspath(join(self._BuildDir, 'scripts'))
def build_net45(self): def build(self):
"""Build the gtksharp binaries for .Net 4.5""" """Build the gtksharp binaries for .Net 4.5"""
os.makedirs(self.Build_ScriptDir, exist_ok=True) os.makedirs(self.Build_ScriptDir, exist_ok=True)
buildfile = join(self.Build_ScriptDir, 'net45_build.sh') buildfile = join(self.Build_ScriptDir, 'net45_build.sh')
@ -56,7 +54,7 @@ class GtkSharp(ProfileBase):
cmd = Helper.run_cmd(cmds, self.SrcDir) cmd = Helper.run_cmd(cmds, self.SrcDir)
def copy_net45(self): def copy(self):
"""Copy the .Net 4.5 dll's to the build dir""" """Copy the .Net 4.5 dll's to the build dir"""
net45_build_dir = join(self.Build_NugetDir, 'build', 'net45') net45_build_dir = join(self.Build_NugetDir, 'build', 'net45')

View file

@ -0,0 +1,155 @@
#!/usr/bin/python3
import os, shutil
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
# This is due to some small api changes in the platform that the Gtksharp code would need to be adjusted to
# We can however use the newer dotnet build system specifying the net461 platform
# This is the same set of platform libs under the surface (using mono) but a step in the right direction
# with modernising the build system. One advantage to this newer build system is that we don't need to list all the .cs files
# Within the project files (see generated .xproj file and project.json)
# TODO look into package for symbols, via NuGet -symbols
class GtkSharp_Core(ProfileBase):
def __init__(self):
"""Class Init"""
super().__init__()
self._NuGet_PackageName = 'GtkSharp.Core'
self._Version = Helper.get_gtksharp_version(self.SrcDir)
self.Solution = None
self.BuildConfig = 'Release'
@property
def Build_CoreDir(self):
return abspath(join(self._BuildDir, 'core'))
@property
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])
os.makedirs(destdir, exist_ok=True)
for fname in srclist:
shutil.copy(fname, destdir)
def SetupProject(self, projname):
proj = CoreVSProject()
proj.Name = 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.Version = self._Version
self.Solution.Projects.append(proj)
self.Solution.write()
return proj
def Build_Project(self, proj):
projdir = join(self.Build_CoreDir, proj.Name)
Helper.run_cmd([self.Dotnet_BuildExe, 'restore'], projdir)
Helper.run_cmd([self.Dotnet_BuildExe, 'build',
'--configuration', self.BuildConfig,
'--framework', 'net461',
'--output', join(self.Build_CoreDir, 'build')]
, projdir)
def build(self):
"""Build the gtksharp binaries for .Net 4.5"""
os.makedirs(self.Build_CoreDir, exist_ok=True)
self.Solution = vsgen.solution.VSGSolution()
self.Solution.FileName = join(self.Build_CoreDir, 'GtkSharp.sln')
# Build Glib
self.Copy_CS_Files(['glib/*.cs', 'glib/'])
proj = self.SetupProject('glib')
proj.write()
self.Build_Project(proj)
# Build Gio
self.Copy_CS_Files(['gio/*.cs', 'gio/'])
self.Copy_CS_Files(['gio/generated/GLib/*.cs', 'gio/generated/GLib/'])
proj = self.SetupProject('gio')
proj.Depends = {'glib': self._Version}
proj.write()
self.Build_Project(proj)
# Build Cairo
self.Copy_CS_Files(['cairo/*.cs', 'cairo/'])
proj = self.SetupProject('cairo')
proj.write()
self.Build_Project(proj)
# Build Pango
self.Copy_CS_Files(['pango/*.cs', 'pango/'])
self.Copy_CS_Files(['pango/generated/Pango/*.cs', 'pango/generated/Pango/'])
proj = self.SetupProject('pango')
proj.Depends = {'glib': self._Version,
'cairo': self._Version}
proj.write()
self.Build_Project(proj)
# Build Atk
self.Copy_CS_Files(['atk/*.cs', 'atk/'])
self.Copy_CS_Files(['atk/generated/Atk/*.cs', 'atk/generated/Atk/'])
proj = self.SetupProject('atk')
proj.Depends = {'glib': self._Version}
proj.write()
self.Build_Project(proj)
# Build Gdk
self.Copy_CS_Files(['gdk/*.cs', 'gdk/'])
self.Copy_CS_Files(['gdk/generated/Gdk/*.cs', 'gdk/generated/Gdk/'])
self.Copy_CS_Files(['gdk/generated/GLib/*.cs', 'gdk/generated/GLib/'])
proj = self.SetupProject('gdk')
proj.Depends = {'atk': self._Version,
'cairo': self._Version,
'gio': self._Version,
'glib': self._Version,
'pango': self._Version}
proj.write()
self.Build_Project(proj)
# Build Gtk
self.Copy_CS_Files(['gtk/*.cs', 'gtk/'])
self.Copy_CS_Files(['gtk/generated/GLib/*.cs', 'gtk/generated/GLib/'])
self.Copy_CS_Files(['gtk/generated/Gtk/*.cs', 'gtk/generated/Gtk/'])
proj = self.SetupProject('gtk')
proj.Depends = {'gdk': self._Version,
'glib': self._Version}
proj.write()
self.Build_Project(proj)
def copy_dll(self):
"""Copy the .Net 4.5 dll's to the build dir"""
net45_build_dir = join(self.Build_NugetDir, 'build', 'net45')
net45_lib_dir = join(self.Build_NugetDir, 'lib', 'net45')
os.makedirs(net45_build_dir, exist_ok=True)
os.makedirs(net45_lib_dir, exist_ok=True)
shutil.copy('./misc/GtkSharp.targets', net45_build_dir)
srclist = glob(join(self.Build_CoreDir, 'build', '*.dll'))
for item in srclist:
shutil.copy(item, net45_lib_dir)
# Get the Config files
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)

View file

@ -0,0 +1,144 @@
#!/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
from collections import OrderedDict
class CoreVSProject(VSGProject):
"""
CoreVSProject extends :class:`~vsgen.project.VSGProject` with data and logic needed to create a `.xproj` file.
:ivar str TargetFrameworkVersion: The target framework version.
:ivar str BaseIntermediateOutputPath: Intermediate path for building the output.
:ivar str ProjectXml: Override the xml within the .xproj file.
:ivar str ProjectJson: Override the json within the project.lock file.
"""
__project_type__ = 'netcore'
__writable_name__ = "Visual Studio .Net Core Project"
__registerable_name__ = "Visual Studio C# Compiler"
def __init__(self, **kwargs):
"""
Constructor.
:param kwargs: List of arbitrary keyworded arguments to be processed as instance variable data
"""
super(CoreVSProject, self).__init__(**kwargs)
def _import(self, datadict):
"""
Internal method to import instance variables data from a dictionary
:param dict datadict: The dictionary containing variables values.
"""
super(CoreVSProject, self)._import(datadict)
self.TargetFrameworkVersion = datadict.get('TargetFrameworkVersion', 'v4.6.1')
self.BaseIntermediateOutputPath = datadict.get('BaseIntermediateOutputPath', '.\obj')
self.ProjectXml = datadict.get('ProjectXml', None)
self.ProjectJson = datadict.get('ProjectJson', None)
self.Version = datadict.get('Version', '1.0.0-*')
self.Depends = datadict.get('Depends', {'NETStandard.Library': '1.6.0'})
self.Frameworks = datadict.get('Frameworks', None)
self.BuildOptions = datadict.get('BuildOptions', None)
def get_project_json(self):
"""
Get the json for use in Project.lock
"""
data = OrderedDict()
ver = {'version': self.Version}
data.update(ver)
depends = self.Depends
depends2 = {'dependencies': depends}
data.update(depends2)
if self.Frameworks != None:
frameworks = {'frameworks': self.Frameworks}
else:
frameworks = {'frameworks': {'netstandard1.6': {'imports': 'dnxcore50'}}}
data.update(frameworks)
if self.BuildOptions != None:
buildopts = {'buildOptions': self.BuildOptions}
data.update(buildopts)
return data
def get_project_xml(self):
"""
Get the xml for use in the xproj file
"""
xml_projroot = et.Element('Project')
xml_projroot.set('ToolsVersion', '14.0')
xml_projroot.set('DefaultTargets', 'Build')
xml_projroot.set('xmlns', 'http://schemas.microsoft.com/developer/msbuild/2003')
propgroup1 = et.SubElement(xml_projroot, 'PropertyGroup')
studiover = et.SubElement(propgroup1, 'VisualStudioVersion')
studiover.set('Condition', "'$(VisualStudioVersion)' == ''")
studiover.text = '14.0'
vstoolspath = et.SubElement(propgroup1, 'VSToolsPath')
vstoolspath.set('Condition', "'$(VSToolsPath)' == ''")
vstoolspath.text = r"$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)"
import1 = et.SubElement(xml_projroot, 'Import')
import1.set('Project', '$(VSToolsPath)\DotNet\Microsoft.DotNet.Props')
import1.set('Condition', "'$(VSToolsPath)' != ''")
propgroup2 = et.SubElement(xml_projroot, 'PropertyGroup')
propgroup2.set('Label', 'Globals')
projguid = et.SubElement(propgroup2, 'ProjectGuid')
projguid.text = self.lower(self.GUID)
rootnamespace = et.SubElement(propgroup2, 'RootNamespace')
rootnamespace.text = self.RootNamespace
baseintermediateoutputpath = et.SubElement(propgroup2, 'BaseIntermediateOutputPath')
baseintermediateoutputpath.set('Condition', "'$(BaseIntermediateOutputPath)'=='' ")
baseintermediateoutputpath.text = self.BaseIntermediateOutputPath
targetframeworkversion = et.SubElement(propgroup2, 'TargetFrameworkVersion')
targetframeworkversion.text = self.TargetFrameworkVersion
propgroup3 = et.SubElement(xml_projroot, 'PropertyGroup')
schemaver = et.SubElement(propgroup3, 'SchemaVersion')
schemaver.text = '2.0'
import2 = et.SubElement(xml_projroot, 'Import')
import2.set('Project', '$(VSToolsPath)\DotNet\Microsoft.DotNet.targets')
import2.set('Condition', "'$(VSToolsPath)' != ''")
etstr = et.tostring(xml_projroot, encoding='utf-8', method='xml').decode('utf-8')
outtxt = indent(etstr)
return outtxt
def write(self):
"""
Creates the project files.
"""
npath = os.path.normpath(self.FileName)
(filepath, filename) = os.path.split(npath)
os.makedirs(filepath, exist_ok=True)
projectFileName = os.path.normpath(self.FileName)
projxml = ''
if self.ProjectXml == None:
projxml = self.get_project_xml()
else:
projxml = self.ProjectXml
with open(projectFileName, 'wt') as f:
f.write(projxml)
jsonFileName = join(filepath, 'project.json')
if self.ProjectJson == None:
projjson = self.get_project_json()
else:
projjson = self.ProjectJson
with open(jsonFileName, 'w') as f:
txt = json.dumps(projjson, indent=2, separators=(',', ': '))
f.write(txt)

View file

View file

@ -7,7 +7,7 @@
<ProjectHome> <ProjectHome>
</ProjectHome> </ProjectHome>
<StartupFile>..\..\build.py</StartupFile> <StartupFile>..\..\build.py</StartupFile>
<SearchPath>..\..\;..\..\pybuild\</SearchPath> <SearchPath>..\..\;..\..\pybuild\;..\..\pybuild\vsgen\</SearchPath>
<WorkingDirectory>..\..\</WorkingDirectory> <WorkingDirectory>..\..\</WorkingDirectory>
<OutputPath>.</OutputPath> <OutputPath>.</OutputPath>
<Name>GtkSharp-NugetBuild</Name> <Name>GtkSharp-NugetBuild</Name>
@ -53,6 +53,9 @@
<Compile Include="..\..\pybuild\profiles\GtkSharp.py"> <Compile Include="..\..\pybuild\profiles\GtkSharp.py">
<Link>pybuild\profiles\GtkSharp.py</Link> <Link>pybuild\profiles\GtkSharp.py</Link>
</Compile> </Compile>
<Compile Include="..\..\pybuild\profiles\GtkSharp_Core.py">
<Link>pybuild\profiles\GtkSharp_Core.py</Link>
</Compile>
<Compile Include="..\..\pybuild\profiles\Gtk_Win32.py"> <Compile Include="..\..\pybuild\profiles\Gtk_Win32.py">
<Link>pybuild\profiles\Gtk_Win32.py</Link> <Link>pybuild\profiles\Gtk_Win32.py</Link>
</Compile> </Compile>
@ -62,12 +65,19 @@
<Compile Include="..\..\pybuild\profiles\__init__.py"> <Compile Include="..\..\pybuild\profiles\__init__.py">
<Link>pybuild\profiles\__init__.py</Link> <Link>pybuild\profiles\__init__.py</Link>
</Compile> </Compile>
<Compile Include="..\..\pybuild\vsgenext\CoreVSProject.py">
<Link>pybuild\vsgenext\CoreVSProject.py</Link>
</Compile>
<Compile Include="..\..\pybuild\vsgenext\__init__.py">
<Link>pybuild\vsgenext\__init__.py</Link>
</Compile>
<Compile Include="..\..\pybuild\__init__.py"> <Compile Include="..\..\pybuild\__init__.py">
<Link>pybuild\__init__.py</Link> <Link>pybuild\__init__.py</Link>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="pybuild\" /> <Folder Include="pybuild\" />
<Folder Include="pybuild\vsgenext\" />
<Folder Include="pybuild\profiles\" /> <Folder Include="pybuild\profiles\" />
</ItemGroup> </ItemGroup>
<Import Condition="Exists($(PtvsTargetsFile))" Project="$(PtvsTargetsFile)" /> <Import Condition="Exists($(PtvsTargetsFile))" Project="$(PtvsTargetsFile)" />