How can we install python3 in wine for 32bit ubuntu ?
Using winetricks
python2.7
is possible but my app is written in python3
I don't have windows to test my application so I am going this hard way
Python 3.7 now works in the newer versions of wine.
This user used wine 4.14 to install python 3.7.4 and I'm currently using Python 3.7.6 in wine 5.0-rc3.
I'm able to run pyinstaller
for cross-compiling and I can test the resulting exe packages and my source code in wine without issue.
The apps I'm testing have a GUI based on PyQt5.
I first tried @Hibou57's approach using embedded-python which does not require newer wine versions.
While this works for a minimal python install, I ran into a lot of annoying problems later on requiring a number of hacks.
I gave up on this approach when I couldn't figure out how to install numpy
within embedded python in wine.
To install Python 3.7.6 in wine:
apt
to get the lastest dev versionssudo apt install winehq-devel
.wine cmd /c python-3.7.6.exe
.The script below is what I'm using to install python 3.7.6 inside a docker container for cross compiling using a Ubuntu 18.04 image. I'm also using a 64-bit wine prefix. Note that some parts of this script deal with docker-specific issues.
#!/bin/bash
set -e
echo "---------------------------------"
echo "-------- setup wine prefix ------"
echo "---------------------------------"
# We need the developer version of wine. We need at least version 4.14 (see link).
# This is the earliest version I've seen reported to work with python3 well
# Without this, we'd have to run the embedded install of python which is riddled
# with annoying issues.
# see: https://appdb.winehq.org/objectManager.php?sClass=version&iId=38187
echo "------ Installing required apt packages ------"
apt update
apt install -y wget gnupg software-properties-common apt-utils
echo "------ Add latest wine repo ------"
# Need at least wine 4.14 to install python 3.7
dpkg --add-architecture i386
wget -nc https://dl.winehq.org/wine-builds/winehq.key
apt-key add winehq.key
apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ bionic main'
apt update
# Add repo for faudio package. Required for winedev
add-apt-repository -y ppa:cybermax-dexter/sdl2-backport
echo "-------- Install wine-dev ------"
apt install -y \
winehq-devel \
winetricks \
xvfb # This is for making a dummy X server disply
echo "------ Download python ------"
wget https://www.python.org/ftp/python/3.7.6/python-3.7.6-amd64.exe
#wget https://www.python.org/ftp/python/3.7.6/python-3.7.6.exe
echo "------ Init wine prefix ------"
WINEPREFIX=~/.wine64 WINARCH=win64 winetricks \
corefonts \
win10
# Setup dummy screen
Xvfb :0 -screen 0 1024x768x16 &
jid=$!
echo "------ Install python ------"
DISPLAY=:0.0 WINEPREFIX=~/.wine64 wine cmd /c \
python-3.7.6-amd64.exe \
/quiet \
PrependPath=1 \
&& echo "Python Installation complete!"
# Display=:0.0 redirects wine graphical output to the dummy display.
# This is to avoid docker errors as the python installer requires a display,
# even when quiet install is specified.
I have a similar issue: I have to develop a Python3 application on Ubuntu which is to be delivered on Windows. I wanted to use pyInstaller to produce a Windows executable from Wine, since I unfortunately do not have access to a Windows box. But I failed to install Python3 on Wine too.
However, may be there is another option: using what’s called a python embeddable zip archive. See here: 3.8. Embedded Distribution (docs.python.org).
You can download it from releases download pages, as in this one (an example) : Python 3.5.2 (python.org).
You have two:
This means you have to ask the client if he/she is running a 32 bits or a 64 bits Windows.
That’s not perfect, since if Python3 is not able to run in Wine, there is no way to test the application’s Windows version. But at least, that’s a way to package something which should run on Windows, with the hope the source will behave on Windows the same way it behave on Ubuntu. At least, you should develop on the Ubuntu side, using a Python virtual environment. See 28.3. venv — Creation of virtual environments.
actually You can use python3 on wine:
basically all You need is to install python3 on a windows machine (for You only, not for all Users), and copy the whole directory to the wine machine.
Alternatively You can download it from Python releases download pages, as mentioned in the post of Hibou57
Then add following paths in the wine registry : "c:\python37;C:\python37\Scripts;..." and everything works fine.
I provided some convenient Scripts on Github to do that automatically for Ubuntu
However, You need to decide first if You want to Install WINE STABLE, WINE DEVELOP or WINE STAGING (I suggest WINE DEVELOP).
Then You need to decide which Architecture (32 Bit or 64 Bit Wine) and then, on top of that You can install 32 or 64 Bit Python 2.7 or Python 3.7 by copying as explained before.
the whole process is a bit lengthy and there are many details You need to install, here the scripts :
#!/bin/bash
# ../home/install_wine.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
chmod +x "${my_dir}/lib_bash/*.sh"
source "${my_dir}/lib_bash/lib_color.sh"
source "${my_dir}/lib_bash/lib_retry.sh"
source "${my_dir}/lib_bash/lib_wine_install.sh"
}
include_dependencies # me need to do that via a function to have local scope of my_dir
clr_bold clr_green "Install WINE"
check_wine_version
clr_green "add 386 Architecture"
retry sudo dpkg --add-architecture i386
clr_green "add Wine Keys"
retry wget https://dl.winehq.org/wine-builds/winehq.key
sudo apt-key add winehq.key
sudo apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ xenial main'
clr_green "Wine Packages Update"
retry sudo apt-get update
clr_green "Wine Packages Install"
retry sudo apt-get install --install-recommends winehq-${wine_version}
retry sudo apt-get install -y cabextract
retry sudo apt-get install -y libxml2
retry sudo apt-get install -y libpng-dev
clr_green "Install latest Winetricks"
sudo rm -f /usr/bin/winetricks
retry sudo wget --directory-prefix=/usr/bin/ https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
sudo chmod +x /usr/bin/winetricks
retry sudo winetricks -q --self-update
clr_green "Install latest Winetricks - done"
clr_green "done"
clr_green "******************************************************************************************************************"
clr_bold clr_green "FINISHED installing WINE and WINETRICKS"
clr_green "******************************************************************************************************************"
#!/bin/bash
# ../home/install_wine_machine.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
chmod +x "${my_dir}/lib_bash/*.sh"
source "${my_dir}/lib_bash/lib_color.sh"
source "${my_dir}/lib_bash/lib_retry.sh"
source "${my_dir}/lib_bash/lib_wine_install.sh"
}
include_dependencies # me need to do that via a function to have local scope of my_dir
clr_bold clr_green "Install Wine Machine"
check_wine_prefix
check_wine_arch
check_wine_windows_version
check_headless_xvfb
clr_green "Setup Wine Machine at ${WINEPREFIX}, WINEARCH=${WINEARCH}, wine_windows_version=${wine_windows_version}"
mkdir -p ${WINEPREFIX}
wine_drive_c_dir=${WINEPREFIX}/drive_c
# xvfb-run --auto-servernum winecfg # fails marshal_object couldnt get IPSFactory buffer for interface ...
if [[ ${xvfb_framebuffer_service_active} == "True" ]]; then sudo service xvfb stop ; fi # winecfg fails if xvfb server is running
winecfg
if [[ ${xvfb_framebuffer_service_active} == "True" ]]; then sudo service xvfb start ; fi # winecfg fails if xvfb server is running
echo "Disable GUI Crash Dialogs"
winetricks nocrashdialog
echo "Set Windows Version to ${wine_windows_version}"
winetricks -q ${wine_windows_version}
echo "Install common Packets"
retry winetricks -q windowscodecs
retry winetricks -q msxml3
clr_green "done"
clr_green "******************************************************************************************************************"
clr_bold clr_green "FINISHED installing Wine Machine ${WINEPREFIX}"
clr_green "******************************************************************************************************************"
#!/bin/bash
# ../home/install_wine_python2_preinstalled.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
chmod +x "${my_dir}/lib_bash/*.sh"
source "${my_dir}/lib_bash/lib_color.sh"
source "${my_dir}/lib_bash/lib_retry.sh"
source "${my_dir}/lib_bash/lib_wine_install.sh"
}
include_dependencies # me need to do that via a function to have local scope of my_dir
# if used outside github/travis You need to set :
# WINEARCH=win32 for 32 Bit Wine
# WINEARCH= for 64 Bit Wine
# WINEPREFIX defaults to ${HOME}/.wine or you need to pass it via environment variable
# if running headless, the xvfb service needs to run
clr_bold clr_green "Install Python 2.7 on WINE"
check_wine_prefix
check_wine_arch
wine_drive_c_dir=${WINEPREFIX}/drive_c
decompress_dir=${HOME}/bitranox_decompress
mkdir -p ${decompress_dir}
python_version_short=python27
python_version_doc="Python 2.7"
clr_green "Download ${python_version_doc} Binaries from https://github.com/bitranox/binaries_${python_version_short}_wine/archive/master.zip"
retry wget -nc --no-check-certificate -O ${decompress_dir}/binaries_${python_version_short}_wine-master.zip https://github.com/bitranox/binaries_${python_version_short}_wine/archive/master.zip
clr_green "Unzip ${python_version_doc} Master to ${HOME}"
unzip -nqq ${decompress_dir}/binaries_${python_version_short}_wine-master.zip -d ${decompress_dir}
if [[ "${WINEARCH}" == "win32" ]]
then
clr_green "Joining Multipart Zip in ${decompress_dir}/binaries_${python_version_short}_wine-master/bin"
cat ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/python*_wine_32* > ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/joined_${python_version_short}.zip
add_pythonpath="c:/Python27-32;c:/Python27-32/Scripts"
else
clr_green "Joining Multipart Zip in ${decompress_dir}/binaries_${python_version_short}_wine-master/bin"
cat ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/python*_wine_64* > ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/joined_${python_version_short}.zip
add_pythonpath="c:/Python27-64;c:/Python27-64/Scripts"
fi
clr_green "Unzip ${python_version_doc} to ${wine_drive_c_dir}"
unzip -qq ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/joined_${python_version_short}.zip -d ${wine_drive_c_dir}
prepend_path_to_wine_registry ${add_pythonpath}
clr_green "done"
clr_green "******************************************************************************************************************"
clr_bold clr_green "FINISHED installing Python 2.7 on Wine Machine ${WINEPREFIX}"
clr_green "******************************************************************************************************************"
#!/bin/bash
# ../home/install_wine_python3_preinstalled.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
chmod +x "${my_dir}/lib_bash/*.sh"
source "${my_dir}/lib_bash/lib_color.sh"
source "${my_dir}/lib_bash/lib_retry.sh"
source "${my_dir}/lib_bash/lib_wine_install.sh"
}
include_dependencies # me need to do that via a function to have local scope of my_dir
# if used outside github/travis You need to set :
# WINEARCH=win32 for 32 Bit Wine
# WINEARCH="" for 64 Bit Wine
# WINEPREFIX defaults to ${HOME}/.wine or you need to pass it via environment variable
# if running headless, the xvfb service needs to run
clr_bold clr_green "Install Python 3.7 on WINE"
check_wine_prefix
check_wine_arch
wine_drive_c_dir=${WINEPREFIX}/drive_c
decompress_dir=${HOME}/bitranox_decompress
mkdir -p ${decompress_dir}
python_version_short=python37
python_version_doc="Python 3.7"
clr_green "Download ${python_version_doc} Binaries from https://github.com/bitranox/binaries_${python_version_short}_wine/archive/master.zip"
retry wget -nc --no-check-certificate -O ${decompress_dir}/binaries_${python_version_short}_wine-master.zip https://github.com/bitranox/binaries_${python_version_short}_wine/archive/master.zip
clr_green "Unzip ${python_version_doc} Master to ${HOME}"
unzip -nqq ${decompress_dir}/binaries_${python_version_short}_wine-master.zip -d ${decompress_dir}
if [[ "${WINEARCH}" == "win32" ]]
then
clr_green "Joining Multipart Zip in ${decompress_dir}/binaries_${python_version_short}_wine-master/bin"
cat ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/python*_wine_32* > ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/joined_${python_version_short}.zip
add_pythonpath="c:/Python37-32;c:/Python37-32/Scripts"
else
clr_green "Joining Multipart Zip in ${decompress_dir}/binaries_${python_version_short}_wine-master/bin"
cat ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/python*_wine_64* > ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/joined_${python_version_short}.zip
add_pythonpath="c:/Python37-64;c:/Python37-64/Scripts"
fi
clr_green "Unzip ${python_version_doc} to ${wine_drive_c_dir}"
unzip -qq ${decompress_dir}/binaries_${python_version_short}_wine-master/bin/joined_${python_version_short}.zip -d ${wine_drive_c_dir}
prepend_path_to_wine_registry ${add_pythonpath}
clr_green "done"
clr_green "******************************************************************************************************************"
clr_bold clr_green "FINISHED installing Python 3.7 on Wine Machine ${WINEPREFIX}"
clr_green "******************************************************************************************************************"
#!/bin/bash
# ../home/install_wine_git_portable.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
chmod +x "${my_dir}/lib_bash/*.sh"
source "${my_dir}/lib_bash/lib_color.sh"
source "${my_dir}/lib_bash/lib_retry.sh"
source "${my_dir}/lib_bash/lib_wine_install.sh"
}
include_dependencies # me need to do that via a function to have local scope of my_dir
# if used outside github/travis You need to set :
# WINEARCH=win32 for 32 Bit Wine
# WINEARCH= for 64 Bit Wine
# WINEPREFIX defaults to ${HOME}/.wine or you need to pass it via environment variable
# if running headless, the xvfb service needs to run
clr_bold clr_green "Install Git Portable"
check_wine_prefix
check_wine_arch
wine_drive_c_dir=${WINEPREFIX}/drive_c
decompress_dir=${HOME}/bitranox_decompress
mkdir -p ${decompress_dir}
clr_green "Download Git Portable Binaries"
retry wget -nc --no-check-certificate -O ${decompress_dir}/binaries_portable_git-master.zip https://github.com/bitranox/binaries_portable_git/archive/master.zip
clr_green "Unzip Git Portable Binaries Master to ${decompress_dir}"
unzip -nqq ${decompress_dir}/binaries_portable_git-master.zip -d ${decompress_dir}
if [[ "${WINEARCH}" == "win32" ]]
then
clr_green "Joining Multipart Zip in ${decompress_dir}/binaries_portable_git-master/bin"
cat ${decompress_dir}/binaries_portable_git-master/bin/PortableGit32* > ${decompress_dir}/binaries_portable_git-master/bin/joined_PortableGit.zip
add_git_path="c:/PortableGit32/cmd"
else
clr_green "Joining Multipart Zip in ${decompress_dir}/binaries_portable_git-master/bin"
cat ${decompress_dir}/binaries_portable_git-master/bin/PortableGit64* > ${decompress_dir}/binaries_portable_git-master/bin/joined_PortableGit.zip
add_git_path="c:/PortableGit64/cmd"
fi
clr_green "Unzip Git Portable Binaries to ${wine_drive_c_dir}"
unzip -qq ${decompress_dir}/binaries_portable_git-master/bin/joined_PortableGit.zip -d ${wine_drive_c_dir}
prepend_path_to_wine_registry ${add_git_path}
clr_green "done"
clr_green "******************************************************************************************************************"
clr_bold clr_green "FINISHED installing Git Portable on Wine Machine ${WINEPREFIX}"
clr_green "******************************************************************************************************************"
#!/bin/bash
# ../home/lib_bash/lib_color.sh
#
# Constants and functions for terminal colors.
# Author: Max Tsepkov <[email protected]>
# Manual see https://github.com/mercuriev/bash_colors
#
CLR_ESC="\033["
# All these variables has a function with the same name, but in lower case.
#
CLR_RESET=0 # reset all attributes to their defaults
CLR_RESET_UNDERLINE=24 # underline off
CLR_RESET_REVERSE=27 # reverse off
CLR_DEFAULT=39 # set underscore off, set default foreground color
CLR_DEFAULTB=49 # set default background color
CLR_BOLD=1 # set bold
CLR_BRIGHT=2 # set half-bright (simulated with color on a color display)
CLR_UNDERSCORE=4 # set underscore (simulated with color on a color display)
CLR_REVERSE=7 # set reverse video
CLR_BLACK=30 # set black foreground
CLR_RED=31 # set red foreground
CLR_GREEN=32 # set green foreground
CLR_BROWN=33 # set brown foreground
CLR_BLUE=34 # set blue foreground
CLR_MAGENTA=35 # set magenta foreground
CLR_CYAN=36 # set cyan foreground
CLR_WHITE=37 # set white foreground
CLR_BLACKB=40 # set black background
CLR_REDB=41 # set red background
CLR_GREENB=42 # set green background
CLR_BROWNB=43 # set brown background
CLR_BLUEB=44 # set blue background
CLR_MAGENTAB=45 # set magenta background
CLR_CYANB=46 # set cyan background
CLR_WHITEB=47 # set white background
# check if string exists as function
# usage: if fn_exists "sometext"; then ... fi
function fn_exists
{
type -t "$1" | grep -q 'function'
}
# iterate through command arguments, o allow for iterative color application
function clr_layer
{
# default echo setting
CLR_ECHOSWITCHES="-e"
CLR_STACK=""
CLR_SWITCHES=""
ARGS=("$@")
# iterate over arguments in reverse
for ((i=$#; i>=0; i--)); do
ARG=${ARGS[$i]}
# echo $ARG
# set CLR_VAR as last argtype
firstletter=${ARG:0:1}
# check if argument is a switch
if [ "$firstletter" = "-" ] ; then
# if -n is passed, set switch for echo in clr_escape
if [[ $ARG == *"n"* ]]; then
CLR_ECHOSWITCHES="-en"
CLR_SWITCHES=$ARG
fi
else
# last arg is the incoming string
if [ -z "$CLR_STACK" ]; then
CLR_STACK=$ARG
else
# if the argument is function, apply it
if [ -n "$ARG" ] && fn_exists $ARG; then
#continue to pass switches through recursion
CLR_STACK=$($ARG "$CLR_STACK" $CLR_SWITCHES)
fi
fi
fi
done
# pass stack and color var to escape function
clr_escape "$CLR_STACK" $1;
}
# General function to wrap string with escape sequence(s).
# Ex: clr_escape foobar $CLR_RED $CLR_BOLD
function clr_escape
{
local result="$1"
until [ -z "${2:-}" ]; do
if ! [ $2 -ge 0 -a $2 -le 47 ] 2>/dev/null; then
echo "clr_escape: argument \"$2\" is out of range" >&2 && return 1
fi
result="${CLR_ESC}${2}m${result}${CLR_ESC}${CLR_RESET}m"
shift || break
done
echo "$CLR_ECHOSWITCHES" "$result"
}
function clr_reset { clr_layer $CLR_RESET "$@"; }
function clr_reset_underline { clr_layer $CLR_RESET_UNDERLINE "$@"; }
function clr_reset_reverse { clr_layer $CLR_RESET_REVERSE "$@"; }
function clr_default { clr_layer $CLR_DEFAULT "$@"; }
function clr_defaultb { clr_layer $CLR_DEFAULTB "$@"; }
function clr_bold { clr_layer $CLR_BOLD "$@"; }
function clr_bright { clr_layer $CLR_BRIGHT "$@"; }
function clr_underscore { clr_layer $CLR_UNDERSCORE "$@"; }
function clr_reverse { clr_layer $CLR_REVERSE "$@"; }
function clr_black { clr_layer $CLR_BLACK "$@"; }
function clr_red { clr_layer $CLR_RED "$@"; }
function clr_green { clr_layer $CLR_GREEN "$@"; }
function clr_brown { clr_layer $CLR_BROWN "$@"; }
function clr_blue { clr_layer $CLR_BLUE "$@"; }
function clr_magenta { clr_layer $CLR_MAGENTA "$@"; }
function clr_cyan { clr_layer $CLR_CYAN "$@"; }
function clr_white { clr_layer $CLR_WHITE "$@"; }
function clr_blackb { clr_layer $CLR_BLACKB "$@"; }
function clr_redb { clr_layer $CLR_REDB "$@"; }
function clr_greenb { clr_layer $CLR_GREENB "$@"; }
function clr_brownb { clr_layer $CLR_BROWNB "$@"; }
function clr_blueb { clr_layer $CLR_BLUEB "$@"; }
function clr_magentab { clr_layer $CLR_MAGENTAB "$@"; }
function clr_cyanb { clr_layer $CLR_CYANB "$@"; }
function clr_whiteb { clr_layer $CLR_WHITEB "$@"; }
# Outputs colors table
function clr_dump
{
local T='gYw'
echo -e "\n 40m 41m 42m 43m 44m 45m 46m 47m";
for FGs in ' 0m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' \
' 32m' '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' \
' 35m' '1;35m' ' 36m' '1;36m' ' 37m' '1;37m';
do
FG=${FGs// /}
echo -en " $FGs \033[$FG $T "
for BG in 40m 41m 42m 43m 44m 45m 46m 47m; do
echo -en " \033[$FG\033[$BG $T \033[0m";
done
echo;
done
echo
clr_bold " Code Function Variable"
echo \
' 0 clr_reset $CLR_RESET
1 clr_bold $CLR_BOLD
2 clr_bright $CLR_BRIGHT
4 clr_underscore $CLR_UNDERSCORE
7 clr_reverse $CLR_REVERSE
30 clr_black $CLR_BLACK
31 clr_red $CLR_RED
32 clr_green $CLR_GREEN
33 clr_brown $CLR_BROWN
34 clr_blue $CLR_BLUE
35 clr_magenta $CLR_MAGENTA
36 clr_cyan $CLR_CYAN
37 clr_white $CLR_WHITE
40 clr_blackb $CLR_BLACKB
41 clr_redb $CLR_REDB
42 clr_greenb $CLR_GREENB
43 clr_brownb $CLR_BROWNB
44 clr_blueb $CLR_BLUEB
45 clr_magentab $CLR_MAGENTAB
46 clr_cyanb $CLR_CYANB
47 clr_whiteb $CLR_WHITEB
'
}
function fail {
clr_bold clr_red "${1}" >&2
exit 1
}
## make it possible to call functions without source include
# Check if the function exists (bash specific)
if [[ ! -z "$1" ]]
then
if declare -f "${1}" > /dev/null
then
# call arguments verbatim
"$@"
else
# Show a helpful error
function_name="${1}"
library_name="${0}"
fail "\"${function_name}\" is not a known function name of \"${library_name}\""
fi
fi
#!/bin/bash
# ../home/lib_bash/lib_retry.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
source "${my_dir}/lib_color.sh"
}
include_dependencies # we need to do that via a function to have local scope of my_dir
function fail {
clr_bold clr_red "${1}" >&2
exit 1
}
function retry {
local n=1
local max=5
local delay=5
while true; do
my_command="${@}"
"$@" && break || {
if [[ $n -lt $max ]]; then
((n++))
clr_bold clr_red "Command \"${my_command}\" failed. Attempt ${n}/${max}:"
sleep $delay;
else
fail "The command \"${my_command}\" has failed after ${n} attempts."
fi
}
done
}
## make it possible to call functions without source include
# Check if the function exists (bash specific)
if [[ ! -z "$1" ]]
then
if declare -f "${1}" > /dev/null
then
# call arguments verbatim
"$@"
else
# Show a helpful error
function_name="${1}"
library_name="${0}"
fail "\"${function_name}\" is not a known function name of \"${library_name}\""
fi
fi
#!/bin/bash
# ../home/lib_bash/lib_wine_install.sh
function include_dependencies {
local my_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" # this gives the full path, even for sourced scripts
chmod +x "${my_dir}/*.sh"
source "${my_dir}/lib_color.sh"
source "${my_dir}/lib_retry.sh"
}
include_dependencies # we need to do that via a function to have local scope of my_dir
function fail {
clr_bold clr_red "${1}" >&2
exit 1
}
function check_wine_version {
if [[ -z ${wine_version} ]]
then
clr_bold clr_red "WARNING - no wine_version in environment set - set now to default: devel"
echo "available Versions: stable, devel, staging"
export wine_version="devel"
fi
}
function check_wine_prefix {
## set wine prefix to ${HOME}/.wine if not given by environment variable
if [[ -z ${WINEPREFIX} ]]
then
clr_bold clr_red "WARNING - no WINEPREFIX in environment - set now to ${HOME}/.wine"
export WINEPREFIX=${HOME}/.wine
fi
}
function check_wine_arch {
if [[ -z ${WINEARCH} ]]
then
clr_bold clr_red "WARNING - no WINEARCH in environment - will install 64 Bit Wine"
clr_bold clr_red "in Order to install 32Bit You need to set WINEARCH=\"win32\""
clr_bold clr_red "in Order to install 64Bit You need to set WINEARCH=\"\""
fi
}
function check_wine_windows_version {
if [[ -z ${wine_windows_version} ]]
then
clr_bold clr_red "WARNING - no wine_windows_version in environment - set now to win10"
clr_bold clr_red "available Versions: win10, win2k, win2k3, win2k8, win31, win7, win8, win81, win95, win98, winxp"
export wine_windows_version="win10"
fi
}
function check_headless_xvfb {
clr_green "Check if we run headless and xvfb Server is running"
export xvfb_framebuffer_service_active="False"
systemctl is-active --quiet xvfb && export xvfb_framebuffer_service_active="True"
# run winetricks with xvfb if needed
if [[ ${xvfb_framebuffer_service_active} == "True" ]]
then
clr_green "we run headless, xvfb service is running"
else
clr_green "we run on normal console, xvfb service is not running"
fi
}
function prepend_path_to_wine_registry {
add_pythonpath="${1}"
clr_green "add Path Settings to Registry"
wine_current_reg_path="`wine reg QUERY \"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" /v PATH | grep REG_SZ | sed 's/^.*REG_SZ\s*//'`"
wine_new_reg_path="${add_pythonpath};${wine_current_reg_path}"
wine reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /t REG_SZ /v PATH /d "${wine_new_reg_path}" /f
wine_actual_reg_path="`wine reg QUERY \"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" /v PATH | grep REG_SZ | sed 's/^.*REG_SZ\s*//'`"
clr_green "adding Path done"
clr_bold clr_green "Wine Registry PATH=${wine_actual_reg_path}"
}
## make it possible to call functions without source include
# Check if the function exists (bash specific)
if [[ ! -z "$1" ]]
then
if declare -f "${1}" > /dev/null
then
# call arguments verbatim
"$@"
else
# Show a helpful error
function_name="${1}"
library_name="${0}"
fail "\"${function_name}\" is not a known function name of \"${library_name}\""
fi
fi
Microsoft offers free Windows VM images for download. They're meant to be used to test websites in Internet Explorer, but they're still fully featured copies of Windows on which you could install Python 3 and test your application in a more faithful Windows environment than Wine
Here is the simple guide that I've used:
#1 Use Wine 2.4
apt install add-apt-repository
add-apt-repository ppa:wine/wine-builds
apt install --install-recommends winehq-devel
#2 Use winetricks (a newer one that what is available in the repo)
wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
./winetricks -q win10
./winetricks vcrun2015
After that just execute wine python-3.4.4.exe or whatever your Python is. If you are using python 3.5 the "install" option will not be visible but if you click in the center of the installer it will complete successfully and python works.
A ready-made docker image: https://hub.docker.com/r/cdrx/pyinstaller-windows
Hopefully it saves some people's time.
As many answers said, there is Wine. But they all made complicated scripts, while we just need some logic to install Python 3 on Wine. As I know, Wine uses code from Windows XP, and since Python since version 3.9 does not support Windows XP, you will have to use Python 3.8.9, which is the last version supported by Windows XP. Here's what I did on my Linux (MX Linux - Wine 6.22, stable branch, 64 bits computer):
sudo apt install wine-stable wine64 -y # use package wine32 instead of wine64 if you install Python 3.8.9 32 bits version
wget -O "python-install.exe" "https://www.python.org/ftp/python/3.8.9/python-3.8.9-amd64.exe" # you can also download the 32bits python version here: https://www.python.org/ftp/python/3.8.9/python-3.8.9-amd64.exe
wine python-install.exe # launchs a new window containing python install, check the add python.exe to path box, click install to hard drive, wait for it install and click close
wine py # can also be `py3` by example or many others depending on which are allready taken **in wine** (not in your linux real installation!)
The last command launches the Python 3.8.9 shell, so you can run print("Hello world !")
to make sure it's installed correctly.
Also, since its running in Wine, os.name
is nt
and platform.system()
is Windows
.
Now, to compile your programm:
cd /folder/containing/my/python/script
wine py -m pip install pyinstaller
wine py -m pyinstaller --onefile myscript.py # the option --onefile creates a portable script where everything required by python (not external programms that are ran by the script !) are inclued in the same .exe file
Note that if you installed Python 3.8.9 32 bits on Wine, your executable will be compatible with 32bits and 64bits Windows (thanks to Wow64 that "emulates" the 32 bits programms to make they can run on 64bits computers) but 64bits Python will produce executable for only 64bits Windows.
wine
?