How to build Windows 64 bits Tryton Client?

Here’s an update of procedure How to build Windows Tryton Client (32 bits)

First you need a Windows 10 64 bits :

In msys interface:

  • Update database packages and system packages:
    pacman -Syu
  • Close msys window and relaunch msys64 to update packages:
    pacman -Su
  • Install some needed packages:
pacman -S mercurial tar python3 mingw-w64-x86_64-atk mingw-w64-x86_64-gcc mingw-w64-x86_64-gdk-pixbuf2 mingw-w64-x86_64-python3-gobject mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-goocanvas mingw-w64-x86_64-gtk3 mingw-w64-x86_64-nsis mingw-w64-x86_64-python3-babel mingw-w64-x86_64-python3-dateutil mingw-w64-x86_64-python3-setuptools mingw-w64-x86_64-librsvg mingw-w64-x86_64-python3-cx_Freeze
  • Clone Tryton and go to latest stable branch (or you could compile in dev version but it’s not recommended):
    hg clone http://hg.tryton.org/tryton
    cd tryton
    hg up 5.2
  • Patch file setup-freeze.py until tryton 5.4 release (minor changes: win32 -> win64, ‘lib’ -> ‘bin’)

https://pastebin.com/J2fb1rR9

  • Execute client compilation script:
    sh make-win32-installer.sh

Now, you should get tryton-setup.exe in c:\msys64\home\username\tryton
Hope this help ! Remarks and comments are welcome.

Great post @maxx.
How to get calendar working? I see goocanvas is installed but I cannot find information about installing goocalendar on msys2.

Thanks Sergyo!

Don’t know. Adding package in setup-freeze.py ? Maybe you should ask to cedk?

GooCalendar should be installed with pip because it is not enough famous to be packaged by MSYS. But its dependencies like GooCanvas should be installed with MSYS tools.

I tried with no success:

pacman -S python3-pip
pip install GooCalendar
sh make-win32-installer.sh

Are you sure to have installed GooCalendar for Python3?

I think so …

Datalife@DESKTOP-0L6677D MINGW64 ~
$ pip -V
pip 19.2.3 from /usr/lib/python3.7/site-packages/pip (python 3.7)

Datalife@DESKTOP-0L6677D MINGW64 ~
$ pip list | grep Calendar
GooCalendar 0.6

But does it work?

$ python3
>>> import goocalendar

GooCalendar depends on non Python dependencies like goocanvas.

No, it doesn’t.
Checking the path of pip I noticed it is not installed on /mingw64 directory but in /usr/lib.

So finally I get it working defining the custom target on pip install:

pip3 install goocalendar -t /mingw64/lib/python3.7/site-packages

Indeed another way would be installing specific pip for mingw64:

pacman -S mingw-w64-x86_64-python3-pip
pip3 install goocalendar

i got this

running compile_catalog
compiling catalog tryton/data/locale/bg/LC_MESSAGES/tryton.po to tryton/data/locale/bg/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/ca/LC_MESSAGES/tryton.po to tryton/data/locale/ca/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/cs/LC_MESSAGES/tryton.po to tryton/data/locale/cs/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/de/LC_MESSAGES/tryton.po to tryton/data/locale/de/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/es/LC_MESSAGES/tryton.po to tryton/data/locale/es/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/es_419/LC_MESSAGES/tryton.po to tryton/data/locale/es_419/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/et/LC_MESSAGES/tryton.po to tryton/data/locale/et/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/fa/LC_MESSAGES/tryton.po to tryton/data/locale/fa/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/fi/LC_MESSAGES/tryton.po to tryton/data/locale/fi/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/fr/LC_MESSAGES/tryton.po to tryton/data/locale/fr/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/hu/LC_MESSAGES/tryton.po to tryton/data/locale/hu/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/it/LC_MESSAGES/tryton.po to tryton/data/locale/it/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/ja_JP/LC_MESSAGES/tryton.po to tryton/data/locale/ja_JP/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/lo/LC_MESSAGES/tryton.po to tryton/data/locale/lo/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/lt/LC_MESSAGES/tryton.po to tryton/data/locale/lt/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/nl/LC_MESSAGES/tryton.po to tryton/data/locale/nl/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/pl/LC_MESSAGES/tryton.po to tryton/data/locale/pl/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/pt/LC_MESSAGES/tryton.po to tryton/data/locale/pt/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/ru/LC_MESSAGES/tryton.po to tryton/data/locale/ru/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/sl/LC_MESSAGES/tryton.po to tryton/data/locale/sl/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/tr/LC_MESSAGES/tryton.po to tryton/data/locale/tr/LC_MESSAGES/tryton.mo
compiling catalog tryton/data/locale/zh_CN/LC_MESSAGES/tryton.po to tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo
running install_exe
running build_exe
C:\msys64\home\user\tryton/tryton/gui/window/view_form/screen/screen.py:641: SyntaxWarning: "is" with a literal. Did you mean "=="?
  saved = all((x is 0 or x > 0 for x in self.group.save()))
C:\msys64\home\user\tryton/tryton/gui/window/view_form/screen/screen.py:646: SyntaxWarning: "is" with a literal. Did you mean "=="?
  saved = record_id is 0 or record_id > 0
C:\msys64\home\user\tryton/tryton/common/domain_parser.py:494: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if value or value is 0 or isinstance(value, float):
C:\msys64\home\user\tryton/tryton/common/domain_parser.py:500: SyntaxWarning: "is not" with a literal. Did you mean "!="?
  and value is not 0
*** WARNING *** unable to create version resource
install pywin32 extensions first
Missing modules:
? StringIO imported from gi._compat, six
? UserList imported from gi._compat
? __main__ imported from bdb, pdb
? _frozen_importlib imported from importlib, importlib.abc, zipimport
? _frozen_importlib_external imported from importlib, importlib._bootstrap, importlib.abc, zipimport
? _posixshmem imported from multiprocessing.resource_tracker, multiprocessing.shared_memory
? _posixsubprocess imported from multiprocessing.util, subprocess
? _scproxy imported from urllib.request
? _uuid imported from uuid
? _winreg imported from platform
? fcntl imported from gi._ossighelper
? gi.repository.Atk imported from pygtkcompat.pygtkcompat
? gi.repository.GLib imported from gi._gtktemplate, gi._ossighelper, gi.overrides.GObject, gi.overrides.GdkPixbuf, gi.overrides.Gio, pygtkcompat.pygtkcompat, tryton.bus, tryton.common.common, tryton.common.completion, tryton.common.selection, tryton.gui.main, tryton.gui.window.dblogin, tryton.gui.window.form, tryton.gui.window.view_board.action, tryton.gui.window.view_form.screen.screen, tryton.gui.window.view_form.view.form_gtk.calendar_, tryton.gui.window.view_form.view.form_gtk.char, tryton.gui.window.view_form.view.form_gtk.dictionary, tryton.gui.window.view_form.view.form_gtk.many2one, tryton.gui.window.view_form.view.form_gtk.multiselection, tryton.gui.window.view_form.view.form_gtk.selection, tryton.gui.window.view_form.view.form_gtk.widget, tryton.gui.window.view_form.view.list, tryton.gui.window.view_form.view.list_gtk.editabletree, tryton.gui.window.view_form.view.list_gtk.widget, tryton.gui.window.view_form.view.screen_container
? gi.repository.GObject imported from gi._gtktemplate, gi.overrides.Gtk, pygtkcompat.generictreemodel, pygtkcompat.pygtkcompat, tryton.common.cellrendererbutton, tryton.common.cellrendererclickablepixbuf, tryton.common.cellrenderercombo, tryton.common.cellrendererfloat, tryton.common.cellrendererinteger, tryton.common.cellrenderertext, tryton.common.cellrenderertoggle, tryton.common.common, tryton.common.datetime_, tryton.common.number_entry, tryton.common.selection, tryton.common.treeviewcontrol, tryton.gui.window.dblogin, tryton.gui.window.view_form.view.form_gtk.dictionary, tryton.gui.window.view_form.view.form_gtk.multiselection, tryton.gui.window.view_form.view.list, tryton.gui.window.view_form.view.list_form, tryton.gui.window.view_form.view.screen_container, tryton.gui.window.win_csv, tryton.gui.window.win_export
? gi.repository.GUdev imported from pygtkcompat.pygtkcompat
? gi.repository.Gdk imported from pygtkcompat.pygtkcompat, tryton.client, tryton.common.cellrendererfloat, tryton.common.common, tryton.common.datetime_, tryton.common.htmltextbuffer, tryton.common.number_entry, tryton.common.popup_menu, tryton.common.selection, tryton.common.treeviewcontrol, tryton.gui.main, tryton.gui.window.form, tryton.gui.window.preference, tryton.gui.window.view_form.view.calendar_gtk.toolbar, tryton.gui.window.view_form.view.form_gtk.binary, tryton.gui.window.view_form.view.form_gtk.image, tryton.gui.window.view_form.view.form_gtk.many2many, tryton.gui.window.view_form.view.form_gtk.many2one, tryton.gui.window.view_form.view.form_gtk.one2many, tryton.gui.window.view_form.view.form_gtk.richtextbox, tryton.gui.window.view_form.view.form_gtk.textbox, tryton.gui.window.view_form.view.form_gtk.widget, tryton.gui.window.view_form.view.graph_gtk.graph, tryton.gui.window.view_form.view.list, tryton.gui.window.view_form.view.list_gtk.editabletree, tryton.gui.window.view_form.view.list_gtk.widget, tryton.gui.window.view_form.view.screen_container, tryton.gui.window.win_csv, tryton.gui.window.win_export, tryton.gui.window.win_form, tryton.gui.window.win_search, tryton.gui.window.wizard
? gi.repository.GdkPixbuf imported from pygtkcompat.pygtkcompat, tryton.common.common, tryton.config, tryton.gui.main, tryton.gui.window.about
? gi.repository.GdkX11 imported from gi.overrides.Gdk
? gi.repository.Gio imported from gi._gtktemplate, pygtkcompat.pygtkcompat, tryton.client, tryton.gui.main, tryton.gui.window.view_form.view.list_form
? gi.repository.GooCanvas imported from pygtkcompat.pygtkcompat
? gi.repository.Gst imported from pygtkcompat.pygtkcompat
? gi.repository.GstAudio imported from pygtkcompat.pygtkcompat
? gi.repository.GstBase imported from pygtkcompat.pygtkcompat
? gi.repository.GstController imported from pygtkcompat.pygtkcompat
? gi.repository.GstInterfaces imported from pygtkcompat.pygtkcompat
? gi.repository.GstPbutils imported from pygtkcompat.pygtkcompat
? gi.repository.GstVideo imported from pygtkcompat.pygtkcompat
? gi.repository.Gtk imported from gi._gtktemplate, pygtkcompat.generictreemodel, pygtkcompat.pygtkcompat, tryton.client, tryton.common.button, tryton.common.cellrendererbutton, tryton.common.cellrendererclickablepixbuf, tryton.common.cellrenderercombo, tryton.common.cellrenderertext, tryton.common.cellrenderertoggle, tryton.common.common, tryton.common.completion, tryton.common.datetime_, tryton.common.focus, tryton.common.htmltextbuffer, tryton.common.number_entry, tryton.common.popup_menu, tryton.common.selection, tryton.common.treeviewcontrol, tryton.gui.main, tryton.gui.window.about, tryton.gui.window.dblogin, tryton.gui.window.email_, tryton.gui.window.form, tryton.gui.window.infobar, tryton.gui.window.limit, tryton.gui.window.preference, tryton.gui.window.revision, tryton.gui.window.tabcontent, tryton.gui.window.view_board.action, tryton.gui.window.view_board.view_board, tryton.gui.window.view_form.screen.screen, tryton.gui.window.view_form.view.calendar_, tryton.gui.window.view_form.view.calendar_gtk.toolbar, tryton.gui.window.view_form.view.form, tryton.gui.window.view_form.view.form_gtk.binary, tryton.gui.window.view_form.view.form_gtk.calendar_, tryton.gui.window.view_form.view.form_gtk.char, tryton.gui.window.view_form.view.form_gtk.checkbox, tryton.gui.window.view_form.view.form_gtk.dictionary, tryton.gui.window.view_form.view.form_gtk.image, tryton.gui.window.view_form.view.form_gtk.integer, tryton.gui.window.view_form.view.form_gtk.many2many, tryton.gui.window.view_form.view.form_gtk.many2one, tryton.gui.window.view_form.view.form_gtk.multiselection, tryton.gui.window.view_form.view.form_gtk.one2many, tryton.gui.window.view_form.view.form_gtk.progressbar, tryton.gui.window.view_form.view.form_gtk.pyson, tryton.gui.window.view_form.view.form_gtk.reference, tryton.gui.window.view_form.view.form_gtk.richtextbox, tryton.gui.window.view_form.view.form_gtk.selection, tryton.gui.window.view_form.view.form_gtk.state_widget, tryton.gui.window.view_form.view.form_gtk.textbox, tryton.gui.window.view_form.view.form_gtk.timedelta, tryton.gui.window.view_form.view.form_gtk.url, tryton.gui.window.view_form.view.form_gtk.widget, tryton.gui.window.view_form.view.graph, tryton.gui.window.view_form.view.graph_gtk.graph, tryton.gui.window.view_form.view.list, tryton.gui.window.view_form.view.list_form, tryton.gui.window.view_form.view.list_gtk.editabletree, tryton.gui.window.view_form.view.list_gtk.widget, tryton.gui.window.view_form.view.screen_container, tryton.gui.window.win_csv, tryton.gui.window.win_export, tryton.gui.window.win_form, tryton.gui.window.win_import, tryton.gui.window.win_search, tryton.gui.window.wizard, tryton.translate
? gi.repository.GtkSpell imported from tryton.gui.window.view_form.view.form_gtk.textbox
? gi.repository.Pango imported from pygtkcompat.pygtkcompat, tryton.common.cellrendererbutton, tryton.common.htmltextbuffer, tryton.gui.window.tabcontent, tryton.gui.window.win_form, tryton.gui.window.wizard
? gi.repository.PangoCairo imported from pygtkcompat.pygtkcompat
? gi.repository.Poppler imported from pygtkcompat.pygtkcompat
? gi.repository.Vte imported from pygtkcompat.pygtkcompat
? gi.repository.WebKit imported from pygtkcompat.pygtkcompat
? gi.repository.cairo imported from gi.overrides.Gdk
? goocalendar imported from tryton, tryton.gui.window.view_form.view.calendar_gtk.calendar_
? grp imported from pathlib, shutil, tarfile
? java.lang imported from platform, xml.sax._exceptions
? multiprocessing.AuthenticationError imported from multiprocessing.connection
? multiprocessing.BufferTooShort imported from multiprocessing.connection
? multiprocessing.TimeoutError imported from multiprocessing.pool
? multiprocessing.get_context imported from multiprocessing.managers, multiprocessing.pool, multiprocessing.sharedctypes
? multiprocessing.get_start_method imported from multiprocessing.spawn
? multiprocessing.set_start_method imported from multiprocessing.spawn
? netbios imported from uuid
? org.python.core imported from copy, pickle, xml.sax
? os.path imported from distutils.file_util, os, pkgutil, py_compile, sysconfig, tracemalloc, unittest, unittest.util
? pkg_resources imported from cairo, tryton.config, tryton.translate
? posix imported from os, shutil
? pwd imported from distutils.util, getpass, http.server, netrc, pathlib, posixpath, shutil, tarfile, webbrowser
? resource imported from test.support
? six.moves imported from dateutil.rrule, dateutil.tz._factories, dateutil.tz.tz, dateutil.tz.win
? termios imported from getpass, tty
? vms_lib imported from platform
? win32evtlog imported from logging.handlers
? win32evtlogutil imported from logging.handlers
? win32wnet imported from uuid
This is not necessarily a problem - the modules may not be needed on this platform.
error: [Errno 2] No such file or directory: 'C:/msys64/mingw64/tcl/tcl8.6'

Got same problem after updating packages…
Seems linked to the latest version of cx_Freeze (mingw-w64-x86_64-python-cx_Freeze-6.0-1)
Try to use an older version of cx_Freeze (5.1.1-3)

Got the same problem when building Windows Tryton Client (32 bits).
Found the following solution:

  1. Create С:\msys32\mingw32\tcl directory and copy into it these directories:
    C:\msys32\mingw32\lib\tcl8
    C:\msys32\mingw32\lib\tcl8.6
    C:\msys32\mingw32\lib\tk8.6
  2. Create С:\msys32\mingw32\Dlls directory and copy into it these files:
    C:\msys32\mingw32\bin\tcl86.dll
    C:\msys32\mingw32\bin\tk86.dll
  3. Rename these files in С:\msys32\mingw32\Dlls directory:
    tcl86.dll -> tcl86t.dll
    tk86.dll -> tk86t.dll

After that you can use the latest version of cx_Freeze and build Tryton Client.

Thanks Victor! Tested to build a 64 bits version…

After cloning tryton, apply following patch (until commited):
https://codereview.tryton.org/250371002

wget https://codereview.tryton.org/download/issue250371002_280621002.diff
patch -p1 < issue250371002_280621002.diff

Apply Victor’s solution for 64bits:

  • Create С:\msys64\mingw64\tcl directory and copy into it these directories:
    C:\msys64\mingw64\lib\tcl8.6
    C:\msys64\mingw64\lib\tk8.6
  • Create С:\msys64\mingw64\Dlls directory and copy into it these files:
    C:\msys64\mingw64\bin\tcl86.dll
    C:\msys64\mingw64\bin\tk86.dll
  • Rename these files in С:\msys64\mingw64\Dlls directory:
    tcl86.dll -> tcl86t.dll
    tk86.dll -> tk86t.dll

Execute client compilation script:

    sh make-win32-installer.sh

Now, you should get your executable in c:\msys64\home\username\tryton

For me, this is due to this https://github.com/anthony-tuininga/cx_Freeze/pull/493
But normally we do not need to bundle tcl/tk. I checked and on our official release, they are not bundled.
Maybe this https://github.com/anthony-tuininga/cx_Freeze/pull/559 fix the issue or we will have to explicitly exclude tkinter.

The latest version of cx_freeze is not packaged in msys32 so don’t know if this issue fix the problem.
But maybe it’s better to exclude tkinter if not used…

I did test again with latest version of cx_freeze and still the same problem with tkinter.
Don’t know why this package is included automatically, to avoid this problem may be we could add an “excludes” section in the setup-freeze.py file ?

...
setup(name='tryton',
    version=version,
    options={
        'build_exe': {
            'no_compress': True,
            'include_files': include_files,
            'silent': True,
            'excludes': ['tcl', 'Tkinter'],
            'packages': ['gi'],
            'include_msvcr': True,
            },
        'bdist_mac':
...

Where is the bug report on cx_Freeze? What is the opinion of the maintainer?
I would avoid include hacks without first trying to solve the problem.

Bug introduced 23/01/2020: https://github.com/anthony-tuininga/cx_Freeze/issues/566
https://github.com/msys2/MINGW-packages/issues/6139
No response…
Anyway it seems strange those packages are included even if Tryton doesn’t use them.

I updated the build machine and I got the same problem now.
As far as I understand, they decided to always bundle tkinter so I reused the example of the documentation and excluded tkinter: Issue 9292: Exclude tkinter from cx_freeze - Tryton issue tracker