Skip to content

Commit

Permalink
interpreter: Fix extract_object subproject validation
Browse files Browse the repository at this point in the history
  • Loading branch information
xclaesse committed Nov 17, 2023
1 parent 2b49408 commit 428455b
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 84 deletions.
5 changes: 0 additions & 5 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3449,11 +3449,6 @@ def check_sources_exist(self, subdir, sources):
if not os.path.isfile(fname):
raise InterpreterException(f'Tried to add non-existing source file {s}.')

# Only permit object extraction from the same subproject
def validate_extraction(self, buildtarget: mesonlib.HoldableObject) -> None:
if self.subproject != buildtarget.subproject:
raise InterpreterException('Tried to extract objects from a different subproject.')

def is_subproject(self) -> bool:
return self.subproject != ''

Expand Down
2 changes: 2 additions & 0 deletions mesonbuild/interpreter/interpreterobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,8 @@ def outdir_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
@noKwargs
@typed_pos_args('extract_objects', varargs=(mesonlib.File, str, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList))
def extract_objects_method(self, args: T.Tuple[T.List[T.Union[mesonlib.FileOrString, 'build.GeneratedTypes']]], kwargs: TYPE_nkwargs) -> build.ExtractedObjects:
if self.subproject != self.held_object.subproject:
raise InterpreterException('Tried to extract objects from a different subproject.')
return self._target_object.extract_objects(args[0])

@noPosargs
Expand Down
9 changes: 0 additions & 9 deletions mesonbuild/interpreterbase/interpreterbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,12 +549,6 @@ def method_call(self, node: mparser.MethodNode) -> T.Optional[InterpreterObject]
return Disabler()
if not isinstance(obj, InterpreterObject):
raise InvalidArguments(f'{object_display_name} is not callable.')
# TODO: InterpreterBase **really** shouldn't be in charge of checking this
if method_name == 'extract_objects':
if isinstance(obj, ObjectHolder):
self.validate_extraction(obj.held_object)
elif not isinstance(obj, Disabler):
raise InvalidArguments(f'Invalid operation "extract_objects" on {object_display_name} of type {type(obj).__name__}')
obj.current_node = self.current_node = node
res = obj.method_call(method_name, args, kwargs)
return self._holderify(res) if res is not None else None
Expand Down Expand Up @@ -670,6 +664,3 @@ def get_variable(self, varname: str) -> InterpreterObject:
if varname in self.variables:
return self.variables[varname]
raise InvalidCode(f'Unknown variable "{varname}".')

def validate_extraction(self, buildtarget: mesonlib.HoldableObject) -> None:
raise InterpreterException('validate_extraction is not implemented in this context (please file a bug)')
93 changes: 50 additions & 43 deletions test cases/common/22 object extraction/meson.build
Original file line number Diff line number Diff line change
@@ -1,50 +1,57 @@
project('object extraction', 'c')

if meson.is_unity()
message('Skipping extraction test because this is a Unity build.')
else
lib1 = library('somelib', 'src/lib.c')
lib2 = library('somelib2', 'lib.c', 'header.h', 'lib2.c')

obj1 = lib1.extract_objects('src/lib.c')
obj2 = lib2.extract_objects(['lib.c'])
obj3 = lib2.extract_objects(files('lib.c'))
obj4 = lib2.extract_objects(['lib.c', 'lib.c'])
obj5 = lib2.extract_objects(['lib.c', 'header.h'])
obj6 = lib2.extract_all_objects(recursive: true)

e1 = executable('main1', 'main.c', objects : obj1)
e2 = executable('main2', 'main.c', objects : obj2)
e3 = executable('main3', 'main.c', objects : obj3)
e4 = executable('main4', 'main.c', objects : obj4)
e5 = executable('main5', 'main.c', objects : obj5)
e6 = executable('main6', 'main.c', objects : obj6)

ct_src = custom_target('lib3.c', output: 'lib3.c', capture: true,
command: [find_program('create-source.py'), 'lib.c'])
lib3 = library('somelib3', ct_src)
e7 = executable('main7', 'main.c', objects: lib3.extract_objects(ct_src[0]))
e8 = executable('main8', 'main.c', objects: lib3.extract_objects(ct_src))
error('MESON_SKIP_TEST, Skipping extraction test because this is a Unity build.')
endif

gen = generator(find_program('create-source.py'), arguments: ['@INPUT@'],
output: '@[email protected]', capture: true)
gen_src = gen.process('lib.c')
lib4 = library('somelib4', gen_src)
e9 = executable('main9', 'main.c', objects: lib4.extract_objects(gen_src))
lib1 = library('somelib', 'src/lib.c')
lib2 = library('somelib2', 'lib.c', 'header.h', 'lib2.c')
obj1 = lib1.extract_objects('src/lib.c')
obj2 = lib2.extract_objects(['lib.c'])
obj3 = lib2.extract_objects(files('lib.c'))
obj4 = lib2.extract_objects(['lib.c', 'lib.c'])
obj5 = lib2.extract_objects(['lib.c', 'header.h'])
obj6 = lib2.extract_all_objects(recursive: true)
e1 = executable('main1', 'main.c', objects : obj1)
e2 = executable('main2', 'main.c', objects : obj2)
e3 = executable('main3', 'main.c', objects : obj3)
e4 = executable('main4', 'main.c', objects : obj4)
e5 = executable('main5', 'main.c', objects : obj5)
e6 = executable('main6', 'main.c', objects : obj6)
ct_src = custom_target('lib3.c', output: 'lib3.c', capture: true,
command: [find_program('create-source.py'), 'lib.c'])
lib3 = library('somelib3', ct_src)
e7 = executable('main7', 'main.c', objects: lib3.extract_objects(ct_src[0]))
e8 = executable('main8', 'main.c', objects: lib3.extract_objects(ct_src))
gen = generator(find_program('create-source.py'), arguments: ['@INPUT@'],
output: '@[email protected]', capture: true)
gen_src = gen.process('lib.c')
lib4 = library('somelib4', gen_src)
e9 = executable('main9', 'main.c', objects: lib4.extract_objects(gen_src))
custom_target('custom_target with object inputs', output: 'objs',
input: [obj1, obj2, obj3, obj5, obj6],
build_by_default: true,
command: [find_program('check-obj.py'), meson.backend(), '@INPUT@'],
capture: true)
test('extraction test 1', e1)
test('extraction test 2', e2)
test('extraction test 3', e3)
test('extraction test 4', e4)
test('extraction test 5', e5)
test('extraction test 6', e6)
test('extraction test 7', e7)
test('extraction test 8', e8)
test('extraction test 9', e9)

custom_target('custom_target with object inputs', output: 'objs',
input: [obj1, obj2, obj3, obj5, obj6],
build_by_default: true,
command: [find_program('check-obj.py'), meson.backend(), '@INPUT@'],
capture: true)
lib = subproject('sub').get_variable('lib')
testcase expect_error('Tried to extract objects from a different subproject.')
lib.extract_objects()
endtestcase

test('extraction test 1', e1)
test('extraction test 2', e2)
test('extraction test 3', e3)
test('extraction test 4', e4)
test('extraction test 5', e5)
test('extraction test 6', e6)
test('extraction test 7', e7)
test('extraction test 8', e8)
test('extraction test 9', e9)
cc = meson.get_compiler('c')
lib = cc.find_library('z', required: false)
if lib.found()
testcase expect_error('Unknown method .*', how: 're')
lib.extract_objects()
endtestcase
endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project('sub', 'c')

lib = static_library('a', 'source.c')
lib.extract_objects()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
int func(void);

int func(void) {
return 1;
}
5 changes: 0 additions & 5 deletions test cases/failing/16 extract from subproject/main.c

This file was deleted.

9 changes: 0 additions & 9 deletions test cases/failing/16 extract from subproject/meson.build

This file was deleted.

This file was deleted.

This file was deleted.

7 changes: 0 additions & 7 deletions test cases/failing/16 extract from subproject/test.json

This file was deleted.

0 comments on commit 428455b

Please sign in to comment.