mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +00:00
Add support for wine+mingw environments
This commit is contained in:
parent
fe39bd3027
commit
3d8662ebfe
5 changed files with 128 additions and 3 deletions
52
README.md
52
README.md
|
@ -279,3 +279,55 @@ pip3 install meson
|
||||||
Note that Meson is written entirely in Python, so you can also run it as-is
|
Note that Meson is written entirely in Python, so you can also run it as-is
|
||||||
from the [git repository](https://github.com/mesonbuild/meson/) if you want to
|
from the [git repository](https://github.com/mesonbuild/meson/) if you want to
|
||||||
use the latest master branch for some reason.
|
use the latest master branch for some reason.
|
||||||
|
|
||||||
|
|
||||||
|
### Setup a mingw/wine based development environment on linux
|
||||||
|
|
||||||
|
#### Install wine and mingw
|
||||||
|
|
||||||
|
##### On fedora x64
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
sudo dnf install mingw64-gcc mingw64-gcc-c++ mingw64-pkg-config mingw64-winpthreads wine
|
||||||
|
```
|
||||||
|
|
||||||
|
FIXME: Figure out what needs to be installed on other distros
|
||||||
|
|
||||||
|
#### Get meson from git
|
||||||
|
|
||||||
|
This simplifies the process and allows us to use the cross files
|
||||||
|
defined in meson itself.
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
git clone https://github.com/mesonbuild/meson.git
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Build and install
|
||||||
|
|
||||||
|
```
|
||||||
|
BUILDDIR=$PWD/winebuild/
|
||||||
|
export WINEPREFIX=$BUILDDIR/wine-prefix/ && mkdir -p $WINEPREFIX
|
||||||
|
# Setting the prefix is mandatory as it is used to setup symlinks during uninstalled development
|
||||||
|
meson/meson.py $BUILDDIR --cross-file meson/cross/linux-mingw-w64-64bit.txt -Dgst-plugins-bad:vulkan=disabled -Dorc:gtk_doc=disabled --prefix=$BUILDDIR/wininstall/ -Djson-glib:gtk_doc=disabled
|
||||||
|
meson/meson.py install -C $BUILDDIR/
|
||||||
|
```
|
||||||
|
|
||||||
|
> __NOTE__: You should use `meson install -C $BUILDDIR` each time you make a change
|
||||||
|
> instead of the usual `ninja -C build` as the environment is not uninstalled.
|
||||||
|
|
||||||
|
#### The development environment
|
||||||
|
|
||||||
|
You can get into the development environment the usual way:
|
||||||
|
|
||||||
|
```
|
||||||
|
ninja -C $BUILDDIR/ devenv
|
||||||
|
```
|
||||||
|
|
||||||
|
After setting up [binfmt] to use wine for windows binaries,
|
||||||
|
you can run GStreamer tools under wine by running:
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-launch-1.0.exe videotestsrc ! glimagesink
|
||||||
|
```
|
||||||
|
|
||||||
|
[binfmt]: http://man7.org/linux/man-pages/man5/binfmt.d.5.html
|
40
gst-env.py
40
gst-env.py
|
@ -19,6 +19,7 @@ from distutils.util import strtobool
|
||||||
from scripts.common import get_meson
|
from scripts.common import get_meson
|
||||||
from scripts.common import git
|
from scripts.common import git
|
||||||
from scripts.common import win32_get_short_path_name
|
from scripts.common import win32_get_short_path_name
|
||||||
|
from scripts.common import get_wine_shortpath
|
||||||
|
|
||||||
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__))
|
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
PREFIX_DIR = os.path.join(SCRIPTDIR, 'prefix')
|
PREFIX_DIR = os.path.join(SCRIPTDIR, 'prefix')
|
||||||
|
@ -88,29 +89,53 @@ def is_library_target_and_not_plugin(target, filename):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_wine_subprocess_env(options, env):
|
||||||
|
with open(os.path.join(options.builddir, 'meson-info', 'intro-buildoptions.json')) as f:
|
||||||
|
buildoptions = json.load(f)
|
||||||
|
|
||||||
|
prefix, = [o for o in buildoptions if o['name'] == 'prefix']
|
||||||
|
path = os.path.normpath(os.path.join(prefix['value'], 'bin'))
|
||||||
|
prepend_env_var(env, "PATH", path, options.sysroot)
|
||||||
|
wine_path = get_wine_shortpath(
|
||||||
|
options.wine.split(' '),
|
||||||
|
[path] + env.get('WINEPATH', '').split(';')
|
||||||
|
)
|
||||||
|
if options.winepath:
|
||||||
|
wine_path += ';' + options.winepath
|
||||||
|
env['WINEPATH'] = wine_path
|
||||||
|
env['WINEDEBUG'] = 'fixme-all'
|
||||||
|
|
||||||
|
return env
|
||||||
|
|
||||||
|
|
||||||
def get_subprocess_env(options, gst_version):
|
def get_subprocess_env(options, gst_version):
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
|
|
||||||
env["CURRENT_GST"] = os.path.normpath(SCRIPTDIR)
|
env["CURRENT_GST"] = os.path.normpath(SCRIPTDIR)
|
||||||
|
env["GST_VERSION"] = gst_version
|
||||||
env["GST_VALIDATE_SCENARIOS_PATH"] = os.path.normpath(
|
env["GST_VALIDATE_SCENARIOS_PATH"] = os.path.normpath(
|
||||||
"%s/subprojects/gst-devtools/validate/data/scenarios" % SCRIPTDIR)
|
"%s/subprojects/gst-devtools/validate/data/scenarios" % SCRIPTDIR)
|
||||||
env["GST_VALIDATE_PLUGIN_PATH"] = os.path.normpath(
|
env["GST_VALIDATE_PLUGIN_PATH"] = os.path.normpath(
|
||||||
"%s/subprojects/gst-devtools/validate/plugins" % options.builddir)
|
"%s/subprojects/gst-devtools/validate/plugins" % options.builddir)
|
||||||
env["GST_VALIDATE_APPS_DIR"] = os.path.normpath(
|
env["GST_VALIDATE_APPS_DIR"] = os.path.normpath(
|
||||||
"%s/subprojects/gst-editing-services/tests/validate" % SCRIPTDIR)
|
"%s/subprojects/gst-editing-services/tests/validate" % SCRIPTDIR)
|
||||||
|
env["GST_ENV"] = 'gst-' + gst_version
|
||||||
|
env["GST_REGISTRY"] = os.path.normpath(options.builddir + "/registry.dat")
|
||||||
prepend_env_var(env, "PATH", os.path.normpath(
|
prepend_env_var(env, "PATH", os.path.normpath(
|
||||||
"%s/subprojects/gst-devtools/validate/tools" % options.builddir),
|
"%s/subprojects/gst-devtools/validate/tools" % options.builddir),
|
||||||
options.sysroot)
|
options.sysroot)
|
||||||
|
|
||||||
|
if options.wine:
|
||||||
|
return get_wine_subprocess_env(options, env)
|
||||||
|
|
||||||
prepend_env_var(env, "PATH", os.path.join(SCRIPTDIR, 'meson'),
|
prepend_env_var(env, "PATH", os.path.join(SCRIPTDIR, 'meson'),
|
||||||
options.sysroot)
|
options.sysroot)
|
||||||
env["GST_VERSION"] = gst_version
|
|
||||||
env["GST_ENV"] = 'gst-' + gst_version
|
|
||||||
env["GST_PLUGIN_SYSTEM_PATH"] = ""
|
env["GST_PLUGIN_SYSTEM_PATH"] = ""
|
||||||
env["GST_PLUGIN_SCANNER"] = os.path.normpath(
|
env["GST_PLUGIN_SCANNER"] = os.path.normpath(
|
||||||
"%s/subprojects/gstreamer/libs/gst/helpers/gst-plugin-scanner" % options.builddir)
|
"%s/subprojects/gstreamer/libs/gst/helpers/gst-plugin-scanner" % options.builddir)
|
||||||
env["GST_PTP_HELPER"] = os.path.normpath(
|
env["GST_PTP_HELPER"] = os.path.normpath(
|
||||||
"%s/subprojects/gstreamer/libs/gst/helpers/gst-ptp-helper" % options.builddir)
|
"%s/subprojects/gstreamer/libs/gst/helpers/gst-ptp-helper" % options.builddir)
|
||||||
env["GST_REGISTRY"] = os.path.normpath(options.builddir + "/registry.dat")
|
|
||||||
|
|
||||||
if os.name is 'nt':
|
if os.name is 'nt':
|
||||||
lib_path_envvar = 'PATH'
|
lib_path_envvar = 'PATH'
|
||||||
|
@ -285,6 +310,12 @@ if __name__ == "__main__":
|
||||||
parser.add_argument("--sysroot",
|
parser.add_argument("--sysroot",
|
||||||
default='',
|
default='',
|
||||||
help="The sysroot path used during cross-compilation")
|
help="The sysroot path used during cross-compilation")
|
||||||
|
parser.add_argument("--wine",
|
||||||
|
default='',
|
||||||
|
help="Build a wine env based on specified wine command")
|
||||||
|
parser.add_argument("--winepath",
|
||||||
|
default='',
|
||||||
|
help="Exra path to set to WINEPATH.")
|
||||||
options, args = parser.parse_known_args()
|
options, args = parser.parse_known_args()
|
||||||
|
|
||||||
if not os.path.exists(options.builddir):
|
if not os.path.exists(options.builddir):
|
||||||
|
@ -302,6 +333,9 @@ if __name__ == "__main__":
|
||||||
gst_version = git("rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD",
|
gst_version = git("rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD",
|
||||||
repository_path=options.srcdir).strip('\n')
|
repository_path=options.srcdir).strip('\n')
|
||||||
|
|
||||||
|
if options.wine:
|
||||||
|
gst_version += '-' + os.path.basename(options.wine)
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
if os.name is 'nt':
|
if os.name is 'nt':
|
||||||
shell = get_windows_shell()
|
shell = get_windows_shell()
|
||||||
|
|
1
gst-uninstalled.py
Symbolic link
1
gst-uninstalled.py
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
gst-env.py
|
10
meson.build
10
meson.build
|
@ -172,6 +172,16 @@ setenv = find_program('gst-env.py')
|
||||||
devenv_cmd = [setenv, '--builddir=@0@'.format(meson.build_root()),
|
devenv_cmd = [setenv, '--builddir=@0@'.format(meson.build_root()),
|
||||||
'--srcdir=@0@'.format(meson.source_root())]
|
'--srcdir=@0@'.format(meson.source_root())]
|
||||||
|
|
||||||
|
if meson.has_exe_wrapper() and build_machine.system() == 'linux' and host_machine.system() == 'windows'
|
||||||
|
# FIXME: Ideally we could get the wrapper directly from meson
|
||||||
|
devenv_cmd += ['--wine', host_machine.cpu_family() == 'x86_64' ? 'wine64' : 'wine32']
|
||||||
|
sysroot = meson.get_cross_property('sys_root')
|
||||||
|
if sysroot != ''
|
||||||
|
# Logic from meson
|
||||||
|
devenv_cmd += ['--winepath', 'Z:' + join_paths(sysroot, 'bin')]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
run_target('uninstalled', command : devenv_cmd)
|
run_target('uninstalled', command : devenv_cmd)
|
||||||
run_target('devenv', command : devenv_cmd)
|
run_target('devenv', command : devenv_cmd)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import shutil
|
||||||
import argparse
|
import argparse
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
@ -31,6 +32,33 @@ def win32_get_short_path_name(long_name):
|
||||||
else:
|
else:
|
||||||
output_buf_size = needed
|
output_buf_size = needed
|
||||||
|
|
||||||
|
|
||||||
|
def get_wine_shortpath(winecmd, wine_paths):
|
||||||
|
seen = set()
|
||||||
|
wine_paths += [p for p in wine_paths if not (p in seen or seen.add(p))]
|
||||||
|
|
||||||
|
getShortPathScript = '%s.bat' % str(uuid.uuid4()).lower()[:5]
|
||||||
|
with open(getShortPathScript, mode='w') as f:
|
||||||
|
f.write("@ECHO OFF\nfor %%x in (%*) do (\n echo|set /p=;%~sx\n)\n")
|
||||||
|
f.flush()
|
||||||
|
try:
|
||||||
|
with open(os.devnull, 'w') as stderr:
|
||||||
|
wine_path = subprocess.check_output(
|
||||||
|
winecmd +
|
||||||
|
['cmd', '/C', getShortPathScript] + wine_paths,
|
||||||
|
stderr=stderr).decode('utf-8')
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print("Could not get short paths: %s" % e)
|
||||||
|
wine_path = ';'.join(wine_paths)
|
||||||
|
finally:
|
||||||
|
os.remove(getShortPathScript)
|
||||||
|
if len(wine_path) > 2048:
|
||||||
|
raise AssertionError('WINEPATH size {} > 2048'
|
||||||
|
' this will cause random failure.'.format(
|
||||||
|
len(wine_path)))
|
||||||
|
return wine_path
|
||||||
|
|
||||||
|
|
||||||
class Colors:
|
class Colors:
|
||||||
HEADER = '\033[95m'
|
HEADER = '\033[95m'
|
||||||
OKBLUE = '\033[94m'
|
OKBLUE = '\033[94m'
|
||||||
|
|
Loading…
Reference in a new issue