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

Default build settings for RAPIDS symbol visibility handling #10

Open
vyasr opened this issue Jan 4, 2025 · 1 comment
Open

Default build settings for RAPIDS symbol visibility handling #10

vyasr opened this issue Jan 4, 2025 · 1 comment
Assignees

Comments

@vyasr
Copy link
Contributor

vyasr commented Jan 4, 2025

The changes in #7 and the tasks in #9 point to a complex interplay in build-time spdlog usage that we need to address. The idea behind rapidsai/rmm#1740 was that projects using rapids-logger could address the symbol visibility issues and conda package issues by forcing a rebuild of spdlog by their consumers when building the logger (the conda package issues stem from the fact that whether spdlog is using a header-only or compiled fmt is determined when the spdlog package is built, which means that the conda package for spdlog will always trigger dynamic linking to libfmt.so even if we use the header-only spdlog target). However, this choice leads us afoul of the last point in #9: we do not want to require consumers of packages using rapids-logger to need to have spdlog on their system, except in the case of header-only packages, and for header-only packages that requirement should only propagate up one level in the dependency stack.

Stepping back, what we ultimately need is to treat all of our package builds (as opposed to users building from source) as special cases with the following requirements, none of which hold for users building our packages from source or building their packages against our packages:

  • We must always download spdlog to avoid a pre-built spdlog's fmt settings.
  • We must always use a statically compiled spdlog library for maximum symbol hiding.
  • We must avoid installing the built artifacts via EXCLUDE_FROM_ALL so that our packages don't ship any spdlog/fmt.
  • For simplicity, we should probably use spdlog's bundled fmt so that we don't have to think about fmt at all.
  • The most complex piece (which Force downloading spdlog by default to avoid using system packages and fmt linkage rmm#1740 aimed to solve): we must do all of the above in packages that depend on header-only packages that use rapids-logger, but only up to the first non-header-only package. Once we reach a compiled library, the logger impl targets should all be compiled in privately and the spdlog dependency should not propagate any further.

To accomplish all of these goals, the best option we have is to default to using CPM_DOWNLOAD_spdlog and a static spdlog library, and it should set EXCLUDE_FROM_ALL. Presumably we will need to add options to disable these settings so that end-users can still build how they want. These options will need to be available both in our lists files and in our config files so that the same optionality is available whether consumers are building against pre-built packages of ours or using something like CPM to build the whole tree from source.

The outstanding question remains how to deal with the header-only propagation problem. I'm not sure that there is a good tradeoff here. On one hand, rapidsai/rmm#1740 seems too magical a solution and it would be ideal to be explicit and require consumers to find spdlog a priori, i.e. we move to a BYO spdlog model. Concretely, if a package like cugraph that requires rmm but does not itself have a direct dependency on spdlog (because it does not have its own logger) uses a pre-built rmm package, the cugraph build must call rapids_cpm_spdlog with the appropriate settings in place. To facilitate this, the defaulting functionality that I suggested above will probably need to be in rapids_cpm_spdlog or an intermediate helper function that can be called by rapids_cpm_rapids_logger before calling rapids_cpm_spdlog (or other consumers like cugraph). While this is fine for packages that care about the symbol visibility enough to do this kind of thing manually, though, others would probably want spdlog found for them by rmm's config without needing to insert a find_package themselves. I'm not sure of the right tradeoff here. The two choices we have are:

  1. Don't export a spdlog dependency in a rapids-logger consumer's config file. Then, users of that package will not be forced to find spdlog unless they need it, which is typically good, but for header-only packages using rapids-logger their consumers will almost always be stuck with an undesirable requirement of finding spdlog themselves.
  2. Do export the spdlog dependency. In this case everything generally works, but now all consumers at any level of the dependency tree are required to have spdlog available to build.

What would really be ideal would be if we could trigger a rapids_cpm_spdlog call upon linking to the logger_impl target, but I don't know if such arbitrary code can be attached to a target when linked to. I can investigate that a bit further and see. Perhaps there is an approach with custom targets that could work. I suspect that any possible solution would be more convoluted than it's worth, though.

@vyasr vyasr self-assigned this Jan 4, 2025
@vyasr
Copy link
Contributor Author

vyasr commented Jan 8, 2025

After further consideration and some continued experimentation, I've come to the conclusion that the best approach here is to move away from the current design of rapids-logger and to instead aim to ship it as a library. The primary reason that I avoided this in the original design was because we intend to use rapids-logger in some header-only libraries (rmm and raft), with rmm in particular having endeavored to this point to also avoid having any pre-compiled library dependencies so that it could be easily used as a header-only dependency. My experiments in rapidsai/rmm#1740 indicate that it would be possible to accomplish this goal, but it would be quite complex and require propagating changes all the way down dependency trees. Moreover, it would make it quite challenging for dependencies to properly manage their spdlog dependencies from a packaging (not just build) perspective. Based on some offline discussions, I've opened rapidsai/rmm#1779 to propose that we convert rmm to a precompiled library, and since feedback was generally positive I think we can move forward with that approach. It should allow us to solve the core problem addressed by this issue without much of the build-time complexity that the previously proposed solutions would entail.

rapids-bot bot pushed a commit to rapidsai/rmm that referenced this issue Jan 8, 2025
See discussion in rapidsai/rapids-logger#10 (comment) and #1779. spdlog will remain a requirement for 25.02, but we will remove it in favor of a precompiled rapids-logger library in 25.04 (and that library will completely hide everything related to spdlog: APIs, package requirements, symbols, etc).

Authors:
  - Vyas Ramasubramani (https://github.com/vyasr)

Approvers:
  - Bradley Dice (https://github.com/bdice)

URL: #1780
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

No branches or pull requests

1 participant