mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
Add a script to setup a developement environment based on msys2
This environment is meant to be setup in a Visual Studio 'Native X64 tools' terminal, and takes for granted that msys2 has been installed, Visual Studio has C(++) support has been installed and python3 is installed and is present in PATH. https://bugzilla.gnome.org/show_bug.cgi?id=775281
This commit is contained in:
parent
954c27641d
commit
1c46eb2751
4 changed files with 252 additions and 68 deletions
|
@ -8,6 +8,7 @@ import re
|
||||||
import site
|
import site
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from common import get_meson
|
from common import get_meson
|
||||||
|
@ -73,7 +74,7 @@ def get_subprocess_env(options):
|
||||||
lib_path_envvar = 'LD_LIBRARY_PATH'
|
lib_path_envvar = 'LD_LIBRARY_PATH'
|
||||||
|
|
||||||
meson, mesonconf, mesonintrospect = get_meson()
|
meson, mesonconf, mesonintrospect = get_meson()
|
||||||
targets_s = subprocess.check_output([mesonintrospect, options.builddir, '--targets'])
|
targets_s = subprocess.check_output([sys.executable, mesonintrospect, options.builddir, '--targets'])
|
||||||
targets = json.loads(targets_s.decode())
|
targets = json.loads(targets_s.decode())
|
||||||
for target in targets:
|
for target in targets:
|
||||||
filename = target['filename']
|
filename = target['filename']
|
||||||
|
@ -85,7 +86,7 @@ def get_subprocess_env(options):
|
||||||
if target.get('type') != "shared library":
|
if target.get('type') != "shared library":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if "lib/gstreamer-1.0" in os.path.normpath(target.get('install_filename')):
|
if os.path.normpath("lib/gstreamer-1.0") in os.path.normpath(target.get('install_filename')):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
prepend_env_var(env, lib_path_envvar,
|
prepend_env_var(env, lib_path_envvar,
|
||||||
|
|
172
msys2_setup.py
Normal file
172
msys2_setup.py
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Setup meson based GStreamer uninstalled environment based on msys2."""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import itertools
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
from common import git
|
||||||
|
from setup import GstBuildConfigurer
|
||||||
|
|
||||||
|
|
||||||
|
PROJECTNAME = "GStreamer build"
|
||||||
|
|
||||||
|
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
class Msys2Configurer(GstBuildConfigurer):
|
||||||
|
MESON_GIT = 'https://github.com/mesonbuild/meson.git'
|
||||||
|
DEPENDENCIES = ['git',
|
||||||
|
'bison',
|
||||||
|
'mingw-w64-x86_64-pkg-config',
|
||||||
|
'mingw-w64-x86_64-ninja',
|
||||||
|
'mingw-w64-x86_64-libxml2',
|
||||||
|
'mingw-w64-x86_64-ffmpeg',
|
||||||
|
'mingw-w64-x86_64-python3',
|
||||||
|
'mingw-w64-x86_64-json-glib']
|
||||||
|
LIBNAME_EXCEPTIONS = {
|
||||||
|
'zlib1.lib': 'z.lib',
|
||||||
|
# Fancy, but it seems to be the correct way to do it
|
||||||
|
'eay32.lib': 'crypto.lib',
|
||||||
|
'ssleay32.lib': 'ssl.lib',
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_libname(self, dll_name):
|
||||||
|
lib_name = re.sub(r'(?:lib)?(.*?)(?:-\d+)?\.dll', r'\1.lib', dll_name)
|
||||||
|
|
||||||
|
for exception_name, exception_libname in self.LIBNAME_EXCEPTIONS.items():
|
||||||
|
if re.findall(exception_name, lib_name):
|
||||||
|
return exception_libname
|
||||||
|
return lib_name
|
||||||
|
|
||||||
|
def make_lib(self, lib, dll, dll_name):
|
||||||
|
print('%s... ' % os.path.basename(lib), end='')
|
||||||
|
try:
|
||||||
|
os.remove(lib)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
dumpbin = subprocess.check_output(['dumpbin', '/exports', dll])
|
||||||
|
lines = dumpbin.decode().splitlines()
|
||||||
|
export_start = [i for i in enumerate(
|
||||||
|
lines) if i[1].find('ordinal hint') != -1][0][0] + 2
|
||||||
|
exports = itertools.takewhile(lambda x: x != '', lines[export_start:])
|
||||||
|
exports = [i.split() for i in exports]
|
||||||
|
def_file = tempfile.NamedTemporaryFile(
|
||||||
|
suffix='.def', delete=False, mode='w')
|
||||||
|
def_file.write('LIBRARY ' + dll_name + '\r\n')
|
||||||
|
def_file.write('EXPORTS\r\n')
|
||||||
|
for ordinal, _, _, name in exports:
|
||||||
|
def_file.write(name + ' @' + ordinal + '\r\n')
|
||||||
|
def_file.close()
|
||||||
|
subprocess.check_output(['lib', '/def:' + def_file.name,
|
||||||
|
'/out:' + lib])
|
||||||
|
os.remove(def_file.name)
|
||||||
|
|
||||||
|
def make_lib_if_needed(self, dll):
|
||||||
|
if not dll.endswith('.dll'):
|
||||||
|
return
|
||||||
|
|
||||||
|
lib_dir, dll_name = os.path.split(dll)
|
||||||
|
if lib_dir.endswith('bin'):
|
||||||
|
lib_dir = lib_dir[:-3] + 'lib'
|
||||||
|
|
||||||
|
lib_name = self.get_libname(dll_name)
|
||||||
|
lib = os.path.join(lib_dir, lib_name)
|
||||||
|
if os.path.exists(lib) and os.stat(dll).st_mtime_ns < os.stat(lib).st_mtime_ns:
|
||||||
|
return
|
||||||
|
|
||||||
|
print('Generating .lib file for %s ...' % os.path.basename(dll), end='')
|
||||||
|
self.make_lib(lib, dll, dll_name)
|
||||||
|
print('DONE')
|
||||||
|
|
||||||
|
def make_libs(self):
|
||||||
|
base = os.path.join(self.options.msys2_path, 'mingw64', 'bin')
|
||||||
|
for f in os.listdir(base):
|
||||||
|
if f.endswith('.dll'):
|
||||||
|
self.make_lib_if_needed(os.path.join(base, f))
|
||||||
|
|
||||||
|
def get_configs(self):
|
||||||
|
return GstBuildConfigurer.get_configs(self) + [
|
||||||
|
'-D' + m + ':disable_introspection=true' for m in [
|
||||||
|
'gst-devtools', 'gstreamer', 'gst-plugins-base',
|
||||||
|
'gst-editing-services']]
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
if not os.path.exists(self.options.msys2_path):
|
||||||
|
print("msys2 not found in %s. Please make sure to install"
|
||||||
|
" (from http://msys2.github.io/) specify --msys2-path"
|
||||||
|
" if you did not install in the default directory.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
for path in ['mingw64/bin', 'bin', 'usr/bin']:
|
||||||
|
os.environ['PATH'] = os.environ.get(
|
||||||
|
'PATH', '') + os.pathsep + os.path.normpath(os.path.join(self.options.msys2_path, path))
|
||||||
|
os.environ['PATH'] = os.environ['PATH'].replace(';;', ';')
|
||||||
|
os.environ['PKG_CONFIG_PATH'] = os.environ.get(
|
||||||
|
'PKG_CONFIG_PATH', '') + ':/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig'
|
||||||
|
|
||||||
|
subprocess.check_call(
|
||||||
|
['pacman', '-S', '--needed'] + self.DEPENDENCIES, env=os.environ)
|
||||||
|
source_path = os.path.abspath(os.path.curdir)
|
||||||
|
|
||||||
|
print('Making sure meson is present in root folder... ', end='')
|
||||||
|
if not os.path.isdir(os.path.join(source_path, 'meson')):
|
||||||
|
print('\nCloning meson')
|
||||||
|
git('clone', self.MESON_GIT, repository_path=source_path)
|
||||||
|
else:
|
||||||
|
print('\nDONE')
|
||||||
|
|
||||||
|
print("Making libs")
|
||||||
|
self.make_libs()
|
||||||
|
if not os.path.exists(os.path.join(source_path, 'build', 'build.ninja')) or \
|
||||||
|
self.options.reconfigure:
|
||||||
|
print("Done making .lib files.")
|
||||||
|
print("Running meson")
|
||||||
|
if not self.configure_meson():
|
||||||
|
return False
|
||||||
|
|
||||||
|
print("Getting into msys2 environment")
|
||||||
|
try:
|
||||||
|
subprocess.call([sys.executable,
|
||||||
|
os.path.join(source_path, 'gst-uninstalled.py'),
|
||||||
|
'--builddir', os.path.join(source_path, 'build')])
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description='Process some integers.')
|
||||||
|
parser.add_argument("--reconfigure", action='store_true',
|
||||||
|
default=False, help='Force a full reconfiguration'
|
||||||
|
' meaning the build/ folder is removed.'
|
||||||
|
' You can also use `ninja reconfigure` to just'
|
||||||
|
' make sure meson is rerun but the build folder'
|
||||||
|
' is kept.')
|
||||||
|
if os.name != 'nt':
|
||||||
|
print("Using this script outside windows does not make sense.")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
parser.add_argument("-m", "--msys2-path", dest="msys2_path",
|
||||||
|
help="Where to find msys2 root directory."
|
||||||
|
"(deactivates msys if unset)",
|
||||||
|
default="C:\msys64")
|
||||||
|
options, args = parser.parse_known_args()
|
||||||
|
|
||||||
|
if not shutil.which('cl'):
|
||||||
|
print("Can not find MSVC on windows,"
|
||||||
|
" make sure you are in a 'Visual Studio"
|
||||||
|
" Native Tools Command Prompt'")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
configurer = Msys2Configurer(options, args)
|
||||||
|
|
||||||
|
exit(not configurer.setup())
|
||||||
|
|
66
setup
66
setup
|
@ -1,66 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
"""Script for generating the Makefiles."""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from common import git
|
|
||||||
from common import get_meson
|
|
||||||
from common import Colors
|
|
||||||
from common import accept_command
|
|
||||||
|
|
||||||
|
|
||||||
PROJECTNAME = "GStreamer build"
|
|
||||||
|
|
||||||
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
|
|
||||||
|
|
||||||
def get_configs():
|
|
||||||
return ['--werror']
|
|
||||||
|
|
||||||
|
|
||||||
def configure_meson(args, options):
|
|
||||||
"""Configures meson and generate the Makefile."""
|
|
||||||
meson, mesonconf, mesonintrospect = get_meson()
|
|
||||||
if not meson:
|
|
||||||
print("Install mesonbuild to build %s: http://mesonbuild.com/\n"
|
|
||||||
"You can simply install it with:\n"
|
|
||||||
" $ sudo pip3 install meson" % PROJECTNAME)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
ninja = accept_command(["ninja", "ninja-build"])
|
|
||||||
if not ninja:
|
|
||||||
print("Install ninja-build to build %s: https://ninja-build.org/"
|
|
||||||
% PROJECTNAME)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
build_dir = os.path.join(ROOTDIR, "build")
|
|
||||||
shutil.rmtree(build_dir, True)
|
|
||||||
os.mkdir(build_dir)
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_call([sys.executable, meson, "../"] + args + get_configs(), cwd=build_dir)
|
|
||||||
print("\nYou can now build GStreamer and its various subprojects running:\n"
|
|
||||||
" $ ninja -C %s" % build_dir)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print("EXIT meson return %s" % e.returncode)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(description='Process some integers.')
|
|
||||||
parser.add_argument("--no-reconfigure", action='store_true',
|
|
||||||
default=False, help='Avoid removing the build dir'
|
|
||||||
' if not necessary.')
|
|
||||||
options, args = parser.parse_known_args()
|
|
||||||
if options.no_reconfigure:
|
|
||||||
if os.path.exists(
|
|
||||||
ROOTDIR + "/build/build.ninja") and os.path.exists(
|
|
||||||
ROOTDIR + "/Makefile"):
|
|
||||||
print("Not reconfiguring")
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
configure_meson(args, options)
|
|
77
setup.py
Executable file
77
setup.py
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Script for generating the Makefiles."""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from common import get_meson
|
||||||
|
from common import accept_command
|
||||||
|
|
||||||
|
|
||||||
|
PROJECTNAME = "GStreamer build"
|
||||||
|
|
||||||
|
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
class GstBuildConfigurer:
|
||||||
|
|
||||||
|
def __init__(self, options, args):
|
||||||
|
self.options = options
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
def get_configs(self):
|
||||||
|
return ['--werror']
|
||||||
|
|
||||||
|
def configure_meson(self):
|
||||||
|
if not self.options.reconfigure:
|
||||||
|
if os.path.exists(ROOTDIR + "/build/build.ninja"):
|
||||||
|
print("Not reconfiguring")
|
||||||
|
return True
|
||||||
|
|
||||||
|
meson, mesonconf, mesonintrospect = get_meson()
|
||||||
|
if not meson:
|
||||||
|
print("Install mesonbuild to build %s: http://mesonbuild.com/\n"
|
||||||
|
"You can simply install it with:\n"
|
||||||
|
" $ sudo pip3 install meson" % PROJECTNAME)
|
||||||
|
return False
|
||||||
|
|
||||||
|
ninja = accept_command(["ninja", "ninja-build"])
|
||||||
|
if not ninja:
|
||||||
|
print("Install ninja-build to build %s: https://ninja-build.org/"
|
||||||
|
% PROJECTNAME)
|
||||||
|
return False
|
||||||
|
|
||||||
|
build_dir = os.path.join(ROOTDIR, "build")
|
||||||
|
shutil.rmtree(build_dir, True)
|
||||||
|
os.mkdir(build_dir)
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.check_call(
|
||||||
|
[sys.executable, meson, "../"] + self.args + self.get_configs(), cwd=build_dir)
|
||||||
|
print("\nYou can now build GStreamer and its various subprojects running:\n"
|
||||||
|
" $ ninja -C %s" % build_dir)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
return self.configure_meson()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description='Process some integers.')
|
||||||
|
parser.add_argument("--reconfigure", action='store_true',
|
||||||
|
default=False, help='Force a full reconfiguration'
|
||||||
|
' meaning the build/ folder is removed.'
|
||||||
|
' You can also use `ninja reconfigure` to just'
|
||||||
|
' make sure meson is rerun but the build folder'
|
||||||
|
' is kept.')
|
||||||
|
|
||||||
|
options, args = parser.parse_known_args()
|
||||||
|
configurer = GstBuildConfigurer(options, args)
|
||||||
|
exit(not configurer.setup())
|
Loading…
Reference in a new issue