diff --git a/gdk-pixbuf-loader/meson.build b/gdk-pixbuf-loader/meson.build index 101bb942a9f47cf426e02b72e342e750d7bb3049..69cb5dc936ddd78a529bb2c81da5e264e404527b 100644 --- a/gdk-pixbuf-loader/meson.build +++ b/gdk-pixbuf-loader/meson.build @@ -12,8 +12,17 @@ pixbufloader_svg_def = configure_file( capture: true, ) -version_script = meson.current_build_dir() / 'gdk-pixbuf-loader.def' -if host_machine.system() in ['darwin', 'ios'] +pixbufloader_svg_ver = configure_file( + command: [makedef_args, '--list', '@INPUT@'], + input: files( + 'gdk-pixbuf-loader.symbols' + ), + output: 'gdk-pixbuf-loader.ver', + capture: true, +) + +version_script = meson.current_build_dir() / 'gdk-pixbuf-loader.ver' +if host_system in ['darwin', 'ios'] vflag = '-Wl,-exported_symbols_list,@0@'.format(version_script) else vflag = '-Wl,--version-script,@0@'.format(version_script) @@ -21,13 +30,14 @@ endif pixbufloader_link_args = cc.get_supported_link_arguments([vflag]) + strip_link_args -pixbufloader_svg = shared_library( +pixbufloader_svg = shared_module( 'pixbufloader-svg', files( 'io-svg.c' ), c_args: ['-DGDK_PIXBUF_ENABLE_BACKEND'], link_args: pixbufloader_link_args, + link_depends: pixbufloader_svg_ver, dependencies: librsvg_dep, vs_module_defs: pixbufloader_svg_def, install: true, diff --git a/meson.build b/meson.build index 677924999498f7db16293516cfa11f41b61af701..7ae881525db2dd4abaeb73aedccae38a21e3e929 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ librsvg_api_minor = api_split[1] librsvg_pc = 'librsvg-@0@'.format(librsvg_api_version) rsvg_ver = 'rsvg-@0@'.format(librsvg_api_major) -system = build_machine.system() +host_system = host_machine.system() cc = meson.get_compiler('c') # MSRV - Minimum Supported Rust Version @@ -92,7 +92,7 @@ pangocairo_dep = dependency('pangocairo', fallback: ['pango', 'libpangocairo_dep']) pangoft2_dep = dependency('pangoft2', version: pango_required, - required: system not in ['windows', 'darwin', 'ios'], + required: host_system not in ['windows', 'darwin', 'ios'], fallback: ['pango', 'libpangoft2_dep']) gmodule_dep = dependency('gmodule-2.0', version: glib_required, fallback : ['glib', 'libgmodule_dep']) @@ -112,7 +112,7 @@ vapigen_dep = dependency('vapigen', required: get_option('vala')) # Extra env to pass to cargo -extra_env = {} +extra_env = environment() # If FreeType and/or libxml2 is/are found by CMake instead of # pkg-config, we must tell Cargo the libraries explicitly and @@ -122,15 +122,15 @@ if freetype2_dep.type_name() == 'cmake' or libxml_dep.type_name() == 'cmake' endif if freetype2_dep.type_name() == 'cmake' ft2_lib = freetype2_dep.get_variable('FREETYPE_LIBRARIES') - extra_env += {'SYSTEM_DEPS_FREETYPE2_NO_PKG_CONFIG': '1', - 'SYSTEM_DEPS_FREETYPE2_SEARCH_NATIVE': fs.parent(ft2_lib), - 'SYSTEM_DEPS_FREETYPE2_LIB': fs.stem(ft2_lib)} + extra_env.set('SYSTEM_DEPS_FREETYPE2_NO_PKG_CONFIG', '1') + extra_env.set('SYSTEM_DEPS_FREETYPE2_SEARCH_NATIVE', fs.parent(ft2_lib)) + extra_env.set('SYSTEM_DEPS_FREETYPE2_LIB', fs.stem(ft2_lib)) endif if libxml_dep.type_name() == 'cmake' libxml_lib = libxml_dep.get_variable('LIBXML2_LIBRARIES') - extra_env += {'SYSTEM_DEPS_LIBXML2_NO_PKG_CONFIG': '1', - 'SYSTEM_DEPS_LIBXML2_SEARCH_NATIVE': fs.parent(libxml_lib), - 'SYSTEM_DEPS_LIBXML2_LIB': fs.stem(libxml_lib)} + extra_env.set('SYSTEM_DEPS_LIBXML2_NO_PKG_CONFIG', '1') + extra_env.set('SYSTEM_DEPS_LIBXML2_SEARCH_NATIVE', fs.parent(libxml_lib)) + extra_env.set('SYSTEM_DEPS_LIBXML2_LIB', fs.stem(libxml_lib)) endif build_gir = get_option('introspection').require(not meson.is_cross_build() and gi_dep.found()) @@ -145,7 +145,7 @@ build_tests = get_option('tests').require(pixbuf_dep.found(), error_message: 'Te gnome = import('gnome') foundation_dep = dependency('appleframeworks', modules: 'Foundation', - required: system in ['darwin', 'ios']) + required: host_system in ['darwin', 'ios']) m_dep = cc.find_library('m', required: false) # ignore the system dependencies for GIR @@ -165,65 +165,80 @@ library_dependencies_sole = [ ] library_dependencies = library_dependencies_sole +private_dependencies = [] -if system == 'windows' +target = get_option('triplet') + +if host_system == 'windows' rustc_native_libs_harness = find_program('meson/query-rustc-native-libs.py', native: true, required: get_option('default_library') != 'shared') + rustc_native_libs_args = [ + rustc_native_libs_harness, + rustc, + ] + if target != '' + rustc_native_libs_args += ['--target', target] + endif + native_libs = run_command( - [ - rustc_native_libs_harness, - rustc, - ], + rustc_native_libs_args, capture: true, check: true ) foreach i: native_libs.stdout().split() if i != 'msvcrt' - library_dependencies += cc.find_library(i, required: get_option('default_library') != 'shared') + private_dependencies += cc.find_library(i, required: get_option('default_library') != 'shared') endif endforeach endif -library_dependencies += [m_dep, foundation_dep] +private_dependencies += [m_dep, foundation_dep] +library_dependencies += private_dependencies cargo_toml = meson.project_source_root() / 'Cargo.toml' if get_option('default_library') == 'static' - extra_env += { - # Tell the pkg-config crate to think of all libraries as static - 'PKG_CONFIG_ALL_STATIC': '1', - # Tell the system-deps crate to process linker flag for static deps - 'SYSTEM_DEPS_LINK': 'static', - # Allow cross-compilation - 'PKG_CONFIG_ALLOW_CROSS': '1' - } + # Tell the pkg-config crate to think of all libraries as static + extra_env.set('PKG_CONFIG_ALL_STATIC', '1') + # Tell the system-deps crate to process linker flag for static deps + extra_env.set('SYSTEM_DEPS_LINK', 'static') + # Allow cross-compilation + extra_env.set('PKG_CONFIG_ALLOW_CROSS', 'static') endif pkg_config = find_program('pkgconfig', 'pkg-config', 'pkgconf', required: true) -extra_env += {'PKG_CONFIG': pkg_config.full_path()} +extra_env.set('PKG_CONFIG', pkg_config.full_path()) pkg_config_path = get_option('pkg_config_path') if pkg_config_path.length() > 0 - pathsep = ':' - if system == 'windows' - pathsep = ';' - endif - extra_env += {'PKG_CONFIG_PATH': pathsep.join(pkg_config_path)} + pathsep = build_machine.system() == 'windows' ? ';' : ':' + extra_env.set('PKG_CONFIG_PATH', pathsep.join(pkg_config_path)) endif # used in librsvg/meson.build. This is so that '#include ` will pick # up exactly that file from the source tree. includeinc = include_directories('include') +# Ideally, cc.get_argument_syntax() == 'msvc' should +# cover this, but 'clang' can mean GCC or MSVC-style +# depending on the env and/or flags on Windows +is_msvc_style = cc.get_define('_MSC_VER') != '' + # Set the suffixes up -if system == 'windows' - lib_prefix = '' +if host_system == 'windows' ext_dynamic = 'dll' - ext_import = 'dll.lib' - ext_static = 'lib' ext_exe = '.exe' -elif system == 'darwin' + if is_msvc_style + lib_prefix = '' + ext_import = 'dll.lib' + ext_static = 'lib' + else + lib_prefix = 'lib' + ext_import = 'dll.a' + ext_static = 'a' + endif +elif host_system == 'darwin' lib_prefix = 'lib' ext_dynamic = 'dylib' ext_static = 'a' @@ -243,18 +258,11 @@ cargo_wrapper_args = [ '--libdir', get_option('libdir'), ] -# Ideally, cc.get_argument_syntax() == 'msvc' should -# cover this, but 'clang' can mean GCC or MSVC-style -# depending on the env and/or flags on Windows -is_msvc_style = cc.get_define('_MSC_VER') != '' - if not get_option('debug') or \ (is_msvc_style and get_option('buildtype') == 'debugoptimized') cargo_wrapper_args += ['--release'] endif -target = get_option('triplet') - if target != '' cargo_wrapper_args += ['--target', target] endif diff --git a/meson/cargo_wrapper.py b/meson/cargo_wrapper.py index e99610521264a6a1652c597b54dd63381e586f54..d455d7f70ed9806a9537aa554c92d0fc0108ac7b 100755 --- a/meson/cargo_wrapper.py +++ b/meson/cargo_wrapper.py @@ -69,18 +69,15 @@ parser.add_argument("--libdir", required=True, help="Value of get_option('libdir g = parser.add_argument_group("Outputs") group = parser.add_mutually_exclusive_group(required=False) group.add_argument( - "--extensions", - nargs="*", - default=[], - help="filename extensions for libraries (so, a, dll, lib, dylib)", + "--extension", help="filename extension for the static library (a, lib)", ) group.add_argument("--bin", help="Name of binary to build") args = parser.parse_args() if args.command == 'test': - if args.extensions or args.bin: - raise ValueError('Cargo test does not take --extensions or --bin') + if args.extension or args.bin: + raise ValueError('Cargo test does not take --extension or --bin') cargo_target_dir = Path(args.project_build_root) / "target" @@ -145,10 +142,9 @@ subprocess.run(cargo_cmd, env=env, check=True) if args.command in ["cbuild", "build"]: # Copy so/dll/etc files to build dir - if args.extensions: - for ext in args.extensions: - for f in cargo_target_dir.glob(f"**/{buildtype}/*.{ext}"): - shutil.copy(f, args.current_build_dir) + if args.extension: + for f in cargo_target_dir.glob(f"**/{buildtype}/*.{args.extension}"): + shutil.copy(f, args.current_build_dir) # Copy binary and, if applicable, the corresponding .pdb file, to build dir else: binary = Path(cargo_target_output_dir / buildtype / args.bin) diff --git a/meson/query-rustc-native-libs.py b/meson/query-rustc-native-libs.py index 9c5cebac8e116f820d5f30ed29f67fd21fe0beb1..9b23de2b8860b2aff5f3ab7be50840b86c2692ae 100755 --- a/meson/query-rustc-native-libs.py +++ b/meson/query-rustc-native-libs.py @@ -1,50 +1,42 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser -from pathlib import Path -import re -import subprocess -import tempfile - -parser = ArgumentParser() - -parser.add_argument("RUSTC", type=Path, help="Path to rustc") - -if __name__ == "__main__": - args = parser.parse_args() - - with tempfile.TemporaryDirectory() as tmpdir: - dummy_rs = Path(tmpdir) / "dummy.rs" - dummy_rs.open("w", encoding="utf-8").write( - """ - use std::io::{Result}; - pub fn main() -> Result<()>{ - println!("Hello world!"); - Ok(()) - } - """ - ) - - native_static_libs = subprocess.run( - [ - args.RUSTC, - "--print=native-static-libs", - "--crate-type", - "staticlib", - dummy_rs, - ], - check=True, - capture_output=True, - text=True, - cwd=tmpdir, - ) - for i in native_static_libs.stderr.strip().splitlines(): - match = re.match(r".+native-static-libs: (.+)", i) - if match: - print( - " ".join( - set( - [lib.removesuffix(".lib") for lib in match.group(1).split()] - ) - ) - ) +#!/usr/bin/env python3 + +from argparse import ArgumentParser +from pathlib import Path +import os +import re +import subprocess +import tempfile + +parser = ArgumentParser() + +parser.add_argument("RUSTC", type=Path, help="Path to rustc") + +parser.add_argument("--target", help="Target triplet") + +if __name__ == "__main__": + args = parser.parse_args() + + rustc_cmd = [args.RUSTC, "--print=native-static-libs", "--crate-type", "staticlib"] + if args.target: + rustc_cmd.extend(['--target', args.target]) + + rustc_cmd.append(os.devnull) + + native_static_libs = subprocess.run( + rustc_cmd, + capture_output=True, + text=True, + ) + for i in native_static_libs.stderr.strip().splitlines(): + match = re.match(r".+native-static-libs: (.+)", i) + if match: + libs = match.group(1).split() + libs = [lib.removesuffix(".lib") for lib in libs] # msvc + libs = [lib.removeprefix("-l") for lib in libs] # msys2 + print( + " ".join( + set( + libs + ) + ) + ) diff --git a/rsvg/meson.build b/rsvg/meson.build index 3fe571962d8716895ff82505ebb8e95a5d421eb2..a882c20ddbe0907b9613624d9edc025b2fa3ce0f 100644 --- a/rsvg/meson.build +++ b/rsvg/meson.build @@ -87,7 +87,6 @@ rust_artifacts = custom_target( build_by_default: true, output: '@0@rsvg_@1@.@2@'.format(lib_prefix, librsvg_api_major, ext_static), console: true, - install: false, depend_files: library_sources + librsvg_c_sources, env: extra_env, command: [ @@ -97,8 +96,10 @@ rust_artifacts = custom_target( '--current-build-dir', '@OUTDIR@', '--current-source-dir', meson.current_source_dir(), '--packages', 'librsvg-c', - '--extensions', ext_static, - ] + '--extension', ext_static, + ], + install: get_option('default_library') == 'static', + install_dir: get_option('libdir'), ) librsvg_c_lib = rust_artifacts[0] @@ -109,9 +110,9 @@ makedef_args = [ '^rsvg_.', ] -if system in ['darwin', 'ios'] +if host_system in ['darwin', 'ios'] makedef_args += ['--os', 'darwin'] -elif system in ['windows', 'cygwin'] +elif host_system in ['windows', 'cygwin'] makedef_args += ['--os', 'win'] else makedef_args += ['--os', 'linux'] @@ -125,7 +126,7 @@ endif makedef_tool_args = [] -if cc.get_define('_MSC_VER') != '' +if is_msvc_style dumpbin = find_program('dumpbin', native: true) makedef_tool_args += ['--dumpbin', dumpbin] else @@ -150,8 +151,9 @@ librsvg_ver = custom_target( capture: true, ) -version_script = meson.current_build_dir() / '@0@.def'.format(librsvg_pc) -if host_machine.system() in ['darwin', 'ios'] +version_script = meson.current_build_dir() / '@0@.ver'.format(librsvg_pc) + +if host_system in ['darwin', 'ios'] vflag = '-Wl,-exported_symbols_list,@0@'.format(version_script) else vflag = '-Wl,--version-script,@0@'.format(version_script) @@ -166,9 +168,13 @@ endif # if the library is a Meson generated target. # No further flags are needed under MSVC, because LINK will already strip # the library by default. +# +# Also check for -Bsymbolic-functions linker flag used to avoid +# intra-library PLT jumps, if available. strip_link_args = cc.get_supported_link_arguments( '-Wl,-dead_strip', - '-Wl,--gc-sections' + '-Wl,--gc-sections', + '-Wl,-Bsymbolic-functions', ) link_args = cc.get_supported_link_arguments([vflag]) + strip_link_args @@ -199,18 +205,22 @@ else ) endif -librsvg_lib = shared_library( - rsvg_ver, - rsvg_dummy, - link_whole: librsvg_c_lib, - link_args: link_args, - link_depends: librsvg_ver, - dependencies: library_dependencies, - include_directories: [includeinc], - vs_module_defs: librsvg_ver, # librsvg_def - install: true, - version: meson.project_version() # it's not exact as m4 -) +if get_option('default_library') == 'shared' + librsvg_lib = shared_library( + rsvg_ver, + rsvg_dummy, + link_whole: librsvg_c_lib, + link_args: link_args, + link_depends: librsvg_ver, + dependencies: library_dependencies, + include_directories: [includeinc], + vs_module_defs: librsvg_def, + install: true, + version: meson.project_version() # it's not exact as m4 + ) +else + librsvg_lib = librsvg_c_lib +endif # This is the main dependency to use for tests; it means "link to the library we just built" librsvg_dep = declare_dependency( @@ -228,13 +238,15 @@ librsvg_c_pc = pkg.generate( description : 'library that renders svg files', libraries : librsvg_lib, subdirs: librsvg_pc, + requires: library_dependencies_sole, + libraries_private: private_dependencies, ) if build_gir.allowed() env = environment() - if system in ['darwin', 'ios'] + if host_system in ['darwin', 'ios'] var = 'DYLD_LIBRARY_PATH' - elif system in ['windows', 'cygwin'] + elif host_system in ['windows', 'cygwin'] var = 'PATH' else var = 'LD_LIBRARY_PATH' @@ -250,7 +262,7 @@ if build_gir.allowed() check: true, ) env.set(var, current_library_path.stdout().strip()) - if system == 'windows' + if host_system == 'windows' env.prepend('PATH', meson.current_build_dir() / 'rsvg') foreach i: library_dependencies_sole x = i.get_variable(pkgconfig: 'bindir', default_value: '') @@ -286,8 +298,20 @@ if build_gir.allowed() ] endif + if get_option('default_library') == 'shared' + librsvg_gir = librsvg_lib + else + librsvg_gir = shared_library( + 'rsvg-gir', + rsvg_dummy, + link_whole: librsvg_c_lib, + dependencies: library_dependencies, + include_directories: [includeinc], + ) + endif + rsvg_gir = gnome.generate_gir( - librsvg_lib, + librsvg_gir, namespace: 'Rsvg', nsversion: '2.0', symbol_prefix: [ 'rsvg', 'librsvg' ], @@ -324,9 +348,6 @@ if build_tests.allowed() 'src/test_utils/reference_utils.rs', ) - # HACK: Meson tests don't take OptionString nor ExternalProgram - c_w_a = [] - test( 'Rust tests', cargo_wrapper, @@ -338,6 +359,6 @@ if build_tests.allowed() '--current-source-dir', meson.current_source_dir(), ], env: extra_env, - depends: librsvg_lib + depends: get_option('default_library') == 'shared' ? librsvg_lib : rust_artifacts ) endif