Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modules/gnome, modules/Python: Allow injecting RPATH flags through LDFLAGS if needed #14238

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mesonbuild/dependencies/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ def __init__(self, name: str, environment: 'Environment',
# Add rpath, will be de-duplicated if necessary
if framework_prefix.startswith('/Applications/Xcode.app/'):
self.link_args += ['-Wl,-rpath,' + framework_prefix]
self.raw_link_args += ['-Wl,-rpath,' + framework_prefix]

class PythonFrameworkDependency(ExtraFrameworkDependency, _PythonDependencyBase):

Expand Down
28 changes: 17 additions & 11 deletions mesonbuild/modules/gnome.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,14 +702,14 @@ def _get_dependencies_flags_raw(
lib_dir = os.path.dirname(flag)
external_ldflags.update([f'-L{lib_dir}'])
if include_rpath:
external_ldflags.update([f'-Wl,-rpath {lib_dir}'])
external_ldflags.update([f'-Wl,-rpath,{lib_dir}'])
libname = os.path.basename(flag)
if libname.startswith("lib"):
libname = libname[3:]
libname = libname.split(".so")[0]
flag = f"-l{libname}"
# FIXME: Hack to avoid passing some compiler options in
if flag.startswith("-W"):
if flag.startswith("-W") and not flag.startswith('-Wl,-rpath'):
continue
# If it's a framework arg, slurp the framework name too
# to preserve the order of arguments
Expand Down Expand Up @@ -962,6 +962,7 @@ def _make_gir_target(
scan_command: T.Sequence[T.Union['FileOrString', Executable, ExternalProgram, OverrideProgram]],
generated_files: T.Sequence[T.Union[str, mesonlib.File, CustomTarget, CustomTargetIndex, GeneratedList]],
depends: T.Sequence[T.Union['FileOrString', build.BuildTarget, 'build.GeneratedTypes', build.StructuredSources]],
env_flags: T.Sequence[str],
kwargs: T.Dict[str, T.Any]) -> GirTarget:
install = kwargs['install_gir']
if install is None:
Expand All @@ -982,6 +983,7 @@ def _make_gir_target(
# g-ir-scanner uses Python's distutils to find the compiler, which uses 'CC'
cc_exelist = state.environment.coredata.compilers.host['c'].get_exelist()
run_env.set('CC', [quote_arg(x) for x in cc_exelist], ' ')
run_env.set('CFLAGS', [quote_arg(x) for x in env_flags], ' ')
run_env.merge(kwargs['env'])

return GirTarget(
Expand Down Expand Up @@ -1088,11 +1090,12 @@ def _get_scanner_cflags(cflags: T.Iterable[str]) -> T.Iterable[str]:
yield f

@staticmethod
def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> T.Iterable[str]:
def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> tuple[list[str], list[str]]:
'g-ir-scanner only accepts -L/-l; must ignore -F and other linker flags'
for f in ldflags:
if f.startswith(('-L', '-l', '--extra-library')):
yield f
return (
[f for f in ldflags if f.startswith(('-L', '-l', '--extra-library'))],
[f for f in ldflags if f.startswith(('-Wl,-rpath'))],
)

@typed_pos_args('gnome.generate_gir', varargs=(Executable, build.SharedLibrary, build.StaticLibrary), min_varargs=1)
@typed_kwargs(
Expand Down Expand Up @@ -1161,11 +1164,14 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut
scan_cflags += list(self._get_scanner_cflags(dep_cflags))
scan_cflags += list(self._get_scanner_cflags(self._get_external_args_for_langs(state, [lc[0] for lc in langs_compilers])))
scan_internal_ldflags = []
scan_internal_ldflags += list(self._get_scanner_ldflags(internal_ldflags))
scan_internal_ldflags += list(self._get_scanner_ldflags(dep_internal_ldflags))
scan_external_ldflags = []
scan_external_ldflags += list(self._get_scanner_ldflags(external_ldflags))
scan_external_ldflags += list(self._get_scanner_ldflags(dep_external_ldflags))
scan_env_ldflags = []
for cli_flags, env_flags in (self._get_scanner_ldflags(internal_ldflags), self._get_scanner_ldflags(dep_internal_ldflags)):
scan_internal_ldflags += cli_flags
scan_env_ldflags = env_flags
for cli_flags, env_flags in (self._get_scanner_ldflags(external_ldflags), self._get_scanner_ldflags(dep_external_ldflags)):
scan_external_ldflags += cli_flags
scan_env_ldflags = env_flags
girtargets_inc_dirs = self._get_gir_targets_inc_dirs(girtargets)
inc_dirs = kwargs['include_directories']

Expand Down Expand Up @@ -1216,7 +1222,7 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut
generated_files = [f for f in libsources if isinstance(f, (GeneratedList, CustomTarget, CustomTargetIndex))]

scan_target = self._make_gir_target(
state, girfile, scan_command, generated_files, depends,
state, girfile, scan_command, generated_files, depends, scan_env_ldflags,
# We have to cast here because mypy can't figure this out
T.cast('T.Dict[str, T.Any]', kwargs))

Expand Down
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/dep1/dep1.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
EXPORTS
meson_dep1_new
meson_dep1_just_return_it
meson_dep1_get_type
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
EXPORTS
meson_dep2_new
meson_dep2_return_message
meson_dep2_get_type
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ dep2lib = shared_library(
'dep2lib',
sources : dep2sources,
dependencies : gobj,
vs_module_defs: 'dep2.def',
install : true
)

envdata.append('GI_TYPELIB_DIR', dep2lib.outdir())

dep2gir = gnome.generate_gir(
dep2lib,
sources : dep2sources,
env : envdata,
nsversion : '1.0',
namespace : 'MesonDep2',
symbol_prefix : 'meson',
Expand Down
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
EXPORTS
meson_dep3_new
meson_dep3_return_message
meson_dep3_get_type
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ dep3lib = shared_library(
'dep3lib',
sources : dep3sources,
dependencies : gobj,
vs_module_defs: 'dep3.def',
install : true
)

envdata.append('GI_TYPELIB_DIR', dep3lib.outdir())

dep3gir = gnome.generate_gir(
dep3lib,
sources : dep3sources,
env : envdata,
nsversion : '1.0',
namespace : 'MesonDep3',
symbol_prefix : 'meson',
Expand Down
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/dep1/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ dep1lib = shared_library(
'dep1lib',
sources : dep1sources,
dependencies : gobj,
vs_module_defs: 'dep1.def',
install : true
)

envdata.append('GI_TYPELIB_DIR', dep1lib.outdir())

# But the gir does need it because it we use the MesonDep2* structure defined
# in the header
dep1gir = gnome.generate_gir(
dep1lib,
sources : dep1sources,
env : envdata,
nsversion : '1.0',
namespace : 'MesonDep1',
symbol_prefix : 'meson',
Expand Down
51 changes: 51 additions & 0 deletions test cases/frameworks/7 gnome/gir/meson-python-sample.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "meson-python-sample.h"

#include <Python.h>

struct _MesonPythonSample
{
GObject parent_instance;
};

G_DEFINE_TYPE (MesonPythonSample, meson_python_sample, G_TYPE_OBJECT)

/**
* meson_python_sample_new:
*
* Allocates a new #MesonPythonSample.
*
* Returns: (transfer full): a #MesonPythonSample.
*/
MesonPythonSample *
meson_python_sample_new (void)
{
return g_object_new (MESON_TYPE_PYTHON_SAMPLE, NULL);
}

static void
meson_python_sample_class_init (MesonPythonSampleClass *klass)
{
if (!Py_IsInitialized ()) {
Py_Initialize ();
Py_Finalize ();
}
}

static void
meson_python_sample_init (MesonPythonSample *self)
{
}

/**
* meson_python_sample_print_message:
* @self: a #MesonSample2.
*
* Prints Hello.
*
* Returns: Nothing.
*/
void
meson_python_sample_print_message (MesonPythonSample *self)
{
g_print ("Message: Hello\n");
}
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/meson-python-sample.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
EXPORTS
meson_python_sample_new
meson_python_sample_print_message
meson_python_sample_get_type
17 changes: 17 additions & 0 deletions test cases/frameworks/7 gnome/gir/meson-python-sample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef MESON_PYTHON_SAMPLE_H
#define MESON_PYTHON_SAMPLE_H

#include <glib-object.h>

G_BEGIN_DECLS

#define MESON_TYPE_PYTHON_SAMPLE (meson_python_sample_get_type())

G_DECLARE_FINAL_TYPE (MesonPythonSample, meson_python_sample, MESON, SAMPLE, GObject)

MesonPythonSample *meson_python_sample_new (void);
void meson_python_sample_print_message (MesonPythonSample *self);

G_END_DECLS

#endif /* MESON_PYTHON_SAMPLE_H */
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/meson-sample.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
EXPORTS
meson_sample_new
meson_sample_print_message
meson_sample_get_type
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/gir/meson-sample2.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
EXPORTS
meson_sample2_new
meson_sample2_print_message
meson_sample2_get_type
50 changes: 39 additions & 11 deletions test cases/frameworks/7 gnome/gir/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ subdir('dep1')

libsources = ['meson-sample.c', 'meson-sample.h']
lib2sources = ['meson-sample2.c', 'meson-sample2.h']
pythonsources = ['meson-python-sample.c', 'meson-python-sample.h']

gen_source = custom_target(
'meson_sample3.h',
Expand All @@ -16,16 +17,35 @@ girlib = shared_library(
sources : libsources,
c_args: '-DMESON_TEST_2',
dependencies : [gobj, dep1_dep],
vs_module_defs: 'meson-sample.def',
install : true
)

girlib2 = shared_library(
'gir_lib2',
sources : lib2sources,
dependencies : [gobj],
vs_module_defs: 'meson-sample2.def',
install : true
)

if get_option('b_sanitizer') == 'none'
py3_dep = py3.dependency(embed: true)
else
warning('Python 3 test not supported with b_sanitizer')
py3_dep = disabler()
endif

if py3_dep.found()
pythongirlib = shared_library(
'python_gir_lib',
sources: pythonsources,
dependencies: [gobj, py3_dep],
vs_module_defs: 'meson-python-sample.def',
install: true
)
endif

girexe = executable(
'girprog',
sources : 'prog.c',
Expand All @@ -36,28 +56,36 @@ girexe = executable(

fake_dep = dependency('no-way-this-exists', required: false)

envdata.append('GI_TYPELIB_PATH', girlib.outdir())
# g-ir-scanner ignores CFLAGS for MSVC
flags_dep_for_msvc = declare_dependency(
compile_args: ['-DMESON_TEST_2']
)

girs = [girlib, girlib2]
girs_sources = [libsources, lib2sources, gen_source]
girs_deps = [fake_dep, dep1_dep, flags_dep_for_msvc]
if py3_dep.found()
girs += [pythongirlib]
girs_sources += [pythonsources]
girs_deps += [py3_dep]
endif

gnome.generate_gir(
girlib, girlib2,
sources : [libsources, lib2sources, gen_source],
env : {'CPPFLAGS': '-DMESON_TEST_2'},
girs,
sources : girs_sources,
env : envdata,
nsversion : '1.0',
namespace : 'Meson',
symbol_prefix : 'meson',
identifier_prefix : 'Meson',
includes : ['GObject-2.0', 'MesonDep1-1.0'],
# dep1_dep pulls in dep2_dep for us
dependencies : [[fake_dep, dep1_dep]],
dependencies : girs_deps,
install : true,
build_by_default : true,
)

test('gobject introspection/c', girexe)
gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir(), dep3lib.outdir()])
envdata = environment()
envdata.append('GI_TYPELIB_PATH', gir_paths, separator : ':')
envdata.append('LD_LIBRARY_PATH', gir_paths)
if ['windows', 'cygwin'].contains(host_machine.system())
envdata.append('PATH', gir_paths)
endif
test('gobject introspection/py', find_program('prog.py'),
env : envdata)
37 changes: 32 additions & 5 deletions test cases/frameworks/7 gnome/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project('gobject-introspection', 'c')
project('gobject-introspection', 'c', meson_version: '>= 1.2.0')

copyfile = find_program('copyfile.py')
copyfile_gen = generator(copyfile,
Expand All @@ -15,8 +15,8 @@ if not gir.found()
error('MESON_SKIP_TEST gobject-introspection not found.')
endif

python3 = import('python3')
py3 = python3.find_python()
python3 = import('python')
py3 = python3.find_installation()
if run_command(py3, '-c', 'import gi;', check: false).returncode() != 0
error('MESON_SKIP_TEST python3-gi not found')
endif
Expand All @@ -30,7 +30,6 @@ if cc.get_id() == 'intel'
add_global_arguments('-wd2282', language : 'c')
endif

py3 = import('python3').find_python()
pycode = '''import os, sys
if "MESON_UNIT_TEST_PRETEND_GLIB_OLD" in os.environ:
sys.exit(0)
Expand All @@ -45,7 +44,7 @@ endif

gnome = import('gnome')
gio = dependency('gio-2.0')
giounix = dependency('gio-unix-2.0')
giounix = dependency('gio-unix-2.0', required: host_machine.system() != 'windows', disabler: true)
glib = dependency('glib-2.0')
gobj = dependency('gobject-2.0')
gir = dependency('gobject-introspection-1.0')
Expand All @@ -63,6 +62,34 @@ endif
# Test that static deps don't error out when static libraries aren't found
glib_static = dependency('glib-2.0', static : true)


envdata = environment()
if ['darwin', 'ios'].contains(host_machine.system())
var = 'DYLD_LIBRARY_PATH'
elif ['windows', 'cygwin'].contains(host_machine.system())
var = 'PATH'
else
var = 'LD_LIBRARY_PATH'
endif

current_library_path = run_command(
[
py3,
'-c',
'import os; print(os.environ["@0@"]) if "@0@" in os.environ else ""'.format(var)
],
capture: true,
check: true,
)

envdata.set(var, current_library_path.stdout().strip())
if ['windows', 'cygwin'].contains(host_machine.system())
bindir = gir.get_variable(pkgconfig: 'bindir', default_value: '')
if bindir != ''
envdata.prepend('PATH', bindir)
endif
endif

subdir('resources-data')
subdir('resources')
subdir('gir')
Expand Down
Loading
Loading