-no-pie in FLTK Libraries build.

已查看 25 次
跳至第一个未读帖子

Rob McDonald

未读,
2024年3月17日 01:52:053月17日
收件人 fltk.general
In addition to building an executable binary of my application, I also use SWIG to wrap my program to be called from Python.

SWIG sets up a shared object library that gets loaded by Python.  This has to be a shared object because the alternative would be a custom built version of Python with my program (and FLTK) statically linked into it.  No good can come from that.

I have two versions of this wrapper -- one without graphics and one with the full GUI and OpenGL graphics embedded.  We can launch our program's full GUI from within Python -- but that isn't the point of the story.

When we create this shared object, we try to statically link everything we can -- including FLTK.  So, we're statically linking FLTK into a shared library.

This has generally worked on Windows, MacOS, and Linux for a while.  For Linux, I've worked with Ubuntu 18 and 20 and RHEL7.  I recently started working with RHEL9.

For some reason, on RHEL9, when I go to link the Python wrapper with FLTK into the shared object, I get the following error:

/usr/bin/ld: crt1.0: in function `_start': (.text+0x1b): undefined reference to `main’
collect2: error: ld returned 1 exit status

Of course, since this is a shared object, I don't have a main().

I dug into the details of the linker command and eventually discovered that it included a '-no-pie' that if removed, linking would proceed as desired.

After considerable digging, I figured out that the '-no-pie' is coming from fltk:fltk.  I used this utility (discussed previously here) to peer into everything in this target.  The output is below:

fltk::fltk BINARY_DIR = /home/somepath/build/gccrel-VSP/src
fltk::fltk IMPORTED = TRUE
fltk::fltk IMPORTED_CONFIGURATIONS = RELEASE
fltk::fltk INTERFACE_INCLUDE_DIRECTORIES = /home/somepath/build/gccrel-Libs/FLTK-prefix/include
fltk::fltk INTERFACE_LINK_DIRECTORIES = /home/somepath/build/gccrel-Libs/FLTK-prefix/lib
fltk::fltk INTERFACE_LINK_LIBRARIES = /usr/lib64/libdl.a;/usr/lib64/libX11.so;/usr/lib64/libXext.so;/usr/lib64/libXinerama.so;/usr/lib64/libXfixes.so;/usr/lib64/libXcursor.so;/usr/lib64/libXrender.so;/usr/lib64/libpango-1.0.so;/usr/lib64/libpangocairo-1.0.so;/usr/lib64/libcairo.so;/usr/lib64/libgobject-2.0.so;/usr/lib64/libpangoxft-1.0.so;/usr/lib64/libXft.so;/usr/lib64/libfontconfig.so;-lwayland-egl -lEGL;-L/usr/lib64;-lgtk-3;-lgdk-3;-lpangocairo-1.0;-lpango-1.0;-lharfbuzz;-latk-1.0;-lcairo-gobject;-lcairo;-lgdk_pixbuf-2.0;-lgio-2.0;-lgobject-2.0;-lglib-2.0;-lwayland-cursor -lwayland-client -lxkbcommon -ldl;-L/usr/lib64;-ldbus-1;-no-pie
fltk::fltk LOCATION = /home/somepath/build/gccrel-Libs/FLTK-prefix/lib64/libfltk.a
fltk::fltk LOCATION_Release = /home/somepath/build/gccrel-Libs/FLTK-prefix/lib64/libfltk.a
fltk::fltk MACOSX_PACKAGE_LOCATION = /home/somepath/build/gccrel-Libs/FLTK-prefix/lib64/libfltk.a
fltk::fltk NAME = fltk::fltk
fltk::fltk SOURCE_DIR = /home/somepath/repo/src
fltk::fltk SYSTEM = ON
fltk::fltk TYPE = STATIC_LIBRARY
fltk::fltk VS_DEPLOYMENT_LOCATION = /home/somepath/build/gccrel-Libs/FLTK-prefix/lib64/libfltk.a


