diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-04-13 23:27:40 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2017-04-17 12:48:54 +0300 |
commit | 0e47e74a77447575cbabd71315481c6dd9632601 (patch) | |
tree | 368de0c60806fdb1d1109aabdc7dc8abae0b9c6c | |
parent | 0e45134dee09b12005c028aee066b04ff86228e5 (diff) | |
download | meson-0e47e74a77447575cbabd71315481c6dd9632601.zip meson-0e47e74a77447575cbabd71315481c6dd9632601.tar.gz meson-0e47e74a77447575cbabd71315481c6dd9632601.tar.bz2 |
Do not obliterate old rpath because it might be used due to read only data sharing. Closes #1619.
-rw-r--r-- | mesonbuild/scripts/depfixer.py | 15 | ||||
-rwxr-xr-x | run_unittests.py | 22 | ||||
-rw-r--r-- | test cases/unit/7 run installed/foo/foo.c | 3 | ||||
-rw-r--r-- | test cases/unit/7 run installed/foo/meson.build | 7 | ||||
-rw-r--r-- | test cases/unit/7 run installed/meson.build | 9 | ||||
-rw-r--r-- | test cases/unit/7 run installed/prog.c | 5 |
6 files changed, 58 insertions, 3 deletions
diff --git a/mesonbuild/scripts/depfixer.py b/mesonbuild/scripts/depfixer.py index 1404619..16050d7 100644 --- a/mesonbuild/scripts/depfixer.py +++ b/mesonbuild/scripts/depfixer.py @@ -297,11 +297,20 @@ class Elf(DataSizes): old_rpath = self.read_str() if len(old_rpath) < len(new_rpath): sys.exit("New rpath must not be longer than the old one.") - self.bf.seek(rp_off) - self.bf.write(new_rpath) - self.bf.write(b'\0' * (len(old_rpath) - len(new_rpath) + 1)) + # The linker does read-only string deduplication. If there is a + # string that shares a suffix with the rpath, they might get + # dedupped. This means changing the rpath string might break something + # completely unrelated. This has already happened once with X.org. + # Thus we want to keep this change as small as possible to minimize + # the chance of obliterating other strings. It might still happen + # but our behaviour is identical to what chrpath does and it has + # been in use for ages so based on that this should be rare. if len(new_rpath) == 0: self.remove_rpath_entry(entrynum) + else: + self.bf.seek(rp_off) + self.bf.write(new_rpath) + self.bf.write(b'\0') def remove_rpath_entry(self, entrynum): sec = self.find_section(b'.dynamic') diff --git a/run_unittests.py b/run_unittests.py index e8ecbb2..3e98c21 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1460,6 +1460,28 @@ class LinuxlikeTests(BasePlatformTests): self.assertIn('-Werror', plain_comp) self.assertNotIn('-Werror', c03_comp) + def test_run_installed(self): + testdir = os.path.join(self.unit_test_dir, '7 run installed') + self.init(testdir) + self.build() + self.install() + installed_exe = os.path.join(self.installdir, 'usr/bin/prog') + installed_libdir = os.path.join(self.installdir, 'usr/foo') + installed_lib = os.path.join(installed_libdir, 'libfoo.so') + self.assertTrue(os.path.isfile(installed_exe)) + self.assertTrue(os.path.isdir(installed_libdir)) + self.assertTrue(os.path.isfile(installed_lib)) + # Must fail when run without LD_LIBRARY_PATH to ensure that + # rpath has been properly stripped rather than pointing to the builddir. + self.assertNotEqual(subprocess.call(installed_exe, stderr=subprocess.DEVNULL), 0) + # When LD_LIBRARY_PATH is set it should start working. + # For some reason setting LD_LIBRARY_PATH in os.environ fails + # when all tests are run (but works when only this test is run), + # but doing this explicitly works. + env = os.environ.copy() + env['LD_LIBRARY_PATH'] = installed_libdir + self.assertEqual(subprocess.call(installed_exe, env=env), 0) + class RewriterTests(unittest.TestCase): def setUp(self): diff --git a/test cases/unit/7 run installed/foo/foo.c b/test cases/unit/7 run installed/foo/foo.c new file mode 100644 index 0000000..402c895 --- /dev/null +++ b/test cases/unit/7 run installed/foo/foo.c @@ -0,0 +1,3 @@ +int foo() { + return 0; +} diff --git a/test cases/unit/7 run installed/foo/meson.build b/test cases/unit/7 run installed/foo/meson.build new file mode 100644 index 0000000..082f985 --- /dev/null +++ b/test cases/unit/7 run installed/foo/meson.build @@ -0,0 +1,7 @@ +# Try to invoke linker constant string deduplication, +# to ensure we are not clobbering shared strings. +# Name everything possible just as "foo". +foolib = shared_library('foo', 'foo.c', + install_dir : 'foo', + install : true) + diff --git a/test cases/unit/7 run installed/meson.build b/test cases/unit/7 run installed/meson.build new file mode 100644 index 0000000..46236fa --- /dev/null +++ b/test cases/unit/7 run installed/meson.build @@ -0,0 +1,9 @@ +project('foo', 'c', + default_options : 'libdir=lib') + +subdir('foo') + +executable('prog', 'prog.c', + link_with : foolib, + install : true) + diff --git a/test cases/unit/7 run installed/prog.c b/test cases/unit/7 run installed/prog.c new file mode 100644 index 0000000..8e61e6e --- /dev/null +++ b/test cases/unit/7 run installed/prog.c @@ -0,0 +1,5 @@ +int foo(); + +int main(int argc, char **argv) { + return foo(); +} |