ocaml / dune

A composable build system for OCaml.
https://dune.build/
MIT License
1.63k stars 401 forks source link

Linker flags vs. libraries #2977

Open jamesjer opened 4 years ago

jamesjer commented 4 years ago

I am trying to build a couple of projects for the Fedora Linux distribution. These projects use dune to build. Fedora mandates that certain flags be passed to the linker (e.g., -Wl,-z,relro and -Wl,--as-needed). I cannot seem to find the correct way to do this. If I pass these flags along with the libraries to be linked with in c_library_flags, then the cmxs files are appropriately linked, but the stub libraries generated with ocamlmklib are not. In fact, ocamlmklib emits "Unknown option" warnings. What I need is some way to specify linker flags, which have to be guarded with -ldopt when passed to ocamlmklib, separately from the libraries to be used for linking. Does dune provide some way of doing this?

This seems to be related to #119.

ghost commented 4 years ago

You can try adding (library_flags -ldopt -Wl,-z,relro -ldopt -Wl,--as-needed). But if it is a global property that must be consistently enforced, it seems to me that this is something that should be set when configuring the OCaml compiler itself so that such flags are consistently passed.

rwmjones commented 4 years ago

Finally in Fedora 32 we are now setting all the flags on OCaml-compiled native binaries. But crucially this only applies to ocamlopt, and if I understand Jerry's request correctly, he's interested in the flags being applied to ocamlmklib. Jerry could you link to a build.log that shows the problem? It may be helpful here.

ghost commented 4 years ago

Have you considered doing the same for ocamlmklib? Concretely, I'm thinking of a flag that one would pass to the configure script of ocaml, i.e.:

$ ./configure --ocamlmklib-link-flags "-ldopt -Wl,-z,relro ..."

Otherwise, we are talking about patching the dune files right?

jamesjer commented 4 years ago

Sorry for the delay; I left town for the holidays. Here is an example from building cairo2 0.6.1 (this link is only valid for a few days):

https://kojipkgs.fedoraproject.org//work/tasks/3495/40053495/build.log

The configure files allow settings CAIRO_CFLAGS, CAIRO_LIBS, GTK_CFLAGS, and GTK_LIBS, which are used to generate c_flags.sexp and c_library_flags.sexp files in the relevant directories. If I add the linker flags of interest to CAIRO_LIBS and GTK_LIBS, then ocamlopt links the .cmxs files appropriately. However, ocamlmklib generates the "Unknown option" lines in the build log due to the absence of -ldopt.

If I add -ldopt at the beginning of CAIRO_LIBS and GTK_LIBS, then ocamlmklib still complains about unknown options, and additionally the cmxs building steps fail with "/usr/bin/ld: cannot find -ldopt".

Perhaps Fedora's ocamlmklib could be configured to pass the correct flags. I will defer to @rwmjones on that. But doesn't it seem generally useful to be able to tell dune to pass non-library flags to the linker and have it do the right thing for both ocamlopt and ocamlmklib?

ghost commented 4 years ago

But doesn't it seem generally useful to be able to tell dune to pass non-library flags to the linker and have it do the right thing for both ocamlopt and ocamlmklib?

Could you clarify what you mean by non-library flags and doing the right thing? Or, could you post a concrete dune file and what command you would expect dune to emit?

jamesjer commented 4 years ago

I'm talking about flags such as -Wl,-z,relro and -Wl,--as-needed. The right thing to do is to guard those with -ldopt when passing them to ocamlmklib. Presumably they are being passed to ocamlopt correctly already.

rwmjones commented 4 years ago

In Fedora we have modified the build chain slightly so that ocamlopt does indeed use those flags. Please see: https://pagure.io/fedora-ocaml/c/122b350037d93e9f44357b215d5ecfbadb8d8fa5?branch=fedora-32-4.10.0-beta1

ghost commented 4 years ago

I'll admit that this conversation still feels a bit abstract to me. I'm ccing @dra27 who is more knowledgeable than me in this domain.

Personally, it would help my understanding if I could see an example of dune file (possibly with some fields that don't exist yet) and what ocamlopt/ocamlmklib commands you would expect dune to emit.

One of my concern is how dune would detect that a certain flag must be wrapped with -ldopt. If it would detect it by analysing the flag itself, that would mean that we would need to maintain a hardcoded list of flags in dune for specific tools, which is not great.

dra27 commented 4 years ago

Sorry, I'm coming late to this and being unable to see that log is a nuisance - is it possible to have a link to another (GitHub gists are very useful for this, as they are permanent), please?

I think that as in #119, it may be that we want to alter both ocamlmklib and dune - the -Wl, syntax is common enough that it would be sensible for ocamlopt and ocamlmklib to recognise it directly as an alias for -ldopt, etc. (cf. https://github.com/alainfrisch/flexdll/issues/72), but I'd like to see a log to be sure I'm understanding it all correctly!