Notice that INTERFACE_LINK_LIBRARIES contains -no-pie.  Notably, this is a linker option, not a library.

The FLTKConfig.cmake.in file contains no reference to -no-pie.  So I dug into the FLTK source, and there are three hits.  One in ./configure.ac, one in libdecor, and the relevant one in /src/CMakeLists.txt:768.

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)
list(APPEND OPTIONAL_LIBS "-no-pie")
endif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)

This is perhaps a reasonable thing to do if you assume that fltk is going to be statically linked into an executable program.  It does not work in my situation where fltk is statically linked into a shared library.

I am also not certain how appropriate it is that this 'leaks' its way into the fltk:fltk target.  Perhaps it must be this way.  I don't fully understand all the mechanisms at work.

At a minimum, I'm pretty sure this should be assigned to a target LINK_OPTIONS property.  Or, perhaps even better, a target POSITION_INDEPENDENT_CODE property (rather than appended to a string list of library names).

I don't know the long-term fix for this.

In the short term, I'm going to attempt something like

get_target_property(templist fltk:fltk INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM templist "-no-pie")
set_target_properties(fltk:fltk PROPERTIES INTERFACE_LINK_LIBRARIES ${templist})

Or something like that.

Rob

Albrecht Schlosser

未读,
2024年3月17日 09:43:473月17日
收件人 fltkg...@googlegroups.com
On 3/17/24 06:52 Rob McDonald wrote:
In addition to building an executable binary of my application, I also use SWIG to wrap my program to be called from Python.

SWIG sets up a shared object library that gets loaded by Python. ...

Noted, but I can't comment on anything related to SWIG or Python.

When we create this shared object, we try to statically link everything we can -- including FLTK.  So, we're statically linking FLTK into a shared library.
For some reason, on RHEL9, when I go to link the Python wrapper with FLTK into the shared object, I get the following error:

/usr/bin/ld: crt1.0: in function `_start': (.text+0x1b): undefined reference to `main’
collect2: error: ld returned 1 exit status

Of course, since this is a shared object, I don't have a main().

I dug into the details of the linker command and eventually discovered that it included a '-no-pie' that if removed, linking would proceed as desired.

OK, I believe this is a bug in our CMake files... see below.

After considerable digging, I figured out that the '-no-pie' is coming from fltk:fltk.  I used this utility (discussed previously here) to peer into everything in this target.  The output is below:

[...]

fltk::fltk INTERFACE_LINK_LIBRARIES = /usr/lib64/libdl.a;/usr/lib64/libX11.so;/usr/lib64/libXext.so;/usr/lib64/libXinerama.so;/usr/lib64/libXfixes.so;/usr/lib64/libXcursor.so;/usr/lib64/libXrender.so;/usr/lib64/libpango-1.0.so;/usr/lib64/libpangocairo-1.0.so;/usr/lib64/libcairo.so;/usr/lib64/libgobject-2.0.so;/usr/lib64/libpangoxft-1.0.so;/usr/lib64/libXft.so;/usr/lib64/libfontconfig.so;-lwayland-egl -lEGL;-L/usr/lib64;-lgtk-3;-lgdk-3;-lpangocairo-1.0;-lpango-1.0;-lharfbuzz;-latk-1.0;-lcairo-gobject;-lcairo;-lgdk_pixbuf-2.0;-lgio-2.0;-lgobject-2.0;-lglib-2.0;-lwayland-cursor -lwayland-client -lxkbcommon -ldl;-L/usr/lib64;-ldbus-1;-no-pie
[...]

Notice that INTERFACE_LINK_LIBRARIES contains -no-pie.  Notably, this is a linker option, not a library.

You're IMHO correct, this shouldn't be there.


The FLTKConfig.cmake.in file contains no reference to -no-pie.  So I dug into the FLTK source, and there are three hits.  One in ./configure.ac, one in libdecor, and the relevant one in /src/CMakeLists.txt:768.

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)
list(APPEND OPTIONAL_LIBS "-no-pie")
endif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)

This is perhaps a reasonable thing to do if you assume that fltk is going to be statically linked into an executable program.  It does not work in my situation where fltk is statically linked into a shared library.

I am also not certain how appropriate it is that this 'leaks' its way into the fltk:fltk target.

That's probably due to some "old code" leaking into the "Modern CMake" approach. I didn't have the time yet to rewrite everything and I'm aware that there's still something to do.


Perhaps it must be this way.  I don't fully understand all the mechanisms at work.

I don't think that it must be this way, I'll check this...


At a minimum, I'm pretty sure this should be assigned to a target LINK_OPTIONS property.  Or, perhaps even better, a target POSITION_INDEPENDENT_CODE property (rather than appended to a string list of library names).

Yep, that's correct, and very likely it should be added to PRIVATE CMake properties rather than PUBLIC, hence it would not affect your build at all (PRIVATE properties are not included in INTERFACE_* properties).


I don't know the long-term fix for this.

I'll check if I can fix this.


In the short term, I'm going to attempt something like

get_target_property(templist fltk:fltk INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM templist "-no-pie")
set_target_properties(fltk:fltk PROPERTIES INTERFACE_LINK_LIBRARIES ${templist})

Or something like that.

Might work but it's only a workaround.

Rob McDonald

未读,
2024年3月17日 14:24:093月17日
收件人 fltk.general
Noted, but I can't comment on anything related to SWIG or Python.

Understood -- just trying to provide some context as to the weird thing I'm doing.... 


That's probably due to some "old code" leaking into the "Modern CMake" approach. I didn't have the time yet to rewrite everything and I'm aware that there's still something to do.

I figured this would be the root cause.

 
At a minimum, I'm pretty sure this should be assigned to a target LINK_OPTIONS property.  Or, perhaps even better, a target POSITION_INDEPENDENT_CODE property (rather than appended to a string list of library names).

Yep, that's correct, and very likely it should be added to PRIVATE CMake properties rather than PUBLIC, hence it would not affect your build at all (PRIVATE properties are not included in INTERFACE_* properties).

This makes a lot of sense. 

I don't know the long-term fix for this.

I'll check if I can fix this.

Thanks much. 

In the short term, I'm going to attempt something like

get_target_property(templist fltk:fltk INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM templist "-no-pie")
set_target_properties(fltk:fltk PROPERTIES INTERFACE_LINK_LIBRARIES ${templist})

Or something like that.

Might work but it's only a workaround.

Exactly.

Rob
 

Albrecht Schlosser

未读,
2024年3月17日 18:09:573月17日
收件人 fltkg...@googlegroups.com
On 3/17/24 19:24 Rob McDonald wrote:

That's probably due to some "old code" leaking into the "Modern CMake" approach. I didn't have the time yet to rewrite everything and I'm aware that there's still something to do.

I figured this would be the root cause.

Very likely, I see pretty much chaos and inconsistent code in this area.  :-(

I started working on this but it will take some time - definitely not today.


In the short term, I'm going to attempt something like

get_target_property(templist fltk:fltk INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM templist "-no-pie")
set_target_properties(fltk:fltk PROPERTIES INTERFACE_LINK_LIBRARIES ${templist})

Or something like that.

Might work but it's only a workaround.

Exactly.

For now I have a short request to test: can you please comment out (or delete) the 3 lines of code in src/CMakeLists.txt that set the '-no-pie' flag in the FLTK code and try again w/o the assignment?

   767	  if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)
   768	    list(APPEND OPTIONAL_LIBS "-no-pie")
   769	  endif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)

I believe that we can remove that '-no-pie' entirely but I'm still investigating why it was introduced in the first place. The condition used for the assignment (... AND NOT FLTK_BUILD_SHARED_LIBS) is wrong anyway in this context.


Alternatively (or additionally) you could try changing the two lines that assign OPTIONAL_LIBS as PUBLIC to PRIVATE:
   775	target_link_libraries(fltk PUBLIC ${OPTIONAL_LIBS})
   831	  target_link_libraries(fltk-shared PUBLIC ${OPTIONAL_LIBS})

