Skip to content

Cargo integration in Meson via an "unstable-cargo" module #2616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def flatten_object_list(self, target, proj_dir_to_build_root=''):
def serialize_executable(self, exe, cmd_args, workdir, env={},
capture=None):
import hashlib
# Can't just use exe.name here; it will likely be run more than once
# Generate a good scratch file name
if isinstance(exe, (dependencies.ExternalProgram,
build.BuildTarget, build.CustomTarget)):
basename = exe.name
Expand Down
33 changes: 25 additions & 8 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,12 +486,18 @@ def unwrap_dep_list(self, target):
deps.append(os.path.join(self.get_target_dir(i), output))
return deps

def custom_target_needs_serialization(self, target, cmd):
if target.capture or target.envvars or any('\n' in c for c in cmd) or \
((mesonlib.is_windows() or mesonlib.is_cygwin()) and
self.determine_windows_extra_paths(target.command[0])):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Flake8]

visually indented line with same indent as next logical line

return True

def generate_custom_target(self, target, outfile):
self.custom_target_generator_inputs(target, outfile)
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
deps = self.unwrap_dep_list(target)
deps += self.get_custom_target_depend_files(target)
desc = 'Generating {0} with a {1} command.'
desc = 'Generating custom target {!r} with {}'
if target.build_always:
deps.append('PHONY')
if target.depfile is None:
Expand All @@ -507,32 +513,43 @@ def generate_custom_target(self, target, outfile):
# If the target requires capturing stdout, then use the serialized
# executable wrapper to capture that output and save it to a file.
#
# If the target requires environment variables set, we need the wrapper
# to set those vars for us.
#
# If the command line requires a newline, also use the wrapper, as
# ninja does not support them in its build rule syntax.
#
# Windows doesn't have -rpath, so for EXEs that need DLLs built within
# the project, we need to set PATH so the DLLs are found. We use
# a serialized executable wrapper for that and check if the
# CustomTarget command needs extra paths first.
if (target.capture or any('\n' in c for c in cmd) or
((mesonlib.is_windows() or mesonlib.is_cygwin()) and
self.determine_windows_extra_paths(target.command[0]))):
exe_data = self.serialize_executable(target.command[0], cmd[1:],
exe = target.command[0]
# Get the command's basename for printing when the target is run
if isinstance(exe, (dependencies.ExternalProgram,
build.BuildTarget, build.CustomTarget)):
basename = exe.name
else:
basename = os.path.basename(exe)
if self.custom_target_needs_serialization(target, cmd):
exe_data = self.serialize_executable(exe, cmd[1:],
# All targets are built from the build dir
self.environment.get_build_dir(),
env=target.envvars,
capture=ofilenames[0] if target.capture else None)
cmd_str = '{!r} using the meson_exe.py wrapper'.format(basename)
cmd = self.environment.get_build_command() + ['--internal', 'exe', exe_data]
cmd_type = 'meson_exe.py custom'
else:
cmd_type = 'custom'
cmd_str = '{!r}'.format(basename)
if target.depfile is not None:
rel_dfile = os.path.join(self.get_target_dir(target), target.depfile)
abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(abs_pdir, exist_ok=True)
elem.add_item('DEPFILE', rel_dfile)
if target.ninja_pool is not None:
elem.add_item('pool', target.ninja_pool)
cmd = self.replace_paths(target, cmd)
elem.add_item('COMMAND', cmd)
elem.add_item('description', desc.format(target.name, cmd_type))
elem.add_item('description', desc.format(target.name, cmd_str))
elem.write(outfile)
self.processed_targets[target.get_id()] = True

Expand Down
1 change: 1 addition & 0 deletions mesonbuild/backend/vs2010backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ def gen_custom_target_vcxproj(self, target, ofname, guid):
exe_data = self.serialize_executable(target.command[0], cmd[1:],
# All targets run from the target dir
tdir_abs,
env=target.envvars,
capture=ofilenames[0] if target.capture else None)
wrapper_cmd = self.environment.get_build_command() + ['--internal', 'exe', exe_data]
ET.SubElement(customstep, 'Command').text = ' '.join(self.quote_arguments(wrapper_cmd))
Expand Down
19 changes: 14 additions & 5 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import copy, os, re
from pathlib import PurePath
from collections import OrderedDict
import itertools

Expand Down Expand Up @@ -1517,6 +1518,8 @@ def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False):
self.extra_depends = []
self.depend_files = [] # Files that this target depends on but are not on the command line.
self.depfile = None
self.envvars = {}
self.ninja_pool = None
self.process_kwargs(kwargs)
self.extra_files = []
# Whether to use absolute paths for all files on the commandline
Expand Down Expand Up @@ -1583,10 +1586,13 @@ def process_kwargs(self, kwargs):
inputs = get_sources_string_names(self.sources)
values = get_filenames_templates_dict(inputs, [])
for i in self.outputs:
if not(isinstance(i, str)):
if not isinstance(i, str):
raise InvalidArguments('Output argument not a string.')
if '/' in i:
raise InvalidArguments('Output must not contain a path segment.')
ipath = PurePath(i)
if ipath.is_absolute():
raise InvalidArguments('Output must not be an absolute path')
if '..' in ipath.parts:
raise InvalidArguments('Output path must not contain ".."')
if '@INPUT@' in i or '@INPUT0@' in i:
m = 'Output cannot contain @INPUT@ or @INPUT0@, did you ' \
'mean @PLAINNAME@ or @BASENAME@?'
Expand All @@ -1607,8 +1613,11 @@ def process_kwargs(self, kwargs):
depfile = kwargs['depfile']
if not isinstance(depfile, str):
raise InvalidArguments('Depfile must be a string.')
if os.path.split(depfile)[1] != depfile:
raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
deppath = PurePath(depfile)
if deppath.is_absolute():
raise InvalidArguments('Depfile must not be an absolute path')
if '..' in deppath.parts:
raise InvalidArguments('Depfile must not contain ".."')
self.depfile = depfile
self.command = self.flatten_command(kwargs['command'])
if self.capture:
Expand Down
2 changes: 2 additions & 0 deletions mesonbuild/mesonlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ def expand_arguments(args):
return None
return expended_args

Popen_safe_errors = (FileNotFoundError, PermissionError, subprocess.CalledProcessError)

def Popen_safe(args, write=None, stderr=subprocess.PIPE, **kwargs):
if sys.version_info < (3, 6) or not sys.stdout.encoding:
return Popen_safe_legacy(args, write=write, stderr=stderr, **kwargs)
Expand Down
Loading