Repository: mesonbuild/meson

Issue:
rpath order of two subprojects is not deterministic
This is related to issue #3922.
In the attached testcase meson sometimes uses

'-Wl,-rpath,$$ORIGIN/subprojects/sub1:$$ORIGIN/subprojects/sub2'

and sometimes

'-Wl,-rpath,$$ORIGIN/subprojects/sub2:$$ORIGIN/subprojects/sub1'

[meson-test.zip](https://github.com/mesonbuild/meson/files/2217864/meson-test.zip)


Discussion:
This is likely because we use a `set()` in `mesonbuild/backend/backends.py:determine_rpath_dirs()` could you open a PR that fixes that with a test? Maybe add it to https://github.com/mesonbuild/meson/pull/3927?
I will probably have a pr for it tomorrow.

Resolving patch:
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -376,7 +376,7 @@ def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
 
     def determine_rpath_dirs(self, target):
         link_deps = target.get_all_link_deps()
-        result = set()
+        result = OrderedSet()
         for ld in link_deps:
             if ld is target:
                 continue
diff --git a/run_unittests.py b/run_unittests.py
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -3600,6 +3600,25 @@ def test_deterministic_dep_order(self):
                     return
         raise RuntimeError('Could not find the build rule')
 
+    def test_deterministic_rpath_order(self):
+        '''
+        Test that the rpaths are always listed in a deterministic order.
+        '''
+        if is_cygwin():
+            raise unittest.SkipTest('rpath are not used on Cygwin')
+        testdir = os.path.join(self.unit_test_dir, '35 rpath order')
+        self.init(testdir)
+        if is_osx():
+            rpathre = re.compile('-rpath,.*/subprojects/sub1.*-rpath,.*/subprojects/sub2')
+        else:
+            rpathre = re.compile('-rpath,\$\$ORIGIN/subprojects/sub1:\$\$ORIGIN/subprojects/sub2')
+        with open(os.path.join(self.builddir, 'build.ninja')) as bfile:
+            for line in bfile:
+                if '-rpath' in line:
+                    self.assertRegex(line, rpathre)
+                    return
+        raise RuntimeError('Could not find the rpath')
+
     @skipIfNoPkgconfig
     def test_usage_external_library(self):
         '''


Test patch:
diff --git a/test cases/unit/35 rpath order/meson.build b/test cases/unit/35 rpath order/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/35 rpath order/meson.build	
@@ -0,0 +1,11 @@
+project('myexe', 'c')
+
+sub1 = subproject('sub1')
+sub1_dep = sub1.get_variable('sub1_dep')
+
+sub2 = subproject('sub2')
+sub2_dep = sub2.get_variable('sub2_dep')
+
+executable('myexe',
+           'myexe.c',
+           dependencies: [sub1_dep, sub2_dep])
diff --git a/test cases/unit/35 rpath order/myexe.c b/test cases/unit/35 rpath order/myexe.c
new file mode 100644
--- /dev/null
+++ b/test cases/unit/35 rpath order/myexe.c	
@@ -0,0 +1,3 @@
+int main(void) {
+  return 0;
+}
diff --git a/test cases/unit/35 rpath order/subprojects/sub1/lib.c b/test cases/unit/35 rpath order/subprojects/sub1/lib.c
new file mode 100644
diff --git a/test cases/unit/35 rpath order/subprojects/sub1/meson.build b/test cases/unit/35 rpath order/subprojects/sub1/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/35 rpath order/subprojects/sub1/meson.build	
@@ -0,0 +1,5 @@
+project('sub1', 'c')
+
+sub1_lib = library('sub1', 'lib.c')
+
+sub1_dep = declare_dependency(link_with : sub1_lib)
diff --git a/test cases/unit/35 rpath order/subprojects/sub2/lib.c b/test cases/unit/35 rpath order/subprojects/sub2/lib.c
new file mode 100644
diff --git a/test cases/unit/35 rpath order/subprojects/sub2/meson.build b/test cases/unit/35 rpath order/subprojects/sub2/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/35 rpath order/subprojects/sub2/meson.build	
@@ -0,0 +1,5 @@
+project('sub2', 'c')
+
+sub2_lib = library('sub2', 'lib.c')
+
+sub2_dep = declare_dependency(link_with : sub2_lib)