简体   繁体   中英

Dealing with C code dependencies inside OCaml projects

I'm using ocamlbuild to build my OCaml project that uses an external C library "cstub". I found a very solution online to include the C library in the compilation process using ocamlbuild in http://l-lang.blogspot.com/2012/08/incorporating-c-code-in-ocaml-project.html (adding the pdep ["link";] "linkdep" (fun param -> [param]); line to myocamlbuild.ml ).

However, my C library has an external ASM dependency itself, and the solution above is not able to capture it. It fails to link with the ASM functions because it is not compiled together with the ASM file. Therefore, my question is: is there a way to tweak the suggestion given above to add the support to the ASM file when compiling the C program? For example, is there an additional parameter to be added to the pdep command to support additional compilation features?

Thank you very much in advance!

The default preamble for all build-related questions. Consider using dune if you have that option. OCamlBuild is retiring so don't expect too much help on it or good modern documentation. With that said, I understand that it is not always an option and I am myself using ocamlbuild for my main project.

So the pdep rule that you added to your ocamlbuild plugin is taking a parameter, eg,

<*.native>: linkdep(toto_c.o)

This toto_c.o (or anything between the parens) is passed as param and you need to translate it to a list of paths, so if your asm file is compiled to foo.o , you can write it as

<*.native>: linkdep(toto_c.o,foo.o)

and your pdep rule should be

pdep ["link"] "linkdep" (String.split_at_char ',')

If you want ocamlbuild to build foo.o from file foo.s , you will also need to write a rule for assembling files, ( ocamlbuild -documentation will show you all rules known to ocamlbuild , I didn't find any rules for the *.s -> *.o pattern).

Totally untested, but the rule should look something like this,

let asm_rule () =
  let deps = ["%.s"] and prod = "%.o" in
  let action env _ =
    let src = env "%.s" and obj = env "%.o" in
    let tags = tags_of_pathname src ++ "compile" in
    Cmd (S [Sh "as"; T tags; P src; A "-o"; Px obj]) in
  rule "asm: s -> o" ~deps ~prod action

Then add it on dispatch in the Before_rules stage, eg,

let () = dispatch (function
  | Before_rules -> 
    asm_rule ()
  | After_rules ->
    pdep ["link"] "linkdep" (String.split_on_char ',')
  | _ -> ())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM