aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Generating-sources.md2
-rw-r--r--docs/markdown/Release-notes-for-0.45.0.md31
-rw-r--r--docs/markdown/snippets/improved-meson-init.md19
-rw-r--r--mesonbuild/minit.py130
-rwxr-xr-xrun_unittests.py3
5 files changed, 162 insertions, 23 deletions
diff --git a/docs/markdown/Generating-sources.md b/docs/markdown/Generating-sources.md
index 1c3225b..cbe6c0d 100644
--- a/docs/markdown/Generating-sources.md
+++ b/docs/markdown/Generating-sources.md
@@ -127,7 +127,7 @@ argument list as separate elements.
gen3 = generator(genprog,
output : '@BASENAME@.cc',
arguments : ['@INPUT@', '@EXTRA_ARGS@', '@OUTPUT@'])
-gen3_src1 = gen3.process('input1.y)
+gen3_src1 = gen3.process('input1.y')
gen3_src2 = gen3.process('input2.y', extra_args: '--foo')
gen3_src3 = gen3.process('input3.y', extra_args: ['--foo', '--bar'])
```
diff --git a/docs/markdown/Release-notes-for-0.45.0.md b/docs/markdown/Release-notes-for-0.45.0.md
index 23bff93..6b24183 100644
--- a/docs/markdown/Release-notes-for-0.45.0.md
+++ b/docs/markdown/Release-notes-for-0.45.0.md
@@ -5,13 +5,18 @@ short-description: Release notes for 0.45
# New features
+## Python minimum version is now 3.5
+
+Meson will from this version on require Python version 3.5 or newer.
+
## Config-Tool based dependencies can be specified in a cross file
-Tools like LLVM and pcap use a config tool for dependencies, this is a script
-or binary that is run to get configuration information (cflags, ldflags, etc)
-from.
+Tools like LLVM and pcap use a config tool for dependencies, this is a
+script or binary that is run to get configuration information (cflags,
+ldflags, etc) from.
-These binaries may now be specified in the `binaries` section of a cross file.
+These binaries may now be specified in the `binaries` section of a
+cross file.
```dosini
[binaries]
@@ -109,8 +114,8 @@ values. It can be specified like this in the `meson_options.txt` file:
## New method meson.project_license()
-The `meson` builtin object now has a `project_license()` method that returns a
-list of all licenses for the project.
+The `meson` builtin object now has a `project_license()` method that
+returns a list of all licenses for the project.
## Rust cross-compilation
@@ -147,10 +152,10 @@ meson init --name=myproject --type=executable --language=c
## Improve test setup selection
-Test setups are now identified (also) by the project they belong to and it
-is possible to select the used test setup from a specific project. E.g.
-to use a test setup `some_setup` from project `some_project` for all
-executed tests one can use
+Test setups are now identified (also) by the project they belong to
+and it is possible to select the used test setup from a specific
+project. E.g. to use a test setup `some_setup` from project
+`some_project` for all executed tests one can use
meson test --setup some_project:some_setup
@@ -171,9 +176,11 @@ The `promote` command makes it easy to copy nested dependencies to the top level
meson wrap promote scommon
-This will search the project tree for a subproject called `scommon` and copy it to the top level.
+This will search the project tree for a subproject called `scommon`
+and copy it to the top level.
-If there are many embedded subprojects with the same name, you have to specify which one to promote manually like this:
+If there are many embedded subprojects with the same name, you have to
+specify which one to promote manually like this:
meson wrap promote subprojects/s1/subprojects/scommon
diff --git a/docs/markdown/snippets/improved-meson-init.md b/docs/markdown/snippets/improved-meson-init.md
new file mode 100644
index 0000000..ec17bc4
--- /dev/null
+++ b/docs/markdown/snippets/improved-meson-init.md
@@ -0,0 +1,19 @@
+## Autogeneration of simple meson.build files
+
+A feature to generate a meson.build file compiling given C/C++ source
+files into a single executable has been added to "meson init". By
+default, it will take all recognizable source files in the current
+directory. You can also specify a list of dependencies with the -d
+flag and automatically invoke a build with the -b flag to check if the
+code builds with those dependencies.
+
+For example,
+
+```meson
+meson init -fbd sdl2,gl
+```
+
+will look for C or C++ files in the current directory, generate a
+meson.build for them with the dependencies of sdl2 and gl and
+immediately try to build it, overwriting any previous meson.build and
+build directory.
diff --git a/mesonbuild/minit.py b/mesonbuild/minit.py
index 4459a05..0461cd9 100644
--- a/mesonbuild/minit.py
+++ b/mesonbuild/minit.py
@@ -14,8 +14,10 @@
"""Code that creates simple startup projects."""
-import sys, argparse, re
+import os, sys, argparse, re, shutil
from glob import glob
+from mesonbuild import mesonlib
+from mesonbuild.environment import detect_ninja
lib_h_template = '''#pragma once
#if defined _WIN32 || defined __CYGWIN__
@@ -122,8 +124,7 @@ int main(int argc, char **argv) {{
hello_c_meson_template = '''project('{project_name}', 'c',
version : '{version}',
- default_options : ['warning_level=3',
- 'cpp_std=c++14'])
+ default_options : ['warning_level=3'])
exe = executable('{exe_name}', '{source_name}',
install : true)
@@ -147,7 +148,8 @@ int main(int argc, char **argv) {{
hello_cpp_meson_template = '''project('{project_name}', 'cpp',
version : '{version}',
- default_options : ['warning_level=3'])
+ default_options : ['warning_level=3',
+ 'cpp_std=c++14'])
exe = executable('{exe_name}', '{source_name}',
install : true)
@@ -356,15 +358,123 @@ def create_sample(options):
raise RuntimeError('Unreachable code')
print(info_message)
+def autodetect_options(options, sample=False):
+ if not options.name:
+ options.name = os.path.basename(os.getcwd())
+ if not re.match('[a-zA-Z_][a-zA-Z0-9]*', options.name) and sample:
+ print('Name of current directory "{}" is not usable as a sample project name.\n'
+ 'Specify a project name with --name.'.format(options.name))
+ sys.exit(1)
+ print('Using "{}" (name of current directory) as project name.'
+ .format(options.name))
+ if not options.executable:
+ options.executable = options.name
+ print('Using "{}" (project name) as name of executable to build.'
+ .format(options.executable))
+ if sample:
+ # The rest of the autodetection is not applicable to generating sample projects.
+ return
+ if not options.srcfiles:
+ srcfiles = []
+ for f in os.listdir():
+ if f.endswith('.cc') or f.endswith('.cpp') or f.endswith('.c'):
+ srcfiles.append(f)
+ if not srcfiles:
+ print("No recognizable source files found.\n"
+ "Run me in an empty directory to create a sample project.")
+ sys.exit(1)
+ options.srcfiles = srcfiles
+ print("Detected source files: " + ' '.join(srcfiles))
+ if not options.language:
+ for f in options.srcfiles:
+ if f.endswith('.cc') or f.endswith('.cpp'):
+ options.language = 'cpp'
+ break
+ if f.endswith('.c'):
+ options.language = 'c'
+ break
+ if not options.language:
+ print("Can't autodetect language, please specify it with -l.")
+ sys.exit(1)
+ print("Detected language: " + options.language)
+
+meson_executable_template = '''project('{project_name}', '{language}',
+ version : '{version}',
+ default_options : [{default_options}])
+
+executable('{executable}',
+ {sourcespec},{depspec}
+ install : true)
+'''
+
+def create_meson_build(options):
+ if options.type != 'executable':
+ print('\nGenerating a meson.build file from existing sources is\n'
+ 'supported only for project type "executable".\n'
+ 'Run me in an empty directory to create a sample project.')
+ sys.exit(1)
+ default_options = ['warning_level=3']
+ if options.language == 'cpp':
+ # This shows how to set this very common option.
+ default_options += ['cpp_std=c++14']
+ # If we get a meson.build autoformatter one day, this code could
+ # be simplified quite a bit.
+ formatted_default_options = ', '.join("'{}'".format(x) for x in default_options)
+ sourcespec = ',\n '.join("'{}'".format(x) for x in options.srcfiles)
+ depspec = ''
+ if options.deps:
+ depspec = '\n dependencies : [\n '
+ depspec += ',\n '.join("dependency('{}')".format(x)
+ for x in options.deps.split(','))
+ depspec += '],'
+ content = meson_executable_template.format(project_name=options.name,
+ language=options.language,
+ version=options.version,
+ executable=options.executable,
+ sourcespec=sourcespec,
+ depspec=depspec,
+ default_options=formatted_default_options)
+ open('meson.build', 'w').write(content)
+ print('Generated meson.build file:\n\n' + content)
+
def run(args):
parser = argparse.ArgumentParser(prog='meson')
- parser.add_argument('--name', default = 'mesonsample')
+ parser.add_argument("srcfiles", metavar="sourcefile", nargs="*",
+ help="source files. default: all recognized files in current directory")
+ parser.add_argument("-n", "--name", help="project name. default: name of current directory")
+ parser.add_argument("-e", "--executable", help="executable name. default: project name")
+ parser.add_argument("-d", "--deps", help="dependencies, comma-separated")
+ parser.add_argument("-l", "--language", choices=['c', 'cpp'],
+ help="project language. default: autodetected based on source files")
+ parser.add_argument("-b", "--build", help="build after generation", action='store_true')
+ parser.add_argument("--builddir", help="directory for build", default='build')
+ parser.add_argument("-f", "--force", action="store_true",
+ help="force overwrite of existing files and directories.")
parser.add_argument('--type', default='executable',
choices=['executable', 'library'])
- parser.add_argument('--language', default='c', choices=['c', 'cpp'])
- parser.add_argument('--version', default='1.0')
+ parser.add_argument('--version', default='0.1')
options = parser.parse_args(args)
- if len(glob('*')) != 0:
- sys.exit('This command must be run in an empty directory.')
- create_sample(options)
+ if len(glob('*')) == 0:
+ autodetect_options(options, sample=True)
+ if not options.language:
+ print('Defaulting to generating a C language project.')
+ options.language = 'c'
+ create_sample(options)
+ else:
+ autodetect_options(options)
+ if os.path.isfile('meson.build') and not options.force:
+ print('meson.build already exists. Use --force to overwrite.')
+ sys.exit(1)
+ create_meson_build(options)
+ if options.build:
+ if os.path.isdir(options.builddir) and options.force:
+ print('Build directory already exists, deleting it.')
+ shutil.rmtree(options.builddir)
+ print('Building...')
+ err = os.system('{} "{}"'.format(' '.join(mesonlib.meson_command), options.builddir))
+ if err:
+ sys.exit(1)
+ err = os.system('{} -C "{}"'.format(detect_ninja(), options.builddir))
+ if err:
+ sys.exit(1)
return 0
diff --git a/run_unittests.py b/run_unittests.py
index 0a55ac1..8f69077 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1780,6 +1780,9 @@ int main(int argc, char **argv) {
workdir=tmpdir)
self._run(ninja,
workdir=os.path.join(tmpdir, 'builddir'))
+ with tempfile.TemporaryDirectory() as tmpdir:
+ open(os.path.join(tmpdir, 'foo.' + lang), 'w').write('int main() {}')
+ self._run(meson_command + ['init', '-b'], workdir=tmpdir)
# The test uses mocking and thus requires that
# the current process is the one to run the Meson steps.