parent
567c96b68b
commit
598e968993
17 changed files with 277 additions and 8 deletions
@ -0,0 +1,29 @@ |
||||
## Developer environment |
||||
|
||||
New method `meson.add_devenv()` adds an [`environment()`](#environment) object |
||||
to the list of environments that will be applied when using `meson devenv` |
||||
command line. This is useful for developpers who wish to use the project without |
||||
installing it, it is often needed to set for example the path to plugins |
||||
directory, etc. Alternatively, a list or dictionary can be passed as first |
||||
argument. |
||||
|
||||
``` meson |
||||
devenv = environment() |
||||
devenv.set('PLUGINS_PATH', meson.current_build_dir()) |
||||
... |
||||
meson.add_devenv(devenv) |
||||
``` |
||||
|
||||
New command line has been added: `meson devenv -C builddir [<command>]`. |
||||
It runs a command, or open interactive shell if no command is provided, with |
||||
environment setup to run project from the build directory, without installation. |
||||
|
||||
These variables are set in environment in addition to those set using `meson.add_devenv()`: |
||||
- `MESON_DEVENV` is defined to `'1'`. |
||||
- `MESON_PROJECT_NAME` is defined to the main project's name. |
||||
- `PKG_CONFIG_PATH` includes the directory where Meson generates `-uninstalled.pc` |
||||
files. |
||||
- `PATH` includes every directory where there is an executable that would be |
||||
installed into `bindir`. On windows it also includes every directory where there |
||||
is a DLL needed to run those executables. |
||||
|
@ -0,0 +1,79 @@ |
||||
import os, subprocess |
||||
import argparse |
||||
import tempfile |
||||
|
||||
from pathlib import Path |
||||
from . import build |
||||
from .mesonlib import MesonException, is_windows |
||||
|
||||
import typing as T |
||||
|
||||
def add_arguments(parser: argparse.ArgumentParser) -> None: |
||||
parser.add_argument('-C', default='.', dest='wd', |
||||
help='directory to cd into before running') |
||||
parser.add_argument('command', nargs=argparse.REMAINDER, |
||||
help='Command to run in developer environment (default: interactive shell)') |
||||
|
||||
def get_windows_shell() -> str: |
||||
mesonbuild = Path(__file__).parent |
||||
script = mesonbuild / 'scripts' / 'cmd_or_ps.ps1' |
||||
command = ['powershell.exe', '-noprofile', '-executionpolicy', 'bypass', '-file', str(script)] |
||||
result = subprocess.check_output(command) |
||||
return result.decode().strip() |
||||
|
||||
def get_env(b: build.Build, build_dir: str) -> T.Dict[str, str]: |
||||
env = os.environ.copy() |
||||
for i in b.devenv: |
||||
env = i.get_env(env) |
||||
|
||||
extra_env = build.EnvironmentVariables() |
||||
extra_env.set('MESON_DEVENV', ['1']) |
||||
extra_env.set('MESON_PROJECT_NAME', [b.project_name]) |
||||
|
||||
meson_uninstalled = Path(build_dir) / 'meson-uninstalled' |
||||
if meson_uninstalled.is_dir(): |
||||
extra_env.prepend('PKG_CONFIG_PATH', [str(meson_uninstalled)]) |
||||
|
||||
return extra_env.get_env(env) |
||||
|
||||
def run(options: argparse.Namespace) -> int: |
||||
options.wd = os.path.abspath(options.wd) |
||||
buildfile = Path(options.wd) / 'meson-private' / 'build.dat' |
||||
if not buildfile.is_file(): |
||||
raise MesonException(f'Directory {options.wd!r} does not seem to be a Meson build directory.') |
||||
b = build.load(options.wd) |
||||
|
||||
devenv = get_env(b, options.wd) |
||||
|
||||
args = options.command |
||||
if not args: |
||||
prompt_prefix = f'[{b.project_name}]' |
||||
if is_windows(): |
||||
shell = get_windows_shell() |
||||
if shell == 'powershell.exe': |
||||
args = ['powershell.exe'] |
||||
args += ['-NoLogo', '-NoExit'] |
||||
prompt = f'function global:prompt {{ "{prompt_prefix} PS " + $PWD + "> "}}' |
||||
args += ['-Command', prompt] |
||||
else: |
||||
args = [os.environ.get("COMSPEC", r"C:\WINDOWS\system32\cmd.exe")] |
||||
args += ['/k', f'prompt {prompt_prefix} $P$G'] |
||||
else: |
||||
args = [os.environ.get("SHELL", os.path.realpath("/bin/sh"))] |
||||
if "bash" in args[0] and not os.environ.get("MESON_DISABLE_PS1_OVERRIDE"): |
||||
tmprc = tempfile.NamedTemporaryFile(mode='w') |
||||
bashrc = os.path.expanduser('~/.bashrc') |
||||
if os.path.exists(bashrc): |
||||
tmprc.write(f'. {bashrc}\n') |
||||
tmprc.write(f'export PS1="{prompt_prefix} $PS1"') |
||||
tmprc.flush() |
||||
# Let the GC remove the tmp file |
||||
args.append("--rcfile") |
||||
args.append(tmprc.name) |
||||
|
||||
try: |
||||
return subprocess.call(args, close_fds=False, |
||||
env=devenv, |
||||
cwd=options.wd) |
||||
except subprocess.CalledProcessError as e: |
||||
return e.returncode |
@ -0,0 +1,22 @@ |
||||
# Copyied from GStreamer project |
||||
# Author: Seungha Yang <seungha.yang@navercorp.com> |
||||
|
||||
$i=1 |
||||
$ppid=(gwmi win32_process -Filter "processid='$pid'").parentprocessid |
||||
$pname=(Get-Process -id $ppid).Name |
||||
While($true) { |
||||
if($pname -eq "cmd" -Or $pname -eq "powershell") { |
||||
Write-Host ("{0}.exe" -f $pname) |
||||
Break |
||||
} |
||||
|
||||
# 10 times iteration seems to be sufficient |
||||
if($i -gt 10) { |
||||
Break |
||||
} |
||||
|
||||
# not found yet, find grand parant |
||||
$ppid=(gwmi win32_process -Filter "processid='$ppid'").parentprocessid |
||||
$pname=(Get-Process -id $ppid).Name |
||||
$i++ |
||||
} |
@ -0,0 +1,14 @@ |
||||
#include <stdio.h> |
||||
|
||||
#ifdef _WIN32 |
||||
#define DO_IMPORT __declspec(dllimport) |
||||
#else |
||||
#define DO_IMPORT |
||||
#endif |
||||
|
||||
DO_IMPORT int foo(void); |
||||
|
||||
int main(void) { |
||||
printf("This is text.\n"); |
||||
return foo(); |
||||
} |
@ -0,0 +1,12 @@ |
||||
project('devenv', 'c') |
||||
|
||||
meson.add_devenv('TEST_A=1') |
||||
foo_dep = dependency('foo', fallback: 'sub') |
||||
|
||||
env = environment() |
||||
env.append('TEST_B', ['2', '3'], separator: '+') |
||||
meson.add_devenv(env) |
||||
|
||||
# This exe links on a library built in another directory. On Windows this means |
||||
# PATH must contain builddir/subprojects/sub to be able to run it. |
||||
executable('app', 'main.c', dependencies: foo_dep, install: true) |
@ -0,0 +1,10 @@ |
||||
#ifdef _WIN32 |
||||
#define DO_EXPORT __declspec(dllexport) |
||||
#else |
||||
#define DO_EXPORT |
||||
#endif |
||||
|
||||
DO_EXPORT int foo(void) |
||||
{ |
||||
return 0; |
||||
} |
@ -0,0 +1,6 @@ |
||||
project('sub', 'c') |
||||
|
||||
meson.add_devenv({'TEST_B': '1'}) |
||||
|
||||
libfoo = shared_library('foo', 'foo.c') |
||||
meson.override_dependency('foo', declare_dependency(link_with: libfoo)) |
@ -0,0 +1,8 @@ |
||||
#! /usr/bin/python |
||||
|
||||
import os |
||||
|
||||
assert(os.environ['MESON_DEVENV'] == '1') |
||||
assert(os.environ['MESON_PROJECT_NAME'] == 'devenv') |
||||
assert(os.environ['TEST_A'] == '1') |
||||
assert(os.environ['TEST_B'] == '1+2+3') |
Loading…
Reference in new issue