s/PUBLIC/PRIVATE/

There's another line (907) for MSVC that shouldn't matter for now, you can leave that one as-is.

I tried all this myself and didn't find any drawbacks but I'm still working on a more complete solution.

I'd appreciate if you could test and report back, but there's no need to hurry. I won't be able to work on it today, I need some sleep. If you could do it in your TZ's "today" so I could find it here tomorrow that would be great. TIA

PS: I'm also investigating an option like "DISABLE_GLU" to solve your other issue but I'll reply to the other thread tomorrow.

Rob McDonald

未读,
2024年3月18日 00:53:003月18日
收件人 fltk.general
On Sunday, March 17, 2024 at 3:09:57 PM UTC-7 Albrecht-S wrote:
Very likely, I see pretty much chaos and inconsistent code in this area.  :-(

I started working on this but it will take some time - definitely not today.

No worries.  I have my workarounds and am happy to be patient to remove them once it gets settled.  It looks like this may be the tip of a larger iceberg in certain ways.
 

For now I have a short request to test: can you please comment out (or delete) the 3 lines of code in src/CMakeLists.txt that set the '-no-pie' flag in the FLTK code and try again w/o the assignment?

767 if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS) 768 list(APPEND OPTIONAL_LIBS "-no-pie") 769 endif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)

Removing these lines works exactly as you would expect.  Everything else is the same, the '-no-pie' does not come through to my application, everything works.

I believe that we can remove that '-no-pie' entirely but I'm still investigating why it was introduced in the first place. The condition used for the assignment (... AND NOT FLTK_BUILD_SHARED_LIBS) is wrong anyway in this context.


Alternatively (or additionally) you could try changing the two lines that assign OPTIONAL_LIBS as PUBLIC to PRIVATE:
775 target_link_libraries(fltk PUBLIC ${OPTIONAL_LIBS}) 831 target_link_libraries(fltk-shared PUBLIC ${OPTIONAL_LIBS}) s/PUBLIC/PRIVATE/

I made this change as well, when I did so, the INTERFACE_LINK_LIBRARIES target property changed from:

/usr/lib64/libdl.a/usr/lib64/libX11.so/usr/lib64/libXext.so/usr/lib64/libXinerama.so/usr/lib64/libXfixes.so/usr/lib64/libXcursor.so/usr/lib64/libXrender.so/usr/lib64/libpango-1.0.so/usr/lib64/libpangocairo-1.0.so/usr/lib64/libcairo.so/usr/lib64/libgobject-2.0.so/usr/lib64/libpangoxft-1.0.so/usr/lib64/libXft.so/usr/lib64/libfontconfig.so-lwayland-egl -lEGL-L/usr/lib64-lgtk-3-lgdk-3-lpangocairo-1.0-lpango-1.0-lharfbuzz-latk-1.0-lcairo-gobject-lcairo-lgdk_pixbuf-2.0-lgio-2.0-lgobject-2.0-lglib-2.0-lwayland-cursor -lwayland-client -lxkbcommon -ldl-L/usr/lib64-ldbus-1-no-pie

To:

/usr/lib64/libdl.a/usr/lib64/libX11.so/usr/lib64/libXext.so/usr/lib64/libXinerama.so/usr/lib64/libXfixes.so/usr/lib64/libXcursor.so/usr/lib64/libXrender.so/usr/lib64/libpango-1.0.so/usr/lib64/libpangocairo-1.0.so/usr/lib64/libcairo.so/usr/lib64/libgobject-2.0.so/usr/lib64/libpangoxft-1.0.so/usr/lib64/libXft.so/usr/lib64/libfontconfig.so-lwayland-egl -lEGL-L/usr/lib64$<LINK_ONLY:-lgtk-3>$<LINK_ONLY:-lgdk-3>$<LINK_ONLY:-lpangocairo-1.0>$<LINK_ONLY:-lpango-1.0>$<LINK_ONLY:-lharfbuzz>$<LINK_ONLY:-latk-1.0>$<LINK_ONLY:-lcairo-gobject>$<LINK_ONLY:-lcairo>$<LINK_ONLY:-lgdk_pixbuf-2.0>$<LINK_ONLY:-lgio-2.0>$<LINK_ONLY:-lgobject-2.0>$<LINK_ONLY:-lglib-2.0>-lwayland-cursor -lwayland-client -lxkbcommon -ldl-L/usr/lib64$<LINK_ONLY:-ldbus-1>

