Skip to content

Commit

Permalink
Removed include_directories absolute path validation
Browse files Browse the repository at this point in the history
The 'Tried to form an absolute path to a dir in the source tree' check
is a blunt instrument in that it's too simplistic to correctly identify
problematic, non-project-relative absolute path use without preventing
perfectly good and safe absolute include path use that makes for very
clean, maintainable/refactorable build files.

Guesing at potential problems and imposing a particular style on meson
users, particularly when those problems don't exist in practice, seems
like something best avoided.  The true arbiter of a problem path is
ultimately whether a path actually exists/works;  if they work, don't
add unnecessary obstacles for the user; if they don't work, the problem
and solution should be pretty clear to the user.

Discussion on this issue -
mesonbuild#12244
mesonbuild#12281
  • Loading branch information
GertyP committed Oct 22, 2023
1 parent ae7a9b0 commit 1eb66f0
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 93 deletions.
77 changes: 26 additions & 51 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from .. import mesonlib
from ..mesonlib import (EnvironmentVariables, ExecutableSerialisation, MesonBugException, MesonException, HoldableObject,
FileMode, MachineChoice, OptionKey, listify,
extract_as_list, has_path_sep, path_is_in_root, PerMachine)
extract_as_list, has_path_sep, PerMachine)
from ..programs import ExternalProgram, NonExistingExternalProgram
from ..dependencies import Dependency
from ..depfile import DepFile
Expand Down Expand Up @@ -2774,57 +2774,32 @@ def build_incdir_object(self, incdir_strings: T.List[str], is_system: bool = Fal
absbase_build = os.path.join(build_root, self.subdir)

for a in incdir_strings:
if path_is_in_root(Path(a), Path(src_root)):
raise InvalidArguments(textwrap.dedent('''\
Tried to form an absolute path to a dir in the source tree.
You should not do that but use relative paths instead, for
directories that are part of your project.
To get include path to any directory relative to the current dir do
incdir = include_directories(dirname)
After this incdir will contain both the current source dir as well as the
corresponding build dir. It can then be used in any subdirectory and
Meson will take care of all the busywork to make paths work.
Dirname can even be '.' to mark the current directory. Though you should
remember that the current source and build directories are always
put in the include directories by default so you only need to do
include_directories('.') if you intend to use the result in a
different subdirectory.
Note that this error message can also be triggered by
external dependencies being installed within your source
tree - it's not recommended to do this.
try:
self.validate_within_subproject(self.subdir, a)
except InterpreterException:
mlog.warning('include_directories sandbox violation!', location=self.current_node)
print(textwrap.dedent(f'''\
The project is trying to access the directory {a!r} which belongs to a different
subproject. This is a problem as it hardcodes the relative paths of these two projects.
This makes it impossible to compile the project in any other directory layout and also
prevents the subproject from changing its own directory layout.
Instead of poking directly at the internals the subproject should be executed and
it should set a variable that the caller can then use. Something like:
# In subproject
some_dep = declare_dependency(include_directories: include_directories('include'))
# In subproject wrap file
[provide]
some = some_dep
# In parent project
some_dep = dependency('some')
executable(..., dependencies: [some_dep])
This warning will become a hard error in a future Meson release.
'''))
else:
try:
self.validate_within_subproject(self.subdir, a)
except InterpreterException:
mlog.warning('include_directories sandbox violation!', location=self.current_node)
print(textwrap.dedent(f'''\
The project is trying to access the directory {a!r} which belongs to a different
subproject. This is a problem as it hardcodes the relative paths of these two projects.
This makes it impossible to compile the project in any other directory layout and also
prevents the subproject from changing its own directory layout.
Instead of poking directly at the internals the subproject should be executed and
it should set a variable that the caller can then use. Something like:
# In subproject
some_dep = declare_dependency(include_directories: include_directories('include'))
# In subproject wrap file
[provide]
some = some_dep
# In parent project
some_dep = dependency('some')
executable(..., dependencies: [some_dep])
This warning will become a hard error in a future Meson release.
'''))
absdir_src = os.path.join(absbase_src, a)
absdir_build = os.path.join(absbase_build, a)
if not os.path.isdir(absdir_src) and not os.path.isdir(absdir_build):
Expand Down
2 changes: 0 additions & 2 deletions run_project_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,8 +947,6 @@ def gather_tests(testdir: Path, stdout_mandatory: bool, only: T.List[str], skip_
# Filter non-tests files (dot files, etc)
if not t.is_dir() or t.name.startswith('.'):
continue
if t.name in {'18 includedirxyz'}:
continue
if only and not any(t.name.startswith(prefix) for prefix in only):
continue
test_def = TestDef(t, None, [], skip_category=skip_category)
Expand Down
30 changes: 1 addition & 29 deletions test cases/common/18 includedir/meson.build
Original file line number Diff line number Diff line change
@@ -1,32 +1,4 @@
project('include dir test', 'c')

inc = include_directories('include')
subdir('src')

errormsg = '''Tried to form an absolute path to a dir in the source tree.
You should not do that but use relative paths instead, for
directories that are part of your project.
To get include path to any directory relative to the current dir do
incdir = include_directories(dirname)
After this incdir will contain both the current source dir as well as the
corresponding build dir. It can then be used in any subdirectory and
Meson will take care of all the busywork to make paths work.
Dirname can even be '.' to mark the current directory. Though you should
remember that the current source and build directories are always
put in the include directories by default so you only need to do
include_directories('.') if you intend to use the result in a
different subdirectory.
Note that this error message can also be triggered by
external dependencies being installed within your source
tree - it's not recommended to do this.
'''
testcase expect_error(errormsg)
include_directories(meson.current_source_dir() / 'include')
endtestcase
# Test for issue #12217
include_directories(meson.current_source_dir() + 'xyz')
subdir('src')
1 change: 0 additions & 1 deletion test cases/common/18 includedirxyz/do_not_delete

This file was deleted.

3 changes: 0 additions & 3 deletions test cases/failing/44 abspath to srcdir/meson.build

This file was deleted.

7 changes: 0 additions & 7 deletions test cases/failing/44 abspath to srcdir/test.json

This file was deleted.

0 comments on commit 1eb66f0

Please sign in to comment.