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

Make dl library dependency #1245

Merged
merged 4 commits into from
Sep 20, 2024

Conversation

dgreatwood
Copy link
Collaborator

Fix for issue #1230

libdl may be required for function dladdr, used in logStackTrace.
Note: If 'dl' is not available, per Meson the dladdr functionality is provided by libc. So if 'dl' is not available, we assume 'dl' is not required.

Added in meson.build:
deps_libpistache += dependency('dl', required: false)

Copy link

codecov bot commented Sep 20, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 76.24%. Comparing base (a450d5c) to head (eb3a556).
Report is 5 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1245      +/-   ##
==========================================
- Coverage   77.97%   76.24%   -1.73%     
==========================================
  Files          54       57       +3     
  Lines        6883     9801    +2918     
==========================================
+ Hits         5367     7473    +2106     
- Misses       1516     2328     +812     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kiplingw kiplingw self-requested a review September 20, 2024 04:22
@kiplingw kiplingw merged commit e07dc0b into pistacheio:master Sep 20, 2024
126 of 134 checks passed
# #1230.
# Note: If 'dl' is not available, per Meson it suggests that the
# functionality is provided by libc
deps_libpistache += dependency('dl', required: false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this will only work when users use Meson 0.62.0 or newer, while we only require Meson 0.53

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because dependency() in Meson can do different things when looking for a dependency "foo":

  • search for a "foo" dependency overridden with meson.override_dependency('foo', foo_dep)
  • search for a foo.pc file and use it
  • search for FooConfig.cmake files and use them
  • use a custom dependency resolution method if defined for the "foo" dependency

In our case:

  • nobody calls meson.override_dependency('dl')
  • no dl.pc file exists
  • of course no DlConfig.cmake files exist either
  • Meson defines a custom dependency resolution method for "dl", but this was added only in Meson 0.62.0

Until we'll require 0.62.0, we should do this instead:

deps_libpistache += compiler.find_library('dl', required: false)

And when we can require 0.62.0,

deps_libpistache += dependency('dl')

(note how required: false is absent, since we always require libdl's functionality. Meson will take care of figuring out when dl is provided by libc and won't fail when libdl doesn't exist)

Copy link
Member

@Tachi107 Tachi107 Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi -

Although I agree there is a counter argument, I was reluctant to dispense with the "required: false" for
deps_libpistache += dependency('dl')
for fear meson would demand the presence of libdl in cases where we don't need it for real - noting that i) we almost never need it actually, and ii) we use only one potential-libdl function, and meson has no way of knowing which function we need (AFAIK) when determining if we need libdl. In other words, having "required: false" seems the more cautious path vs. breaking a build that might otherwise work.

Regarding meson version, could we / should we condition on the meson version like:

if meson.version().version_compare('>=0.62.0')
        deps_libpistache += dependency('dl', required: false)
else
    	deps_libpistache += compiler.find_library('dl', required: false)
endif

WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I agree there is a counter argument, I was reluctant to dispense with the "required: false" for deps_libpistache += dependency('dl') for fear meson would demand the presence of libdl in cases where we don't need it for real - noting that i) we almost never need it actually

We can find a solution which always works, see below :)

, and ii) we use only one potential-libdl function, and meson has no way of knowing which function we need (AFAIK) when determining if we need libdl.

Of course it has! You can check if you have the potential-libdl function (which is it?) without linking to libdl, and then add libdl if needed:

has_func = compiler.has_function('potential_libdl')
if not has_func
  libdl_dep += dependency('dl')
  has_func = compiler.has_function('potential_libdl', dependencies: libdl_dep)
  if not has_func
    error('Unable to find potential_libdl(), even when linking to libdl')
  endif
  libpistache_deps += libdl_dep
endif

In other words, having "required: false" seems the more cautious path vs. breaking a build that might otherwise work.

Regarding meson version, could we / should we condition on the meson version like:

if meson.version().version_compare('>=0.62.0')
        deps_libpistache += dependency('dl', required: false)
else
    	deps_libpistache += compiler.find_library('dl', required: false)
endif

WDYT?

The only reason why dependency('dl') exists is to be able to always require that dl functionality is available even when it is part of libc and no separate libdl exists. If we don't always require dl functionality, we might as well always use compiler.find_library('dl', required: false) instead.

In other words:

code meaning
dependency('dl') always require dl functionality, whether it's part of libc or in a separate libdl object
compiler.find_library('dl') always look for a separate libdl object
compiler.find_library('dl', required: false) link to libdl, only if found
dependency('dl', required: false) same as above, but requires meson 0.62.0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for fear meson would demand the presence of libdl in cases where we don't need it for real - noting that i) we almost never need it actually, and ii) we use only one potential-libdl function, and meson has no way of knowing which function we need (AFAIK) when determining if we need libdl. In other words, having "required: false" seems the more cautious path vs. breaking a build that might otherwise work.

As a matter of curiosity -- meson uses the presence or absence of dlopen (after #include <dlfcn.h>) as a sentinel for this use case. Both dlopen and dladdr are defined by POSIX, in Issue 8 (same header for both). Issue 7 only defined dlopen and only included it in XSI.

The meson check can only be incorrect for your use case if dlopen requires -ldl, but dladdr does not. Is this a realistic concern? Are there any systems out there that implement such?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi -

As per PR #1252 (and per your comment there), unfortunately the ubi-8 case (and associated meson behaviour) prevents us, as a practical matter, from using has_function for determining if we need to pull in the dl library.

As to whether there are any systems where meson would wrongly determine that the dl library was required, that's kind of impossible to determine for certain in advance. The approach taken here instead seems the lowest risk; it would only fail if dladdr was not supplied by libc and either libdl was not available or libdl did not supply dladdr. Which is a very unlikely combination.

Thanks.
P.S. I have a dim recollection that there was a version of BSD that exposed this issue in some form, but I can't swear to it.

@dgreatwood
Copy link
Collaborator Author

dgreatwood commented Sep 23, 2024 via email

@Tachi107 Tachi107 mentioned this pull request Sep 27, 2024
dgreatwood added a commit to dgreatwood/pistachefork that referenced this pull request Sep 30, 2024
An improved fix for issue pistacheio#1230, previously addressed by PR pistacheio#1245
which did:
    ... = dependency('dl', required: false)
  - support for "required: false" being added in Meson 0.62.0, where
    Pistache only requires Meson 0.53.

Additionally, this new fix requires libdl only if the specific
function dladdr() is not supplied by libc in any case, potentially
avoiding pulling in libdl when not actually required.
dgreatwood added a commit to dgreatwood/pistachefork that referenced this pull request Nov 1, 2024
An improved fix for issue pistacheio#1230, previously addressed by PR pistacheio#1245
which did:
    ... = dependency('dl', required: false)
  - support for "required: false" being added in Meson 0.62.0, where
    Pistache only requires Meson 0.53.

Additionally, this new fix requires libdl only if the specific
function dladdr() is not supplied by libc in any case, potentially
avoiding pulling in libdl when not actually required.
@dgreatwood dgreatwood deleted the MakeDlLibraryDependency branch January 18, 2025 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants