Skip to content

cmake/interpreter: propagate object library pie flag#15958

Open
pobrn wants to merge 1 commit into
mesonbuild:masterfrom
pobrn:cmake_propagate_object_library_pie
Open

cmake/interpreter: propagate object library pie flag#15958
pobrn wants to merge 1 commit into
mesonbuild:masterfrom
pobrn:cmake_propagate_object_library_pie

Conversation

@pobrn

@pobrn pobrn commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

If the target has no ordinary or generated sources, then propagate the "pie" flag from the object libraries. Otherwise it will not use position independent code, making it impossible to link into shared libraries.

Fixes #10764


No idea if this is on the right path, or what else could be done. Another potentially problematic thing is that meson forces each OBJECT_LIBRARY to have pie==True, but cmake does not do that, I think.

If the target has no ordinary or generated sources, then propagate
the "pie" flag from the object libraries. Otherwise it will not
use position independent code, making it impossible to link into
shared libraries.

Fixes mesonbuild#10764
@pobrn pobrn requested review from jpakkane and mensinda as code owners June 26, 2026 12:03
@pobrn

pobrn commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Without this change meson says:

test cases/cmake/29 object library pic/meson.build:7:0: ERROR: Can't link non-PIC static library 'cmTestLib' into shared library 'slib'. Use the 'pic' option to static_library to build with PIC.

but I feel like there is inadequate handling of this in meson. E.g. consider:

==> meson.build <==
project('asd', 'c')

x = static_library('x', 'x.c', pic: false)
shared_library('z', 'z.c', objects: x.extract_all_objects(recursive: true))

==> x.c <==
extern int X;

int getX() { return X; }

==> z.c <==
extern int getX();

int X;

int thing() { return getX(); }

and then this is accepted without any complaints:

$ meson setup build
$ $ ninja -C build
ninja: Entering directory `build'
[4/4] Linking target libz.so
FAILED: [code=1] libz.so 
cc  -o libz.so libx.a.p/x.c.o libz.so.p/z.c.o -Wl,--as-needed -Wl,--no-undefined -shared -fPIC -Wl,-soname,libz.so
/usr/bin/ld: libx.a.p/x.c.o: warning: relocation against `X' in read-only section `.text'
/usr/bin/ld: libx.a.p/x.c.o: relocation R_X86_64_PC32 against symbol `X' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

It seems to me that the "pic" state should be tracked on a per-object-file basis. And then the #10764 would just disappear.

@dcbaker

dcbaker commented Jun 26, 2026

Copy link
Copy Markdown
Member

It seems to me that the "pic" state should be tracked on a per-object-file basis.

It would be pretty trivial to add a pic field to ExtractedObjects, which we could then fill out when we extract objects from a static archive. objects can also be represented by File objects, which complicates things somewhat, but it would still be an improvement to track it in ExtractedObjects.

@dcbaker

dcbaker commented Jun 26, 2026

Copy link
Copy Markdown
Member

I'm also wondering if the best solution is to represent object_library as a static library with a direct call to extract_all_objects()?

@pobrn

pobrn commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

It would be pretty trivial to add a pic field to ExtractedObjects, which we could then fill out when we extract objects from a static archive.

But what if it contains objects from both a pic and a non-pic static library? Will that be disallowed? If not, then isn't it necessary to track it on a per-file basis?

I'm also wondering if the best solution is to represent object_library as a static library with a direct call to extract_all_objects()?

What would be the alternatives?

@dcbaker

dcbaker commented Jun 29, 2026

Copy link
Copy Markdown
Member

But what if it contains objects from both a pic and a non-pic static library? Will that be disallowed? If not, then isn't it necessary to track it on a per-file basis?

I can't remember all of the linking rules around mixing PIE and non-PIE objects, IIRC you can treat PIE objects as non-PIE which would mean mixing PIE and non-PIE would just create a non-PIE ExtractedObjects, just like it should create a non-PIE static library?

The problem here is that Meson doesn't really have per-object granularity in our IR, targets really are the base object of our model. See also why repeated calls for per-object compile flags have been met with resistance, it would be really hard to implement, and it would go against part of our design.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Meson does not detect position independent flag on CMake static library

2 participants