aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--authors.txt1
-rw-r--r--build.py15
-rw-r--r--interpreter.py50
-rw-r--r--manual tests/4 standalone binaries/meson.build8
-rw-r--r--ninjabackend.py26
-rwxr-xr-xrustrunner.py64
-rw-r--r--test cases/common/1 trivial/meson.build2
-rw-r--r--test cases/common/17 if/meson.build16
-rw-r--r--test cases/common/42 string formatting/meson.build20
-rw-r--r--test cases/common/93 private include/meson.build4
-rwxr-xr-xtest cases/common/93 private include/stlib/compiler.py30
-rw-r--r--test cases/common/93 private include/stlib/foo1.def0
-rw-r--r--test cases/common/93 private include/stlib/foo2.def0
-rw-r--r--test cases/common/93 private include/stlib/meson.build12
-rw-r--r--test cases/common/93 private include/user/libuser.c6
-rw-r--r--test cases/common/93 private include/user/meson.build5
-rw-r--r--test cases/failing/20 version/meson.build1
-rw-r--r--test cases/rust/1 basic/installed_files.txt2
-rw-r--r--test cases/rust/2 sharedlib/installed_files.txt4
-rw-r--r--test cases/rust/2 sharedlib/stuff.rs2
-rw-r--r--test cases/rust/3 staticlib/installed_files.txt4
-rw-r--r--test cases/rust/3 staticlib/stuff.rs2
22 files changed, 180 insertions, 94 deletions
diff --git a/authors.txt b/authors.txt
index e32bd28..fe479bf 100644
--- a/authors.txt
+++ b/authors.txt
@@ -22,3 +22,4 @@ Rafaël Kooi
Marko Raatikainen
German Diago Gomez
Kyle Manna
+Haakon Sporsheim
diff --git a/build.py b/build.py
index e838b67..8b372f3 100644
--- a/build.py
+++ b/build.py
@@ -124,11 +124,15 @@ class Build:
return self.global_args.get(compiler.get_language(), [])
class IncludeDirs():
- def __init__(self, curdir, dirs):
+ def __init__(self, curdir, dirs, extra_build_dirs=None):
self.curdir = curdir
self.incdirs = dirs
# Interpreter has validated that all given directories
# actually exist.
+ if extra_build_dirs is None:
+ self.extra_build_dirs = []
+ else:
+ self.extra_build_dirs = extra_build_dirs
def get_curdir(self):
return self.curdir
@@ -136,6 +140,9 @@ class IncludeDirs():
def get_incdirs(self):
return self.incdirs
+ def get_extra_build_dirs(self):
+ return self.extra_build_dirs
+
class ExtractedObjects():
def __init__(self, target, srclist):
self.target = target
@@ -545,7 +552,7 @@ class Generator():
if not isinstance(rule, str):
raise InvalidArguments('"output" may only contain strings.')
if not '@BASENAME@' in rule and not '@PLAINNAME@' in rule:
- raise InvalidArguments('"outputs" must contain @BASENAME@ or @PLAINNAME@.')
+ raise InvalidArguments('Every element of "output" must contain @BASENAME@ or @PLAINNAME@.')
if '/' in rule or '\\' in rule:
raise InvalidArguments('"outputs" must not contain a directory separator.')
if len(outputs) > 1:
@@ -613,6 +620,8 @@ class StaticLibrary(BuildTarget):
raise InvalidArguments('Static libraries not supported for C#.')
self.prefix = environment.get_static_lib_prefix()
self.suffix = environment.get_static_lib_suffix()
+ if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
+ self.suffix = 'rlib'
self.filename = self.prefix + self.name + '.' + self.suffix
def get_import_filename(self):
@@ -635,6 +644,8 @@ class SharedLibrary(BuildTarget):
else:
self.prefix = environment.get_shared_lib_prefix()
self.suffix = environment.get_shared_lib_suffix()
+ if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
+ self.suffix = 'rlib'
self.importsuffix = environment.get_import_lib_suffix()
self.filename = self.prefix + self.name + '.' + self.suffix
diff --git a/interpreter.py b/interpreter.py
index 6cfe103..7e67711 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -355,9 +355,9 @@ class CrossMachineInfo(InterpreterObject):
return self.info['endian']
class IncludeDirsHolder(InterpreterObject):
- def __init__(self, curdir, dirs):
+ def __init__(self, idobj):
super().__init__()
- self.held_object = build.IncludeDirs(curdir, dirs)
+ self.held_object = idobj
class Headers(InterpreterObject):
@@ -459,11 +459,16 @@ class BuildTargetHolder(InterpreterObject):
'extract_all_objects' : self.extract_all_objects_method,
'get_id': self.get_id_method,
'outdir' : self.outdir_method,
+ 'private_dir_include' : self.private_dir_include_method,
})
def is_cross(self):
return self.held_object.is_cross()
+ def private_dir_include_method(self, args, kwargs):
+ return IncludeDirsHolder(build.IncludeDirs('', [],
+ [self.interpreter.backend.get_target_private_dir(self.held_object)]))
+
def outdir_method(self, args, kwargs):
return self.interpreter.backend.get_target_dir(self.held_object)
@@ -905,6 +910,8 @@ class Interpreter():
'pkgconfig_gen' : self.func_pkgconfig_gen,
'vcs_tag' : self.func_vcs_tag,
'set_variable' : self.func_set_variable,
+ 'is_variable' : self.func_is_variable,
+ 'get_variable' : self.func_get_variable,
'import' : self.func_import,
'files' : self.func_files,
'declare_dependency': self.func_declare_dependency,
@@ -1003,6 +1010,29 @@ class Interpreter():
value = self.to_native(args[1])
self.set_variable(varname, value)
+ @noKwargs
+ def func_get_variable(self, node, args, kwargs):
+ if len(args)<1 or len(args)>2:
+ raise InvalidCode('Get_variable takes one or two arguments.')
+ varname = args[0]
+ if not isinstance(varname, str):
+ raise InterpreterException('First argument must be a string.')
+ try:
+ return self.variables[varname]
+ except KeyError:
+ pass
+ if len(args) == 2:
+ return args[1]
+ raise InterpreterException('Tried to get unknown variable "%s".' % varname)
+
+ @stringArgs
+ @noKwargs
+ def func_is_variable(self, node, args, kwargs):
+ if len(args) != 1:
+ raise InvalidCode('Is_variable takes two arguments.')
+ varname = args[0]
+ return varname in self.variables
+
@stringArgs
@noKwargs
def func_import(self, node, args, kwargs):
@@ -1244,6 +1274,11 @@ class Interpreter():
if not self.is_subproject() and 'subproject_dir' in kwargs:
self.subproject_dir = kwargs['subproject_dir']
+ if 'meson_version' in kwargs:
+ cv = coredata.version
+ pv = kwargs['meson_version']
+ if not mesonlib.version_compare(cv, pv):
+ raise InterpreterException('Meson version is %s but project requires %s.' % (cv, pv))
self.build.projects[self.subproject] = args[0]
mlog.log('Project name: ', mlog.bold(args[0]), sep='')
self.add_languages(node, args[1:])
@@ -1656,7 +1691,7 @@ class Interpreter():
absdir = os.path.join(absbase, a)
if not os.path.isdir(absdir):
raise InvalidArguments('Include dir %s does not exist.' % a)
- i = IncludeDirsHolder(self.subdir, args)
+ i = IncludeDirsHolder(build.IncludeDirs(self.subdir, args))
return i
@stringArgs
@@ -1814,12 +1849,12 @@ class Interpreter():
def string_method_call(self, obj, method_name, args):
obj = self.to_native(obj)
+ (posargs, _) = self.reduce_arguments(args)
if method_name == 'strip':
return obj.strip()
elif method_name == 'format':
return self.format_string(obj, args)
elif method_name == 'split':
- (posargs, _) = self.reduce_arguments(args)
if len(posargs) > 1:
raise InterpreterException('Split() must have at most one argument.')
elif len(posargs) == 1:
@@ -1829,6 +1864,13 @@ class Interpreter():
return obj.split(s)
else:
return obj.split()
+ elif method_name == 'startswith' or method_name == 'endswith':
+ s = posargs[0]
+ if not isinstance(s, str):
+ raise InterpreterException('Argument must be a string.')
+ if method_name == 'startswith':
+ return obj.startswith(s)
+ return obj.endswith(s)
raise InterpreterException('Unknown method "%s" for a string.' % method_name)
def to_native(self, arg):
diff --git a/manual tests/4 standalone binaries/meson.build b/manual tests/4 standalone binaries/meson.build
index b524873..baae796 100644
--- a/manual tests/4 standalone binaries/meson.build
+++ b/manual tests/4 standalone binaries/meson.build
@@ -1,12 +1,12 @@
project('myapp', 'cpp')
-sdl = dependency('sdl2', required : host.name() != 'windows')
+sdl = dependency('sdl2', required : host_machine.system() != 'windows')
if meson.get_compiler('cpp').get_id() != 'msvc'
add_global_arguments('-std=c++11', language : 'cpp')
endif
-if host.name() == 'darwin'
+if host_machine.system() == 'darwin'
install_data('myapp.sh',
install_dir : 'Contents/MacOS')
@@ -19,14 +19,14 @@ if host.name() == 'darwin'
meson.set_install_script('osx_bundler.sh')
endif
-if host.name() == 'linux'
+if host_machine.system() == 'linux'
install_data('myapp.sh', install_dir : '.')
meson.set_install_script('linux_bundler.sh')
endif
extra_link_args = []
-if host.name() == 'windows'
+if host_machine.system() == 'windows'
str = '-I@0@/@1@'.format(meson.current_build_dir(), 'SDL2-2.0.3/include')
add_global_arguments(str, language : 'cpp')
extra_link_args = ['/SUBSYSTEM:CONSOLE', 'SDL2main.lib', 'SDL2.lib']
diff --git a/ninjabackend.py b/ninjabackend.py
index e6cb6a5..bd074bf 100644
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -169,7 +169,10 @@ class NinjaBackend(backends.Backend):
continue
for src in gensource.get_outfilelist():
if self.environment.is_header(src):
- header_deps.append(src)
+ header_deps.append(os.path.join(self.get_target_private_dir(target), src))
+ for dep in target.link_targets:
+ if isinstance(dep, (build.StaticLibrary, build.SharedLibrary)):
+ header_deps += self.get_generated_headers(dep)
return header_deps
def generate_target(self, target, outfile):
@@ -815,22 +818,22 @@ class NinjaBackend(backends.Backend):
for i in target.get_sources():
if not rustc.can_compile(i):
raise InvalidArguments('Rust target %s contains a non-rust source file.' % target.get_basename())
- relsrc.append(os.path.join(self.build_to_src, i))
+ relsrc.append(i.rel_to_builddir(self.build_to_src))
target_name = os.path.join(target.subdir, target.get_filename())
args = ['--crate-type']
if isinstance(target, build.Executable):
cratetype = 'bin'
elif isinstance(target, build.SharedLibrary):
- cratetype = 'dylib'
+ cratetype = 'rlib'
elif isinstance(target, build.StaticLibrary):
- cratetype = 'lib'
+ cratetype = 'rlib'
else:
raise InvalidArguments('Unknown target type for rustc.')
args.append(cratetype)
args += rustc.get_buildtype_args(self.environment.coredata.buildtype)
- depfile = target_name + '.d'
+ depfile = target.name + '.d'
args += ['--out-dir', target.subdir]
- args += ['--dep-info', depfile]
+ args += ['--emit', 'dep-info', '--emit', 'link']
orderdeps = [os.path.join(t.subdir, t.get_filename()) for t in target.link_targets]
linkdirs = {}
for d in target.link_targets:
@@ -973,12 +976,9 @@ class NinjaBackend(backends.Backend):
def generate_rust_compile_rules(self, compiler, outfile):
rule = 'rule %s_COMPILER\n' % compiler.get_language()
invoc = ' '.join([ninja_quote(i) for i in compiler.get_exelist()])
- command = ' command = %s %s $out $cratetype %s $ARGS $in\n' % \
- (ninja_quote(sys.executable),
- ninja_quote(os.path.join(os.path.split(__file__)[0], "rustrunner.py")),
- invoc)
+ command = ' command = %s $ARGS $in\n' % invoc
description = ' description = Compiling Rust source $in.\n'
- depfile = ' depfile = $out.d\n'
+ depfile = ' depfile = $targetdep\n'
depstyle = ' deps = gcc\n'
outfile.write(rule)
@@ -1308,6 +1308,8 @@ rule FORTRAN_DEP_HACK
sargs = compiler.get_include_args(srctreedir)
commands += bargs
commands += sargs
+ for d in i.get_extra_build_dirs():
+ commands += compiler.get_include_args(d)
custom_target_include_dirs = []
for i in target.generated:
if isinstance(i, build.CustomTarget):
@@ -1370,7 +1372,7 @@ rule FORTRAN_DEP_HACK
def get_fortran_orderdeps(self, target, compiler):
if compiler.language != 'fortran':
return []
- return [os.path.join(self.get_target_dir(lt), lt.filename) for lt in target.link_targets]
+ return [os.path.join(self.get_target_dir(lt), lt.get_filename()) for lt in target.link_targets]
def generate_msvc_pch_command(self, target, compiler, pch):
if len(pch) != 2:
diff --git a/rustrunner.py b/rustrunner.py
deleted file mode 100755
index 6c20bb3..0000000
--- a/rustrunner.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2014 The Meson development team
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""This is a wrapper script to run the Rust compiler. It is needed
-because:
-
-- output file name of Rust compilation is not knowable at command
- execution time (no, --crate-name can't be used)
-- need to delete old crates so nobody uses them by accident
-"""
-
-import sys, os, subprocess, glob
-
-def delete_old_crates(target_name, target_type):
- if target_type == 'dylib':
- (base, suffix) = os.path.splitext(target_name)
- crates = glob.glob(base + '-*' + suffix)
- crates = [(os.stat(i).st_mtime, i) for i in crates]
- [os.unlink(c[1]) for c in sorted(crates)[:-1]]
- if target_type == 'lib':
- (base, suffix) = os.path.splitext(target_name)
- crates = glob.glob(base + '-*' + '.rlib') # Rust does not use .a
- crates = [(os.stat(i).st_mtime, i) for i in crates]
- [os.unlink(c[1]) for c in sorted(crates)[:-1]]
-
-def invoke_rust(rustc_command):
- return subprocess.call(rustc_command, shell=False)
-
-def touch_file(fname):
- try:
- os.unlink(fname)
- except FileNotFoundError:
- pass
- open(fname, 'w').close()
-
-if __name__ == '__main__':
- if len(sys.argv) < 3:
- print('This script is internal to Meson. Do not run it on its own.')
- print("%s <target name> <target type> <rustc invokation cmd line>")
- sys.exit(1)
- target_name = sys.argv[1]
- target_type = sys.argv[2]
- rustc_command = sys.argv[3:]
- retval = invoke_rust(rustc_command)
- if retval != 0:
- sys.exit(retval)
- if target_type != "bin":
- delete_old_crates(target_name, target_type)
- touch_file(target_name)
-
-
diff --git a/test cases/common/1 trivial/meson.build b/test cases/common/1 trivial/meson.build
index 2e0426a..3f14539 100644
--- a/test cases/common/1 trivial/meson.build
+++ b/test cases/common/1 trivial/meson.build
@@ -1,5 +1,5 @@
# Comment on the first line
-project('trivial test', 'c')
+project('trivial test', 'c', meson_version : '>=0.27.0')
#this is a comment
sources = 'trivial.c'
diff --git a/test cases/common/17 if/meson.build b/test cases/common/17 if/meson.build
index b77f93a..2103d20 100644
--- a/test cases/common/17 if/meson.build
+++ b/test cases/common/17 if/meson.build
@@ -12,3 +12,19 @@ if var2
endif
test('iftest', exe)
+
+if not is_variable('var1')
+ error('Is_variable fail.')
+endif
+
+if is_variable('nonexisting')
+ error('Is_variable fail 2.')
+endif
+
+if not get_variable('var1', false)
+ error('Get_variable fail.')
+endif
+
+if get_variable('nonexisting', false)
+ error('Get_variable fail.')
+endif
diff --git a/test cases/common/42 string formatting/meson.build b/test cases/common/42 string formatting/meson.build
index 4e7cc1a..81f5268 100644
--- a/test cases/common/42 string formatting/meson.build
+++ b/test cases/common/42 string formatting/meson.build
@@ -20,3 +20,23 @@ subs2 = '42'
if templ2.format(subs2) != '42'
error('String formatting with variables is broken.')
endif
+
+long = 'abcde'
+prefix = 'abc'
+suffix = 'cde'
+
+if not long.startswith(prefix)
+ error('Prefix.')
+endif
+
+if long.startswith(suffix)
+ error('Not prefix.')
+endif
+
+if not long.endswith(suffix)
+ error('Suffix.')
+endif
+
+if long.endswith(prefix)
+ error('Not suffix.')
+endif
diff --git a/test cases/common/93 private include/meson.build b/test cases/common/93 private include/meson.build
new file mode 100644
index 0000000..2485fbf
--- /dev/null
+++ b/test cases/common/93 private include/meson.build
@@ -0,0 +1,4 @@
+project('access private', 'c')
+
+subdir('stlib')
+subdir('user')
diff --git a/test cases/common/93 private include/stlib/compiler.py b/test cases/common/93 private include/stlib/compiler.py
new file mode 100755
index 0000000..3e74c88
--- /dev/null
+++ b/test cases/common/93 private include/stlib/compiler.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+assert(len(sys.argv) == 3)
+
+h_templ = '''#pragma once
+unsigned int %s();
+'''
+
+c_templ = '''#include"%s.h"
+
+unsigned int %s() {
+ return 0;
+}
+'''
+
+ifile = sys.argv[1]
+outdir = sys.argv[2]
+
+base = os.path.splitext(os.path.split(ifile)[-1])[0]
+
+cfile = os.path.join(outdir, base + '.c')
+hfile = os.path.join(outdir, base + '.h')
+
+c_code = c_templ % (base, base)
+h_code = h_templ % base
+
+open(cfile, 'w').write(c_code)
+open(hfile, 'w').write(h_code)
diff --git a/test cases/common/93 private include/stlib/foo1.def b/test cases/common/93 private include/stlib/foo1.def
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/93 private include/stlib/foo1.def
diff --git a/test cases/common/93 private include/stlib/foo2.def b/test cases/common/93 private include/stlib/foo2.def
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/93 private include/stlib/foo2.def
diff --git a/test cases/common/93 private include/stlib/meson.build b/test cases/common/93 private include/stlib/meson.build
new file mode 100644
index 0000000..8d70650
--- /dev/null
+++ b/test cases/common/93 private include/stlib/meson.build
@@ -0,0 +1,12 @@
+genbin = find_program('compiler.py')
+
+gen = generator(genbin,
+ output : ['@BASENAME@.h', '@BASENAME@.c'],
+ arguments : ['@INPUT@', '@BUILD_DIR@']
+ )
+
+defs = ['foo1.def', 'foo2.def']
+generated = gen.process(defs)
+
+stlib = static_library('st', generated)
+st_priv_inc = stlib.private_dir_include()
diff --git a/test cases/common/93 private include/user/libuser.c b/test cases/common/93 private include/user/libuser.c
new file mode 100644
index 0000000..a74a973
--- /dev/null
+++ b/test cases/common/93 private include/user/libuser.c
@@ -0,0 +1,6 @@
+#include"foo1.h"
+#include"foo2.h"
+
+int main(int argc, char **argv) {
+ return foo1() + foo2();
+}
diff --git a/test cases/common/93 private include/user/meson.build b/test cases/common/93 private include/user/meson.build
new file mode 100644
index 0000000..ab88b1d
--- /dev/null
+++ b/test cases/common/93 private include/user/meson.build
@@ -0,0 +1,5 @@
+exe = executable('libuser', 'libuser.c',
+ link_with : stlib,
+ include_directories : st_priv_inc)
+
+test('libuser', exe)
diff --git a/test cases/failing/20 version/meson.build b/test cases/failing/20 version/meson.build
new file mode 100644
index 0000000..9a3a851
--- /dev/null
+++ b/test cases/failing/20 version/meson.build
@@ -0,0 +1 @@
+project('version mismatch', 'c', meson_version : '>100.0.0')
diff --git a/test cases/rust/1 basic/installed_files.txt b/test cases/rust/1 basic/installed_files.txt
index 429fde7..61eda27 100644
--- a/test cases/rust/1 basic/installed_files.txt
+++ b/test cases/rust/1 basic/installed_files.txt
@@ -1 +1 @@
-bin/prog
+usr/bin/prog
diff --git a/test cases/rust/2 sharedlib/installed_files.txt b/test cases/rust/2 sharedlib/installed_files.txt
index 0606d1f..5a7c7d6 100644
--- a/test cases/rust/2 sharedlib/installed_files.txt
+++ b/test cases/rust/2 sharedlib/installed_files.txt
@@ -1,2 +1,2 @@
-bin/prog
-lib/libstuff-e4d2ee75-1.0.so
+usr/bin/prog
+usr/lib/libstuff.rlib
diff --git a/test cases/rust/2 sharedlib/stuff.rs b/test cases/rust/2 sharedlib/stuff.rs
index 5e1dcc2..8cabc62 100644
--- a/test cases/rust/2 sharedlib/stuff.rs
+++ b/test cases/rust/2 sharedlib/stuff.rs
@@ -1,3 +1,3 @@
-#![crate_id = "stuff#1.0"]
+#![crate_name = "stuff"]
pub fn explore() -> &'static str { "librarystring" }
diff --git a/test cases/rust/3 staticlib/installed_files.txt b/test cases/rust/3 staticlib/installed_files.txt
index 4c3dfed..5a7c7d6 100644
--- a/test cases/rust/3 staticlib/installed_files.txt
+++ b/test cases/rust/3 staticlib/installed_files.txt
@@ -1,2 +1,2 @@
-bin/prog
-lib/libstuff-e4d2ee75-1.0.rlib
+usr/bin/prog
+usr/lib/libstuff.rlib
diff --git a/test cases/rust/3 staticlib/stuff.rs b/test cases/rust/3 staticlib/stuff.rs
index 5e1dcc2..8cabc62 100644
--- a/test cases/rust/3 staticlib/stuff.rs
+++ b/test cases/rust/3 staticlib/stuff.rs
@@ -1,3 +1,3 @@
-#![crate_id = "stuff#1.0"]
+#![crate_name = "stuff"]
pub fn explore() -> &'static str { "librarystring" }