diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2021-02-23 11:05:47 -0800 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2021-06-07 20:05:11 +0530 |
commit | 1346725ec987f0dc40d94259942c49bc90a35ac6 (patch) | |
tree | a6d921ce91ed3d5eb435fe1d7f69f02d1d817e94 | |
parent | d031a684a689e29c1dbbf75ad36709171d56abdf (diff) | |
download | meson-1346725ec987f0dc40d94259942c49bc90a35ac6.zip meson-1346725ec987f0dc40d94259942c49bc90a35ac6.tar.gz meson-1346725ec987f0dc40d94259942c49bc90a35ac6.tar.bz2 |
Add a rust test for internal c linkage
We have code to support this, but no tests. That seems pretty bad.
And better yet, it doesn't work on MSVC in some cases.
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 17 | ||||
-rw-r--r-- | test cases/rust/16 internal c dependencies/lib.c | 6 | ||||
-rw-r--r-- | test cases/rust/16 internal c dependencies/lib.h | 22 | ||||
-rw-r--r-- | test cases/rust/16 internal c dependencies/main.rs | 9 | ||||
-rw-r--r-- | test cases/rust/16 internal c dependencies/meson.build | 14 | ||||
-rwxr-xr-x | test cases/rust/16 internal c dependencies/test.py | 25 |
6 files changed, 88 insertions, 5 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 7dc7d06..0be5873 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1608,12 +1608,19 @@ int dummy; # dependency, so that collisions with libraries in rustc's # sysroot don't cause ambiguity args += ['--extern', '{}={}'.format(d.name, os.path.join(d.subdir, d.filename))] + elif d.typename == 'static library': + # Rustc doesn't follow Meson's convention that static libraries + # are called .a, and implementation libraries are .lib, so we + # have to manually handle that. + if rustc.linker.id == 'link': + args += ['-C', f'link-arg={self.get_target_filename_for_linking(d)}'] + else: + args += ['-l', f'static={d.name}'] + external_deps.extend(d.external_deps) else: - # Rust uses -l for non rust dependencies, but we still need to add (shared|static)=foo - _type = 'static' if d.typename == 'static library' else 'dylib' - args += ['-l', f'{_type}={d.name}'] - if d.typename == 'static library': - external_deps.extend(d.external_deps) + # Rust uses -l for non rust dependencies, but we still need to + # add dylib=foo + args += ['-l', f'dylib={d.name}'] for e in external_deps: for a in e.get_link_args(): if a.endswith(('.dll', '.so', '.dylib')): diff --git a/test cases/rust/16 internal c dependencies/lib.c b/test cases/rust/16 internal c dependencies/lib.c new file mode 100644 index 0000000..e852de6 --- /dev/null +++ b/test cases/rust/16 internal c dependencies/lib.c @@ -0,0 +1,6 @@ +#include <stdio.h> +#include "lib.h" + +void c_func(void) { + printf("This is a " MODE " C library\n"); +} diff --git a/test cases/rust/16 internal c dependencies/lib.h b/test cases/rust/16 internal c dependencies/lib.h new file mode 100644 index 0000000..847bd16 --- /dev/null +++ b/test cases/rust/16 internal c dependencies/lib.h @@ -0,0 +1,22 @@ +#pragma once + +#if defined _WIN32 || defined __CYGWIN__ + #if defined BUILDING_ADDER + #define DLL_PUBLIC __declspec(dllexport) + #else + #define DLL_PUBLIC __declspec(dllimport) + #endif +#else + #if defined __GNUC__ + #if defined BUILDING_ADDER + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #define DLL_PUBLIC + #endif + #else + #pragma message("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +DLL_PUBLIC void c_func(void); diff --git a/test cases/rust/16 internal c dependencies/main.rs b/test cases/rust/16 internal c dependencies/main.rs new file mode 100644 index 0000000..5383599 --- /dev/null +++ b/test cases/rust/16 internal c dependencies/main.rs @@ -0,0 +1,9 @@ +extern "C" { + fn c_func(); +} + +fn main() { + unsafe { + c_func(); + } +} diff --git a/test cases/rust/16 internal c dependencies/meson.build b/test cases/rust/16 internal c dependencies/meson.build new file mode 100644 index 0000000..c7476d7 --- /dev/null +++ b/test cases/rust/16 internal c dependencies/meson.build @@ -0,0 +1,14 @@ +project('internal dependencies', 'c', 'rust') + +test_prog = find_program('test.py') + +static = static_library('static', 'lib.c', c_args : '-DMODE="static"') +exe = executable('static', 'main.rs', link_with : static) +test('static linkage', test_prog, args : [exe, 'This is a static C library']) + +# Shared linkage with rust doesn't work on macOS with meson, yet +if host_machine.system() != 'darwin' + shared = shared_library('shared', 'lib.c', c_args : '-DMODE="shared"') + exe = executable('shared', 'main.rs', link_with : shared) + test('shared linkage', test_prog, args : [exe, 'This is a shared C library']) +endif diff --git a/test cases/rust/16 internal c dependencies/test.py b/test cases/rust/16 internal c dependencies/test.py new file mode 100755 index 0000000..dacec12 --- /dev/null +++ b/test cases/rust/16 internal c dependencies/test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import argparse +import subprocess +import sys + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument('command') + parser.add_argument('expected') + args = parser.parse_args() + + out = subprocess.run(args.command, stdout=subprocess.PIPE) + actual = out.stdout.decode().strip() + + if args.expected != actual: + print('expected:', args.expected, file=sys.stderr) + print('actual: ', actual, file=sys.stderr) + sys.exit(1) + sys.exit(0) + + +if __name__ == "__main__": + main() |