diff options
author | Jon Turney <jon.turney@dronecode.org.uk> | 2017-04-14 13:58:21 +0100 |
---|---|---|
committer | Jon Turney <jon.turney@dronecode.org.uk> | 2017-07-20 21:11:56 +0100 |
commit | 3fa3922cea27026d44aef1cdf3ca92d82adc7ced (patch) | |
tree | 512b4bed85b53dfd95add859b0724a1ed84d9754 /test cases | |
parent | b43f4841ba5de2e8bc956eb9fd1f578f90d7ae15 (diff) | |
download | meson-3fa3922cea27026d44aef1cdf3ca92d82adc7ced.zip meson-3fa3922cea27026d44aef1cdf3ca92d82adc7ced.tar.gz meson-3fa3922cea27026d44aef1cdf3ca92d82adc7ced.tar.bz2 |
Support implibs for executables on Windows
Add a boolean 'implib' kwarg to executable(). If true, it is permitted to
use the returned build target object in link_with:
On platforms where this makes sense (e.g. Windows), an implib is generated
for the executable and used when linking. Otherwise, it has no effect.
(Rather than checking if it is a StaticLibrary or SharedLibary, BuildTarget
subclasses gain the is_linkable_target method to test if they can appear in
link_with:)
Also install any executable implib in a similar way to a shared library
implib, i.e. placing the implib in the appropriate place
Add tests of:
- a shared_module containing a reference to a symbol which is known (at link
time) to be provided by the executable
- trying to link with non-implib executables (should fail)
- installing the implib
(This last one needs a little enhancement of the installed file checking as
this is the first install test we have which needs to work with either
MSVC-style or GCC-style implib filenames)
Diffstat (limited to 'test cases')
9 files changed, 130 insertions, 0 deletions
diff --git a/test cases/common/154 shared module resolving symbol in executable/meson.build b/test cases/common/154 shared module resolving symbol in executable/meson.build new file mode 100644 index 0000000..06c9902 --- /dev/null +++ b/test cases/common/154 shared module resolving symbol in executable/meson.build @@ -0,0 +1,24 @@ +project('shared module resolving symbol in executable', 'c') + +# The shared module contains a reference to the symbol 'func_from_executable', +# which is always provided by the executable which loads it. This symbol can be +# resolved at run-time by an ELF loader. But when building PE/COFF objects, all +# symbols must be resolved at link-time, so an implib is generated for the +# executable, and the shared module linked with it. +# +# See testcase 125 for an example of the more complex portability gymnastics +# required if we do not know (at link-time) what provides the symbol. + +link_flags = [] +if host_machine.system() != 'windows' + # Needed to export dynamic symbols from the executable + link_flags += ['-rdynamic'] + # Need to add this manually because Meson won't add it automatically because + # it doesn't know that we are loading a module from the build directory. + link_flags += ['-Wl,-rpath,' + meson.current_build_dir()] +endif + +dl = meson.get_compiler('c').find_library('dl', required: false) +e = executable('prog', 'prog.c', dependencies: dl, implib: true, link_args: link_flags) +m = shared_module('module', 'module.c', link_with: e) +test('test', e, args: m) diff --git a/test cases/common/154 shared module resolving symbol in executable/module.c b/test cases/common/154 shared module resolving symbol in executable/module.c new file mode 100644 index 0000000..64374d5 --- /dev/null +++ b/test cases/common/154 shared module resolving symbol in executable/module.c @@ -0,0 +1,16 @@ +#if defined _WIN32 || defined __CYGWIN__ + #define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +extern int func_from_executable(void); + +int DLL_PUBLIC func(void) { + return func_from_executable(); +} diff --git a/test cases/common/154 shared module resolving symbol in executable/prog.c b/test cases/common/154 shared module resolving symbol in executable/prog.c new file mode 100644 index 0000000..746c192 --- /dev/null +++ b/test cases/common/154 shared module resolving symbol in executable/prog.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <assert.h> +#ifdef _WIN32 +#include <windows.h> +#else +#include <dlfcn.h> +#endif + +#if defined _WIN32 || defined __CYGWIN__ + #define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +typedef int (*fptr) (void); + +int DLL_PUBLIC +func_from_executable(void) +{ + return 42; +} + +int +main (int argc, char **argv) +{ + int expected, actual; + fptr importedfunc; + +#ifdef _WIN32 + HMODULE h = LoadLibraryA(argv[1]); +#else + void *h = dlopen(argv[1], RTLD_NOW); +#endif + assert(h != NULL); + +#ifdef _WIN32 + importedfunc = (fptr) GetProcAddress (h, "func"); +#else + importedfunc = (fptr) dlsym(h, "func"); +#endif + assert(importedfunc != NULL); + assert(importedfunc != func_from_executable); + + actual = (*importedfunc)(); + expected = func_from_executable(); + assert(actual == expected); + +#ifdef _WIN32 + FreeLibrary(h); +#else + dlclose(h); +#endif + + return 0; +} diff --git a/test cases/failing/57 link with executable/meson.build b/test cases/failing/57 link with executable/meson.build new file mode 100644 index 0000000..186b3e5 --- /dev/null +++ b/test cases/failing/57 link with executable/meson.build @@ -0,0 +1,4 @@ +project('link with exe', 'c') + +e = executable('prog', 'prog.c') +m = shared_module('module', 'module.c', link_with: e) diff --git a/test cases/failing/57 link with executable/module.c b/test cases/failing/57 link with executable/module.c new file mode 100644 index 0000000..dc0124a --- /dev/null +++ b/test cases/failing/57 link with executable/module.c @@ -0,0 +1,4 @@ + +int func(void) { + return 42; +} diff --git a/test cases/failing/57 link with executable/prog.c b/test cases/failing/57 link with executable/prog.c new file mode 100644 index 0000000..f3836d7 --- /dev/null +++ b/test cases/failing/57 link with executable/prog.c @@ -0,0 +1,5 @@ +int +main (int argc, char **argv) +{ + return 0; +} diff --git a/test cases/windows/12 exe implib/installed_files.txt b/test cases/windows/12 exe implib/installed_files.txt new file mode 100644 index 0000000..d0ea8f6 --- /dev/null +++ b/test cases/windows/12 exe implib/installed_files.txt @@ -0,0 +1,4 @@ +usr/bin/prog.exe +usr/bin/prog.pdb +?gcc:usr/lib/libprog.exe.a +?msvc:usr/lib/prog.lib diff --git a/test cases/windows/12 exe implib/meson.build b/test cases/windows/12 exe implib/meson.build new file mode 100644 index 0000000..2393e79 --- /dev/null +++ b/test cases/windows/12 exe implib/meson.build @@ -0,0 +1,7 @@ +project('wintest', 'c') + +# Test that we can produce an implib for an executable on Windows, and that it +# is installed along with the executable + +prog = executable('prog', 'prog.c', install: true, implib: true) +test('wintest', prog) diff --git a/test cases/windows/12 exe implib/prog.c b/test cases/windows/12 exe implib/prog.c new file mode 100644 index 0000000..6d5a9f5 --- /dev/null +++ b/test cases/windows/12 exe implib/prog.c @@ -0,0 +1,6 @@ +#include <windows.h> + +int __declspec(dllexport) +main(int argc, char **argv) { + return 0; +} |