Of course the '-no-pie' is gone from removing the first lines.

However, the change from PUBLIC to PRIVATE added the $<LINK_ONLY:foo> wrapper around a bunch of the list items.  This still worked in the end, but I am not sure if this is what is expected / intended.

For fun, I restored the first three lines, but kept the change to PRIVATE.  The result of this is as follows:

/usr/lib64/libdl.a/usr/lib64/libX11.so/usr/lib64/libXext.so/usr/lib64/libXinerama.so/usr/lib64/libXfixes.so/usr/lib64/libXcursor.so/usr/lib64/libXrender.so/usr/lib64/libpango-1.0.so/usr/lib64/libpangocairo-1.0.so/usr/lib64/libcairo.so/usr/lib64/libgobject-2.0.so/usr/lib64/libpangoxft-1.0.so/usr/lib64/libXft.so/usr/lib64/libfontconfig.so-lwayland-egl -lEGL-L/usr/lib64$<LINK_ONLY:-lgtk-3>$<LINK_ONLY:-lgdk-3>$<LINK_ONLY:-lpangocairo-1.0>$<LINK_ONLY:-lpango-1.0>$<LINK_ONLY:-lharfbuzz>$<LINK_ONLY:-latk-1.0>$<LINK_ONLY:-lcairo-gobject>$<LINK_ONLY:-lcairo>$<LINK_ONLY:-lgdk_pixbuf-2.0>$<LINK_ONLY:-lgio-2.0>$<LINK_ONLY:-lgobject-2.0>$<LINK_ONLY:-lglib-2.0>-lwayland-cursor -lwayland-client -lxkbcommon -ldl-L/usr/lib64$<LINK_ONLY:-ldbus-1>$<LINK_ONLY:-no-pie>

So, the change to PRIVATE does not keep the -no-pie from coming through.  The subsequent build failed.  So, the PRIVATE marker is not having the effect I would have expected it to.

 
I'd appreciate if you could test and report back, but there's no need to hurry. I won't be able to work on it today, I need some sleep. If you could do it in your TZ's "today" so I could find it here tomorrow that would be great. TIA

PS: I'm also investigating an option like "DISABLE_GLU" to solve your other issue but I'll reply to the other thread tomorrow.

Thanks for all the help,

Rob
 

Albrecht Schlosser

未读,
2024年3月21日 09:44:033月21日
收件人 fltkg...@googlegroups.com
On 3/18/24 05:53 Rob McDonald wrote:
On Sunday, March 17, 2024 at 3:09:57 PM UTC-7 Albrecht-S wrote:
Very likely, I see pretty much chaos and inconsistent code in this area.  :-(

I started working on this but it will take some time - definitely not today.

No worries.  I have my workarounds and am happy to be patient to remove them once it gets settled.  It looks like this may be the tip of a larger iceberg in certain ways.

Done in commit b53b2b6e1182efaf532d6eb9377a321e6e13a7e4.

I removed the "-no-pie" build option altogether.


For now I have a short request to test: can you please comment out (or delete) the 3 lines of code in src/CMakeLists.txt that set the '-no-pie' flag in the FLTK code and try again w/o the assignment?

767 if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS) 768 list(APPEND OPTIONAL_LIBS "-no-pie") 769 endif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT FLTK_BUILD_SHARED_LIBS)

Removing these lines works exactly as you would expect.  Everything else is the same, the '-no-pie' does not come through to my application, everything works.

Thanks for testing. That's what I did now in above mentioned commit.


Alternatively (or additionally) you could try changing the two lines that assign OPTIONAL_LIBS as PUBLIC to PRIVATE:
775 target_link_libraries(fltk PUBLIC ${OPTIONAL_LIBS}) 831 target_link_libraries(fltk-shared PUBLIC ${OPTIONAL_LIBS}) s/PUBLIC/PRIVATE/

I made this change as well, when I did so, the INTERFACE_LINK_LIBRARIES target property changed from:

/usr/lib64/libdl.a/usr/lib64/libX11.so/usr/lib64/libXext.so/usr/lib64/libXinerama.so/usr/lib64/libXfixes.so/usr/lib64/libXcursor.so/usr/lib64/libXrender.so/usr/lib64/libpango-1.0.so/usr/lib64/libpangocairo-1.0.so/usr/lib64/libcairo.so/usr/lib64/libgobject-2.0.so/usr/lib64/libpangoxft-1.0.so/usr/lib64/libXft.so/usr/lib64/libfontconfig.so-lwayland-egl -lEGL-L/usr/lib64-lgtk-3-lgdk-3-lpangocairo-1.0-lpango-1.0-lharfbuzz-latk-1.0-lcairo-gobject-lcairo-lgdk_pixbuf-2.0-lgio-2.0-lgobject-2.0-lglib-2.0-lwayland-cursor -lwayland-client -lxkbcommon -ldl-L/usr/lib64-ldbus-1-no-pie

To:

/usr/lib64/libdl.a/usr/lib64/libX11.so/usr/lib64/libXext.so/usr/lib64/libXinerama.so/usr/lib64/libXfixes.so/usr/lib64/libXcursor.so/usr/lib64/libXrender.so/usr/lib64/libpango-1.0.so/usr/lib64/libpangocairo-1.0.so/usr/lib64/libcairo.so/usr/lib64/libgobject-2.0.so/usr/lib64/libpangoxft-1.0.so/usr/lib64/libXft.so/usr/lib64/libfontconfig.so-lwayland-egl -lEGL-L/usr/lib64$<LINK_ONLY:-lgtk-3>$<LINK_ONLY:-lgdk-3>$<LINK_ONLY:-lpangocairo-1.0>$<LINK_ONLY:-lpango-1.0>$<LINK_ONLY:-lharfbuzz>$<LINK_ONLY:-latk-1.0>$<LINK_ONLY:-lcairo-gobject>$<LINK_ONLY:-lcairo>$<LINK_ONLY:-lgdk_pixbuf-2.0>$<LINK_ONLY:-lgio-2.0>$<LINK_ONLY:-lgobject-2.0>$<LINK_ONLY:-lglib-2.0>-lwayland-cursor -lwayland-client -lxkbcommon -ldl-L/usr/lib64$<LINK_ONLY:-ldbus-1>

Of course the '-no-pie' is gone from removing the first lines.

However, the change from PUBLIC to PRIVATE added the $<LINK_ONLY:foo> wrapper around a bunch of the list items.  This still worked in the end, but I am not sure if this is what is expected / intended.

Adding the $<LINK_ONLY:...> generator expression is exactly what CMake does for PRIVATE link dependencies (INTERFACE_LINK_LIBRARIES).

This is a distinction that is needed for the new "Modern CMake" approach but it was irrelevant in previous (FLTK/CMake build file) versions. What I still need to figure out is which ones of the target_link_libraries() need to be PUBLIC and which ones can - or better: should -  be PRIVATE.

For fun, I restored the first three lines, but kept the change to PRIVATE.  The result of this is as follows:

[...]

So, the change to PRIVATE does not keep the -no-pie from coming through.

Expected.


The subsequent build failed.  So, the PRIVATE marker is not having the effect I would have expected it to.

Yes, it's CMake "magic". The details are often confusing and hard to understand.

 
PS: I'm also investigating an option like "DISABLE_GLU" to solve your other issue but I'll reply to the other thread tomorrow.

Still working on this one. I'm researching some ideas...


Thanks for all the help,

Welcome.
回复全部
回复作者
转发
0 个新帖子