aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2021-02-26 00:22:57 +0200
committerGitHub <noreply@github.com>2021-02-26 00:22:57 +0200
commit542dea25710fec8df0430d9b777bb15414e15b22 (patch)
tree09c0eb51087f9ed242d8780248cda1771d6ac511
parenteba9535428ee9ea41ff1d05f65e07bfe7060060b (diff)
parent0edd0058046069f715d753dddee6e6c08e79207d (diff)
downloadmeson-542dea25710fec8df0430d9b777bb15414e15b22.zip
meson-542dea25710fec8df0430d9b777bb15414e15b22.tar.gz
meson-542dea25710fec8df0430d9b777bb15414e15b22.tar.bz2
Merge pull request #8404 from dcbaker/submit/rust-c-dependencies
Fix linking Rust with C dependencies
-rw-r--r--mesonbuild/backend/ninjabackend.py22
-rw-r--r--test cases/rust/13 external c dependencies/c_accessing_zlib.c10
-rw-r--r--test cases/rust/13 external c dependencies/meson.build23
-rw-r--r--test cases/rust/13 external c dependencies/meson_options.txt2
-rw-r--r--test cases/rust/13 external c dependencies/prog.rs9
-rw-r--r--test cases/rust/13 external c dependencies/test.json18
6 files changed, 80 insertions, 4 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 58fd5c6..b7723ef 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1598,6 +1598,7 @@ int dummy;
args += rustc.get_output_args(os.path.join(target.subdir, target.get_filename()))
args += self.environment.coredata.get_external_args(target.for_machine, rustc.language)
linkdirs = mesonlib.OrderedSet()
+ external_deps = target.external_deps.copy()
for d in target.link_targets:
linkdirs.add(d.subdir)
if d.uses_rust():
@@ -1609,14 +1610,27 @@ int dummy;
# Rust uses -l for non rust dependencies, but we still need to add (shared|static)=foo
_type = 'static' if d.typename == 'static library' else 'shared'
args += ['-l', f'{_type}={d.name}']
+ if d.typename == 'static library':
+ external_deps.extend(d.external_deps)
+ for e in external_deps:
+ for a in e.get_link_args():
+ if a.endswith(('.dll', '.so', '.dylib')):
+ dir_, lib = os.path.split(a)
+ linkdirs.add(dir_)
+ lib, ext = os.path.splitext(lib)
+ if lib.startswith('lib'):
+ lib = lib[3:]
+ args.extend(['-l', f'dylib={lib}'])
+ elif a.startswith('-L'):
+ args.append(a)
+ elif a.startswith('-l'):
+ # This should always be a static lib, I think
+ args.extend(['-l', f'static={a[2:]}'])
for d in linkdirs:
if d == '':
d = '.'
args += ['-L', d]
- has_shared_deps = False
- for dep in target.get_dependencies():
- if isinstance(dep, build.SharedLibrary):
- has_shared_deps = True
+ has_shared_deps = any(isinstance(dep, build.SharedLibrary) for dep in target.get_dependencies())
if isinstance(target, build.SharedLibrary) or has_shared_deps:
# add prefer-dynamic if any of the Rust libraries we link
# against are dynamic, otherwise we'll end up with
diff --git a/test cases/rust/13 external c dependencies/c_accessing_zlib.c b/test cases/rust/13 external c dependencies/c_accessing_zlib.c
new file mode 100644
index 0000000..358b989
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/c_accessing_zlib.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <string.h>
+#include <zlib.h>
+
+void c_accessing_zlib(void) {
+ struct z_stream_s zstream;
+ printf("Hello from C!\n");
+ memset(&zstream, 0, sizeof(zstream));
+ inflateInit(&zstream);
+}
diff --git a/test cases/rust/13 external c dependencies/meson.build b/test cases/rust/13 external c dependencies/meson.build
new file mode 100644
index 0000000..e5caf70
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/meson.build
@@ -0,0 +1,23 @@
+project('rust linking to c using dependency', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: doesnt work right on macos, please fix!')
+endif
+
+dep_zlib = dependency('zlib', static : get_option('static'), method : get_option('method'), required : false)
+if not dep_zlib.found()
+ error('MESON_SKIP_TEST: Could not find a @0@ zlib'.format(get_option('static') ? 'static' : 'shared'))
+endif
+
+l = static_library(
+ 'c_accessing_zlib',
+ 'c_accessing_zlib.c',
+ dependencies: [dep_zlib],
+)
+
+e = executable(
+ 'prog', 'prog.rs',
+ link_with : l,
+)
+
+test('cdepstest', e)
diff --git a/test cases/rust/13 external c dependencies/meson_options.txt b/test cases/rust/13 external c dependencies/meson_options.txt
new file mode 100644
index 0000000..f501348
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/meson_options.txt
@@ -0,0 +1,2 @@
+option('static', type : 'boolean')
+option('method', type : 'string')
diff --git a/test cases/rust/13 external c dependencies/prog.rs b/test cases/rust/13 external c dependencies/prog.rs
new file mode 100644
index 0000000..b30ec24
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/prog.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn c_accessing_zlib();
+}
+
+fn main() {
+ unsafe {
+ c_accessing_zlib();
+ }
+}
diff --git a/test cases/rust/13 external c dependencies/test.json b/test cases/rust/13 external c dependencies/test.json
new file mode 100644
index 0000000..423581f
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/test.json
@@ -0,0 +1,18 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": true },
+ { "val": false }
+ ],
+ "method": [
+ { "val": "pkg-config" },
+ { "val": "cmake" },
+ { "val": "system" }
+ ]
+ },
+ "exclude": [
+ { "static": true, "method": "pkg-config" }
+ ]
+ }
+}