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

Test cannot load other library target at runtime via dlopen #4218

Closed
th0br0 opened this issue Dec 4, 2017 · 7 comments
Closed

Test cannot load other library target at runtime via dlopen #4218

th0br0 opened this issue Dec 4, 2017 · 7 comments
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-CPP Issues for C++ rules type: feature request

Comments

@th0br0
Copy link

th0br0 commented Dec 4, 2017

Description of the problem / feature request / question:

There is no easy way for a test to load another target at runtime using dynloading.
The only solution I have found so far is to add the library to deps and then reference via e.g. "$CWD + /../_solib_local/libtests_Slibmylib.so" but this is an ugly hack. There seems to exist no way to add the output of a cc_library target to the test's runfiles directory.

One example use case for this is testing a module ABI for run-time plugins.

If possible, provide a minimal example to reproduce the problem:

This is a sketch and not a runnable example. I can provide one if preferred.

cc_test(name="dl_test", srcs=["test.c"],data=[":mylib"])
cc_library(name="mylib", srcs=["lib.c"])

with test.c containing:

int main(int argc, char** argv) {
// ...
  void* handle = dlopen("libmylib.so", RTLD_NOW);
// ...
}

This will work fine when run from the workspace dir after a bazel build but not via bazel test because the library can't be found.

Environment info

  • Operating System:
    Linux / OS-independent

  • Bazel version (output of bazel info release):
    release 0.8.0

Have you found anything relevant by searching the web?

No.

@iirina iirina added P3 We're not considering working on this, but happy to review a PR. (No assignee) type: feature request category: rules > C++ labels Dec 4, 2017
@iirina
Copy link
Contributor

iirina commented Dec 4, 2017

CC: @mhlopko

@hlopko hlopko self-assigned this Dec 4, 2017
@hlopko
Copy link
Member

hlopko commented Dec 5, 2017

Library outputs of cc_library shouldn't be relied on, and should be considered as a implementation detail and are toolchain dependent (e.g. if you're using gold linker, we don't produce .a libs at all and use lib-groups instead, also linkstatic=0 on cc_test is something that might change in the future). Ideally you should wait for cc_shared_library (https://docs.google.com/document/d/1d4SPgVX-OTCiEK_l24DNWiFlT14XS5ZxD7XhttFbvrI/edit#heading=h.jwrigiapdkr2) or use cc_binary(name="libfoo.so", linkshared=1) with the hack you mentioned in the meantime. The actual location of shared library dependencies should be available from Skyalrk. Eventually.

@hlopko hlopko added team-Rules-CPP Issues for C++ rules and removed category: rules > C++ labels Oct 11, 2018
@hlopko hlopko removed their assignment Dec 6, 2019
@limdor
Copy link
Contributor

limdor commented Nov 30, 2021

@hlopko could you so kind to give an update regarding if anything done in this direction or if there are any plans?

@hlopko
Copy link
Member

hlopko commented Nov 30, 2021

I'm sorry, I'm no longer working on Bazel. CC @comius @oquenchil

@erenon
Copy link
Contributor

erenon commented Mar 23, 2022

A possible workaround:

cc_library(
  name = "plugin_impl",
  srcs = ["plugin.cpp"],
  alwayslink = True,  # needed to avoid the linker dropping the implementation, as plugin does not reference any symbol of plugin_impl
)

# This target creates libplugin.so, that can be dlopened
cc_binary(
  name = "plugin",
  linkshared = True,  # important, output will be libplugin.so
  deps = ["plugin_impl"],
)

However, if plugin B depends on a plugin A, it can only depend on the cc_library target. But during runtime, on windows, it'll look for plugin_A_impl.dll, not plugin_A.dll (at that point, plugin_A.dll is already loaded). It'd be great if the complete linking of a cc_library were possible.

@cameron-martin
Copy link
Contributor

cameron-martin commented Feb 10, 2023

Is the situation for this much better with the current version of cc_shared_library? You can put the cc_shared_library target as a data dependency of another library, but there's two issues with this:

  1. The correct rpaths don't get generated to allow dlopen to work with just a filename.
  2. Checking of ODR violations doesn't happen across this boundary.

1 could probably be fixed by specifying the correct linkopts in the library.

@fmeum
Copy link
Collaborator

fmeum commented Feb 10, 2023

It you dlopen anyway, it might be a good idea to use the C++ runfiles library (@bazel_tools//tools/cpp/runfiles) to get the path and then pass that to dlopen. That just requires having the library in data, produced by either cc_binary or cc_shared_library.

That won't statically prevent ODR violations, but that seems hard to get right in an automated way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-CPP Issues for C++ rules type: feature request
Projects
None yet
Development

No branches or pull requests

8 participants