diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2021-02-26 00:22:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-26 00:22:57 +0200 |
commit | 542dea25710fec8df0430d9b777bb15414e15b22 (patch) | |
tree | 09c0eb51087f9ed242d8780248cda1771d6ac511 | |
parent | eba9535428ee9ea41ff1d05f65e07bfe7060060b (diff) | |
parent | 0edd0058046069f715d753dddee6e6c08e79207d (diff) | |
download | meson-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
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" } + ] + } +} |