-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Control linking of dependencies for cc_library #492
Comments
Why not use cc_binary if you want to build a dynamic library? On Fri, Oct 2, 2015 at 9:33 AM, jcremer [email protected] wrote:
|
This seems to work for me, but i am not sure if the generation of cc_binary is always the wanted behaviour; For example if you want to have more control over the linked libraries or generate intermediates that i can then use as a build result and additionally to generate more dependent libraries or binaries. |
The relevant documentation is here: http://bazel.io/docs/build-encyclopedia.html#cc_binary.linkstatic Intermediates for what? If you are building an intermediate for Bazel, you should be using cc_library, and everything should work. If you are building an intermediate for use elsewhere, it would help if you further specified what you want. |
I have a main application that loads some other .so files as modules. These modules use symbols already available inside the main application and i dont want to have these symbols also inside every module. But I have some other dependencies inside the module whose symbols I do want inside the module binary. So I need to control which symbols may be undefined inside my module lib at compile time and which are not. |
I'm pretty sure this is possible, I think it would work like this: cc_binary(name = "main", cc_binary(name ="module", cc_library(name ="lib", adding @ulfjack in case I'm totally off. |
Going through .so files may work, but seems a bit roundabout and increases number of pieces to deploy. That said, we don't have a really good mechanism for this; I think the most obvious way to do it is to have a header-only library that doesn't have implementation .cc files, and compile against that in the modules. (And of course, make sure that the implementation is in the binary that wants to load the modules.) |
Is there anything left for addressing this issue? |
As ulfjack already said, the current options are suboptimal, but it is possible to get the wanted behaviour by defining some cc_libraries twice: complete and only-header. |
I have the same problem when I added IMHO, linking with the dependent libraries (specified in |
Use a cc_binary (right now, we may introduce more / better rules to do that) to link dependencies. For larger code bases, linking the transitive closure at every cc_library would be prohibitively expensive (I haven't actually collected data on this, but I'm very confident). cc_library isn't intended as a top-level rule for external consumption - it's not a 'library' in the same sense as, say, openssl is a library. We generally expect cc_library rules to be much more fine-grained, in the limit down to having a single .cc file per cc_library. |
I agree with you that linking takes more time and more memory for more dependencies. This becomes a serious problem when dealing with large code bases. That's why incremental linking is included in many people's most-wanted feature list. Thanks for reiterating the semantic and design of
IMHO, whether Besides, given such design of
Both |
We tried incremental linking, and it was a small performance win, but not significant enough to warrant the complexity. We don't actually build .a files on Linux, where we instead pass the original .o files to the final link (or at least, we have code to do that, and I think it's enabled by default). This is faster than building intermediate .a files and uses less disk space. In the given example, it's not really possible right now to build libfoo.so such that you can install all three independently. One of the problems with dynamic linking is that you have to carefully make sure to never statically link common dependencies into multiple outputs. For example, consider two binaries A and B, depending on a library LIB, which depends on a library LIB2. Let's say A also directly depends on LIB2. If you link LIB as a .so, what do you do with LIB2? You could link it into LIB.so, but then you have to make sure to not link it into A. Or you could require linking it into it's own LIB2.so, in which case you have to make sure that both LIB and A link it dynamically, and the downside is that you then can't use multiple rules for LIB2 - you have to force a single rule to contain everything that you want linked into LIB2.so. A simple, and usually workable policy is to never link dependencies into libraries. At Google, we don't ship pieces of applications independently of each other, we always ship the entire app. This works great for production systems, but doesn't match how Linux distributions work today. Though note that there are efforts to move closer to that, e.g., Ubuntu snappy packages. For Bazel, we'd like to offer a mode that covered this case better, but note that it's inherently brittle under changes to the structure of the dependency graph. We haven't yet been able to come up with a good model: in order to avoid it being brittle, we need to enforce global properties on the build graph, which turns it into a scalability issue. We briefly discussed allowing users to determine the subdivision between linked units manually, and Bazel enforcing correctness at the binary level. It's still brittle, but at least the build will fail if you break it, rather than discovering issues at runtime. |
If you have multiple dependent shared libs is there a way to maintain those dependencies? It seems like I would need to list all needed shared libs for any rule. for example look at test. Is there a work around for this?
|
After 2 years we're going to make this happen! Please take a look and comment on the transitive libraries design doc: https://docs.google.com/document/d/1-tv0_79zGyBoDmaP_pYWaBVUwHUteLpAs90_rUl-VY8/edit?usp=sharing |
See also https://stackoverflow.com/questions/44723821/why-does-bazel-under-link-and-how-do-i-fix-it. This is just broken; Bazel should be able to produce one |
My takeaway from this is that for development, Bazel-style internal library linking is awesome because of the granularity it yields; however, for deployment, if you have all your Bazel internal libraries / binaries use Since
My naive understanding is that this is similar to 5.d. in the Attack Plan, but instead of distributing the top-level library with its upstream components (possibly with or without odd names) in a Can I also ask if this understanding is correct? (Specifically, would this be a valid usage of Quick example (leveraging Matt's
|
Hello! Two years have passed since the last message and I was wandering if there is any plan to add the |
Hi @filippobrizzi, it shouldn't be too hard to tweak https://github.com/bazelbuild/rules_cc/blob/master/examples/my_c_archive/my_c_archive.bzl to collect transitive static libraries from CcInfo and create an archiving action for all of them. |
Hi there! We're doing a clean up of old issues and will be closing this one. Please reopen if you’d like to discuss anything further. We’ll respond as soon as we have the bandwidth/resources to do so. |
@sgowroji I think we should keep this open. cc_shared_library resolves the transitive depdency particially. I think there are still many issues to address:
|
I think we can close this now:
This is covered by #1920, which has an open PR pending implementing an accepted design. If there are any use cases that aren't covered by other open issues, it would be very helpful to have dedicated issues with smaller scope opened for them. These large umbrella issues just tend to get stale as they aren't actionable. |
@fmeum Hello, I'm building a dynamic library for my proto message cause there is a proto instance problem happend when we collaborate two dynamic libraries that static link to this proto. In order to reduce the difficulty of managing the library, I want to build a dynamic proto library which static link to its dependencies for proto.
We use version 6.5.0 of bazel. Here is my BUILD under In some_path/proto/BUILD:
In some_path/BUILD:
|
Well, I add ":cc_test_proto_message_proto" to |
cc_library currently does not link its dependencies, but cc_binary does. It whould be nice if I could control this behaviour for each dependency to create cc_libraries that do contain the symbols from their dependencies. For example by using a flag like linkwithlibrary=true in each dependency or giving a list of "must-link" dependencies inside the final cc_library definition
See also: http://stackoverflow.com/questions/32845940/symbols-from-static-cc-library-dependency-in-so-missing
The text was updated successfully, but these errors were encountered: