I found when using ‘-cc’ and ‘-I +dir’ options together, the ld cannot correctly find the libraries under ‘dir’.
Here’s my case:
I have a sysroot, containing ocaml and a toolchain.
I have OCAMLLIB exported as in env, pointing to the standard library location.
export OCAMLLIB=“/path/to/sysroot/usr/lib/ocaml”
And CC is also exported.
export CC=“x86_64-wrs-linux-gcc -m64 -fstack-protector-strong …”
Now if I use ocamlopt like below, the linking process fails.
ocamlopt -cc ‘${CC}’ -I +compiler-libs
Even if I use host gcc, I get the same failure.
ocamlopt -cc ‘gcc’ -I +compiler-libs
The error message is like below:
ld: :(.text+0xd56): undefined reference to `camlStdlib__Bytes__sub_303’
However, if I don’t use ‘-cc’ option, the build succeed.
ocamlopt -I +compiler-libs
I’m wondering if the ‘-cc’ option has some problem with ocamlopt. Why specifying it will cause problem at linking stage?
The fastest way to diagnose what is going on is to pass the -verbose flag to ocamlopt with and without -cc and comparing the invocation of external commands (the lines starting with +).
The missing symbol (camlStdlib__Bytes__sub_303) comes from the standard library, so I think the -I flags should be irrelevant.
The C compiler specified by the -cc option is used for two things: compiling C files to objects files, and (in native mode only) for the linking steps.
If you pass the -verbose flag to ocamlopt (without -cc), you should be able to see which C compiler is used for linking, which might give you some hints on why the other C compilers don’t work.
The (native) compiler has command line stuff baked in (grep ‘mkexe’). Passing -cc overrides this, so if you do that you must also pass all required compile/link options using -ccopt and -cclib. I’m guessing that includes stdlib info.
@nojb@vlaviron
After adding ‘-verbose’ option and comparing the building results, I found that the biggest different is about the ‘-shared’ option.
When ‘-cc’ option is specified, the ‘-shared’ option does not have effect on ocamlopt, that is, ocamlopt is not adding ‘-shared’ to underlying compiler invocation.
The error happens at compiling .cmxs file.
e.g.,
$(OCAMLOPT) -shared -o findlib_dynload.cmxs $(DYNLOAD_XOBJECTS);
When I set OCAMLOPT like below, the ‘-shared’ is not passed to gcc.
OCAMLOPT = “ocamlopt -verbose -cc ‘${CC}’ -ccopt ‘–sysroot=${STAGING_DIR_TARGET} ${CFLAGS}’ -ccl
ib ‘${LDFLAGS}’ -I +compiler-libs”
If I don’t pass the ‘-cc’ option, things work.
OCAMLOPT:class-target = “ocamlopt -verbose -ccopt ‘–sysroot=${STAGING_DIR_TARGET} ${CFLAGS}’ -ccl
ib ‘${LDFLAGS}’ -I +compiler-libs”
Looking at the Makefile.build_config, there’s MKEXE_EXP and MKDLL_EXP.
It seems that by default MKDLL_EXP will be used when ‘-shared’ is supplied to ocamlopt. But when ‘-cc ${CC}’ is also supplied, it switches to use ${CC}, which does not have ‘-shared’ option.
P.S.
I’m using ocaml 5.0.0. But I briefly checked ‘git log 5.0.0…HEAD’ in ocaml repo, I don’t see ‘-shared’ option related fix. So I assume this problem also applies to latest ocaml.