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

Support for alwayslink cc_library targets #1902

Open
antsareeverywhere opened this issue May 26, 2023 · 2 comments
Open

Support for alwayslink cc_library targets #1902

antsareeverywhere opened this issue May 26, 2023 · 2 comments

Comments

@antsareeverywhere
Copy link

antsareeverywhere commented May 26, 2023

Is your feature request related to a problem? Please describe.
alwayslink cc_library targets create .lo files, which rules_haskell doesn't appear to know how to find. I didn't see any mention of .lo files or alwayslink, so I'm not sure if this is a known limitation.

Describe the solution you'd like
If a haskell_library depends transitively on a cc_library where alwayslink is set to true, then the rules_haskell library builds correctly, or alternately fails with an error indicating that alwayslink isn't currently supported.

Describe alternatives you've considered
I was able to get Bazel to build by creating a build target without alwayslink and making this target a direct dependency on all Haskell targets that indirectly include the original cc_target.

I believe what Bazel does in the cc case is to treat the .lo file as a list of .o files. Then Bazel passes these .o files directly to the linker rather than passing the .lo file itself. From reading the GHC docs, I think it may work for rules_haskell to do the same thing. Essentially, the .lo files would need to be handled in the logic that passes arguments to GHC rather than the logic that generates Cabal files. Currently what happens is that haskell_library correctly detects the dependency, but adds it to the generated Cabal file as a linker argument. The linker isn't able to find a .so.* or .a file for the library, so the build fails with a linker error.

Additional context
The relevant search term for understanding Bazel's handling of .lo files is alwayslink: https://github.com/search?q=repo%3Abazelbuild%2Fbazel++alwayslink&type=code

@aherrmann
Copy link
Member

Thanks for raising this @antsareeverywhere. Do you have a minimal repro that you could share that illustrates the use of the feature?

rules_haskell implemenents most of the handling of CC libraries in this module. I'm not super familiar with the always link feature. Is it sufficient to handle the alwayslink field on LibraryToLink objects or is additional handling required?

Adding support for this to rules_haskell will probably require a bit of thought. rules_haskell relies on the extra-libraries field in the GHC package configuration file. I'm not sure if that has support for the alwayslink concept.

Essentially, the .lo files would need to be handled in the logic that passes arguments to GHC rather than the logic that generates Cabal files. Currently what happens is that haskell_library correctly detects the dependency, but adds it to the generated Cabal file as a linker argument.

Could you clarify what you mean by this? rules_haskell doesn't generate Cabal files. Are you referring to the GHC package configuration files, i.e. what's generated here?

@antsareeverywhere
Copy link
Author

Do you have a minimal repro that you could share that illustrates the use of the feature?

As a minimal repro, you can add alwayslink = True to the cbits cc_library target of rules_haskell_tests/tests/indirect-link/BUILD.bazel. Then try building the indirect-link-static target. It will fail with a linker error about finding -ltests_Sindirect-link_Slibcbits.

Is it sufficient to handle the alwayslink field on LibraryToLink objects or is additional handling required?

Possibly, but I'm not certain. You fix the linking error above by explicitly adding the explicit path to intf.pic.o to the args returned by ghc_cc_program_args in cc.bzl. For example, lines 220-222 might look like

        cc + " -E -undef -traditional",
        "-optc-fno-stack-protector",
        "/home/foo/bar/rules_haskell/rules_haskell_tests/bazel-out/k8-fastbuild/bin/tests/indirect-link/_objs/cbits/intf.pic.o"
    ]

I found out which pic.o file to add here by calling nm bazel-out/k8-fastbuild/bin/tests/indirect-link/libcbits.lo from therules_haskell_tests directory. I believe the names of the pic.o files should be available as outputs of the appropriate action for cbits. You can see this, for example, by running

bazel aquery 'mnemonic("CppCompile",":cbits")' | grep Outputs

What I don't know is whether all the information that's available to Bazel is available in the CcInfo object of haskell_library dependencies. It looks to me like rules_haskell constructs a custom CcInfo object that may diverge from the object Bazel's rules_cc would create. It may be necessary to do work in the haskell_library implementation to pipe the appropriate info through.

rules_haskell doesn't generate Cabal files. Are you referring to the GHC package configuration files, i.e. what's generated here?

Yes sorry, that's my mistake. Once the appropriate pic.o files are passed to GHC, you would need to remove the dependency from the GHC package configuration files. AFAICT from the GHC package config documentation, GHC doesn't support .lo files, so they probably shouldn't be added there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants