Use target.get_id() instead of basename and type_suffix concatenation at call site

Fixes the bug with flat layout and identical target names in subprojects.
Without this change directories are not created with subproject prefix
and they can collide.

Remove dead makedirs code in Backend.__init__(), during initialization
of backend build.targets is empty. Create output directories in
Vs2010Backend.generate_projects() instead.

Also use double blank line in run_unittests.py according to
https://www.python.org/dev/peps/pep-0008/#blank-lines.
pull/3252/head
Aleksey Filippov 7 years ago committed by Jussi Pakkanen
parent 2e128f71bb
commit 7f042b5fe2
  1. 14
      mesonbuild/backend/backends.py
  2. 3
      mesonbuild/backend/ninjabackend.py
  3. 1
      mesonbuild/backend/vs2010backend.py
  4. 17
      run_unittests.py
  5. 1
      test cases/common/182 identical target name in subproject flat layout/foo.c
  6. 16
      test cases/common/182 identical target name in subproject flat layout/main.c
  7. 11
      test cases/common/182 identical target name in subproject flat layout/meson.build
  8. 1
      test cases/common/182 identical target name in subproject flat layout/subprojects/subproj/foo.c
  9. 3
      test cases/common/182 identical target name in subproject flat layout/subprojects/subproj/meson.build

@ -108,9 +108,6 @@ class Backend:
self.processed_targets = {}
self.build_to_src = os.path.relpath(self.environment.get_source_dir(),
self.environment.get_build_dir())
for t in self.build.targets:
priv_dirname = self.get_target_private_dir_abs(t)
os.makedirs(priv_dirname, exist_ok=True)
def get_target_filename(self, t):
if isinstance(t, build.CustomTarget):
@ -170,12 +167,10 @@ class Backend:
return self.build_to_src
def get_target_private_dir(self, target):
dirname = os.path.join(self.get_target_dir(target), target.get_basename() + target.type_suffix())
return dirname
return os.path.join(self.get_target_dir(target), target.get_id())
def get_target_private_dir_abs(self, target):
dirname = os.path.join(self.environment.get_build_dir(), self.get_target_private_dir(target))
return dirname
return os.path.join(self.environment.get_build_dir(), self.get_target_private_dir(target))
def get_target_generated_dir(self, target, gensrc, src):
"""
@ -519,9 +514,8 @@ class Backend:
# Fortran requires extra include directives.
if compiler.language == 'fortran':
for lt in target.link_targets:
priv_dir = os.path.join(self.get_target_dir(lt), lt.get_basename() + lt.type_suffix())
incflag = compiler.get_include_args(priv_dir, False)
commands += incflag
priv_dir = self.get_target_private_dir(lt)
commands += compiler.get_include_args(priv_dir, False)
return commands
def build_target_link_arguments(self, compiler, deps):

@ -474,8 +474,7 @@ int dummy;
def process_target_dependencies(self, target, outfile):
for t in target.get_dependencies():
tname = t.get_basename() + t.type_suffix()
if tname not in self.processed_targets:
if t.get_id() not in self.processed_targets:
self.generate_target(t, outfile)
def custom_target_generator_inputs(self, target, outfile):

@ -304,6 +304,7 @@ class Vs2010Backend(backends.Backend):
projlist = []
for name, target in self.build.targets.items():
outdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(outdir, exist_ok=True)
fname = name + '.vcxproj'
relname = os.path.join(target.subdir, fname)
projfile = os.path.join(outdir, fname)

@ -68,9 +68,11 @@ def get_dynamic_section_entry(fname, entry):
def get_soname(fname):
return get_dynamic_section_entry(fname, 'soname')
def get_rpath(fname):
return get_dynamic_section_entry(fname, r'(?:rpath|runpath)')
class InternalTests(unittest.TestCase):
def test_version_number(self):
@ -444,6 +446,7 @@ class InternalTests(unittest.TestCase):
if f.name != 'add_release_note_snippets_here':
self.assertTrue(False, 'A file without .md suffix in snippets dir: ' + f.name)
class BasePlatformTests(unittest.TestCase):
def setUp(self):
super().setUp()
@ -1868,6 +1871,15 @@ int main(int argc, char **argv) {
testdir = os.path.join(self.unit_test_dir, '23 compiler run_command')
self.init(testdir)
def test_identical_target_name_in_subproject_flat_layout(self):
'''
Test that identical targets in different subprojects do not collide
if layout is flat.
'''
testdir = os.path.join(self.common_test_dir, '182 identical target name in subproject flat layout')
self.init(testdir, extra_args=['--layout=flat'])
self.build()
class FailureTests(BasePlatformTests):
'''
@ -2466,8 +2478,8 @@ class LinuxlikeTests(BasePlatformTests):
def test_unity_subproj(self):
testdir = os.path.join(self.common_test_dir, '49 subproject')
self.init(testdir, extra_args='--unity=subprojects')
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib/simpletest@exe/simpletest-unity.c'))
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib/sublib@sha/sublib-unity.c'))
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib/sublib@@simpletest@exe/simpletest-unity.c'))
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib/sublib@@sublib@sha/sublib-unity.c'))
self.assertPathDoesNotExist(os.path.join(self.builddir, 'user@exe/user-unity.c'))
self.build()
@ -2745,6 +2757,7 @@ class LinuxArmCrossCompileTests(BasePlatformTests):
compdb = self.get_compdb()
self.assertNotIn('-DBUILD_ENVIRONMENT_ONLY', compdb[0]['command'])
class RewriterTests(unittest.TestCase):
def setUp(self):

@ -0,0 +1,16 @@
#include <stdio.h>
int meson_test_main_foo(void);
int meson_test_subproj_foo(void);
int main(void) {
if (meson_test_main_foo() != 10) {
printf("Failed meson_test_main_foo\n");
return 1;
}
if (meson_test_subproj_foo() != 20) {
printf("Failed meson_test_subproj_foo\n");
return 1;
}
return 0;
}

@ -0,0 +1,11 @@
project('subproject targets', 'c')
# Idea behind this test is to create targets with identical name
# but different output files. We can do this by choosing different
# name_prefix of libraries. Target id does not depend on name_prefix.
main_foo = static_library('foo', 'foo.c', name_prefix : 'main')
subproj_foo = subproject('subproj').get_variable('foo')
exe = executable('prog', 'main.c', link_with : [main_foo, subproj_foo])
test('main test', exe)

@ -0,0 +1,3 @@
project('subproj', 'c')
foo = static_library('foo', 'foo.c', name_prefix : 'subproj')
Loading…
Cancel
Save