diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2018-01-13 19:38:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-13 19:38:48 +0200 |
commit | a5b2b90309ec765ea5a2cd50ee6f12361f2d25f5 (patch) | |
tree | 7669e44ccdce091c0fe3813da6ab124a7b391093 | |
parent | 933eaf602268dc5b20a90aed13b4d832a18047d6 (diff) | |
parent | fd4236085bf3852f783e0b6df758365093d3b000 (diff) | |
download | meson-a5b2b90309ec765ea5a2cd50ee6f12361f2d25f5.zip meson-a5b2b90309ec765ea5a2cd50ee6f12361f2d25f5.tar.gz meson-a5b2b90309ec765ea5a2cd50ee6f12361f2d25f5.tar.bz2 |
Merge pull request #2815 from taisei-project/fix_windows_compile_resources
[windows] make compile_resources use custom targets instead of generators
9 files changed, 153 insertions, 5 deletions
diff --git a/docs/markdown/snippets/windows-resources-custom-targets.md b/docs/markdown/snippets/windows-resources-custom-targets.md new file mode 100644 index 0000000..a2dce3a --- /dev/null +++ b/docs/markdown/snippets/windows-resources-custom-targets.md @@ -0,0 +1,3 @@ +## Can use custom targets as Windows resource files + +The `compile_resources()` function of the `windows` module can now be used on custom targets as well as regular files. diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py index c16d7a8..dc6e9d8 100644 --- a/mesonbuild/modules/windows.py +++ b/mesonbuild/modules/windows.py @@ -67,11 +67,42 @@ class WindowsModule(ExtensionModule): suffix = 'o' if not rescomp.found(): raise MesonException('Could not find Windows resource compiler %s.' % ' '.join(rescomp.get_command())) - res_kwargs = {'output': '@BASENAME@.' + suffix, - 'arguments': res_args} - res_gen = build.Generator([rescomp], res_kwargs) - res_output = res_gen.process_files('Windows resource', args, state) - return ModuleReturnValue(res_output, [res_output]) + + res_targets = [] + + def add_target(src): + if isinstance(src, list): + for subsrc in src: + add_target(subsrc) + return + + if hasattr(src, 'held_object'): + src = src.held_object + + res_kwargs = { + 'output': '@BASENAME@.' + suffix, + 'input': [src], + 'command': [rescomp] + res_args, + } + + if isinstance(src, (str, mesonlib.File)): + name = 'file {!r}'.format(str(src)) + elif isinstance(src, build.CustomTarget): + if len(src.get_outputs()) > 1: + raise MesonException('windows.compile_resources does not accept custom targets with more than 1 output.') + + name = 'target {!r}'.format(src.get_id()) + else: + raise MesonException('Unexpected source type {!r}. windows.compile_resources accepts only strings, files, custom targets, and lists thereof.'.format(src)) + + # Path separators are not allowed in target names + name = name.replace('/', '_').replace('\\', '_') + + res_targets.append(build.CustomTarget('Windows resource for ' + name, state.subdir, state.subproject, res_kwargs)) + + add_target(args) + + return ModuleReturnValue(res_targets, [res_targets]) def initialize(): return WindowsModule() diff --git a/test cases/windows/13 resources with custom targets/meson.build b/test cases/windows/13 resources with custom targets/meson.build new file mode 100644 index 0000000..b1e2b09 --- /dev/null +++ b/test cases/windows/13 resources with custom targets/meson.build @@ -0,0 +1,70 @@ +project('winmain', 'c') + +# MinGW windres has a bug due to which it doesn't parse args with space properly: +# https://github.com/mesonbuild/meson/pull/1346 +# https://sourceware.org/bugzilla/show_bug.cgi?id=4933 +if meson.get_compiler('c').get_id() == 'gcc' and host_machine.system() == 'windows' + # Construct build_to_src and skip this test if it has spaces + # because then the -I flag to windres will also have spaces + # and we know the test will fail + src_parts = meson.source_root().split('/') + build_parts = meson.build_root().split('/') + + # Get the common path (which might just be '/' or 'C:/') + common = [] + done = false + count = 0 + if src_parts.length() > build_parts.length() + parts = build_parts + other = src_parts + else + parts = src_parts + other = build_parts + endif + foreach part : parts + if not done and part == other.get(count) + common += [part] + else + done = true + endif + count += 1 + endforeach + + # Create path components to go down from the build root to the common path + count = 0 + rel = build_parts + foreach build : build_parts + if count < build_parts.length() - common.length() + rel += ['..'] + endif + count += 1 + endforeach + + # Create path components to go up from the common path to the build root + count = 0 + foreach src : src_parts + if count >= common.length() + rel += [src] + endif + count += 1 + endforeach + + build_to_src = '/'.join(rel) + + if build_to_src.contains(' ') + message('build_to_src is: ' + build_to_src) + error('MESON_SKIP_TEST build_to_src has spaces') + endif + # Welcome to the end of this conditional. + # We hope you never have to implement something like this. +endif + +subdir('res') + +foreach id : [0, 1, 2] + exe = executable('prog_@0@'.format(id), 'prog.c', + res[id], + gui_app : true) + + test('winmain_@0@'.format(id), exe) +endforeach diff --git a/test cases/windows/13 resources with custom targets/prog.c b/test cases/windows/13 resources with custom targets/prog.c new file mode 100644 index 0000000..2bef6a2 --- /dev/null +++ b/test cases/windows/13 resources with custom targets/prog.c @@ -0,0 +1,14 @@ +#include<windows.h> + +#define MY_ICON 1 + +int APIENTRY +WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) { + HICON hIcon; + hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MY_ICON)); + return hIcon ? 0 : 1; +} diff --git a/test cases/windows/13 resources with custom targets/res/gen-res.py b/test cases/windows/13 resources with custom targets/res/gen-res.py new file mode 100755 index 0000000..2feb02f --- /dev/null +++ b/test cases/windows/13 resources with custom targets/res/gen-res.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import sys + +with open(sys.argv[1], 'r') as infile, open(sys.argv[2], 'w') as outfile: + outfile.write(infile.read().format(icon=sys.argv[3])) diff --git a/test cases/windows/13 resources with custom targets/res/meson.build b/test cases/windows/13 resources with custom targets/res/meson.build new file mode 100644 index 0000000..c15bd92 --- /dev/null +++ b/test cases/windows/13 resources with custom targets/res/meson.build @@ -0,0 +1,18 @@ +win = import('windows') + +rc_writer = find_program('./gen-res.py') + +rc_sources = [] + +foreach id : [1, 2] + rc_sources += custom_target('RC source file @0@'.format(id), + input : 'myres.rc.in', + output : 'myres_@0@.rc'.format(id), + command : [rc_writer, '@INPUT@', '@OUTPUT@', files('sample.ico')], + install : false, + build_always : true) +endforeach + +rc_sources += files('myres_static.rc') + +res = win.compile_resources(rc_sources) diff --git a/test cases/windows/13 resources with custom targets/res/myres.rc.in b/test cases/windows/13 resources with custom targets/res/myres.rc.in new file mode 100644 index 0000000..6899bc8 --- /dev/null +++ b/test cases/windows/13 resources with custom targets/res/myres.rc.in @@ -0,0 +1,3 @@ +#include<windows.h> + +1 ICON "{icon}" diff --git a/test cases/windows/13 resources with custom targets/res/myres_static.rc b/test cases/windows/13 resources with custom targets/res/myres_static.rc new file mode 100644 index 0000000..12838ae --- /dev/null +++ b/test cases/windows/13 resources with custom targets/res/myres_static.rc @@ -0,0 +1,3 @@ +#include<windows.h> + +1 ICON "sample.ico" diff --git a/test cases/windows/13 resources with custom targets/res/sample.ico b/test cases/windows/13 resources with custom targets/res/sample.ico Binary files differnew file mode 100644 index 0000000..24bd3d9 --- /dev/null +++ b/test cases/windows/13 resources with custom targets/res/sample.ico |