Merge pull request #2815 from taisei-project/fix_windows_compile_resources

[windows] make compile_resources use custom targets instead of generators
pull/2915/head
Jussi Pakkanen 7 years ago committed by GitHub
commit a5b2b90309
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      docs/markdown/snippets/windows-resources-custom-targets.md
  2. 41
      mesonbuild/modules/windows.py
  3. 70
      test cases/windows/13 resources with custom targets/meson.build
  4. 14
      test cases/windows/13 resources with custom targets/prog.c
  5. 6
      test cases/windows/13 resources with custom targets/res/gen-res.py
  6. 18
      test cases/windows/13 resources with custom targets/res/meson.build
  7. 3
      test cases/windows/13 resources with custom targets/res/myres.rc.in
  8. 3
      test cases/windows/13 resources with custom targets/res/myres_static.rc
  9. BIN
      test cases/windows/13 resources with custom targets/res/sample.ico

@ -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.

@ -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()

@ -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

@ -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;
}

@ -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]))

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Loading…
Cancel
Save