0

I am working on a library project which mixes C, C++, and Rust code. For historical reasons I use autotools to drive building.

Essentially, my Makefile.am looks like this:

libfoo_la_LIBADD += rustfoo/target/release/librustfoo.a

rustfoo/target/release/librustfoo.a:
    cd rustfoo/; \
    cargo rustc --release -- --crate-type staticlib

dist-hook:
    mkdir -p $(distdir)/rustfoo
    cp -a $(srcdir)/rustfoo/* $(distdir)/rustfoo
    rm -rf $(distdir)/rustfoo/target

Notice, that it is not practical to enumerate all Rust source files in some ....librustfoo_a_SOURCES variable or similar. (Mainly because, I bundle some dependencies in rustfoo/dependencies/.)

All works fine for non-VPATH builds, but fails as expected for VPATH build. Autotools does not know about the rust sources and cannot copy/link them into the $(builddir). Sure, I could cd into the source tree as

 rustfoo/target/release/librustfoo.a:
    cd $(srcdir)/rustfoo/; ...

but that would defeat the purpose of VPATH builds.

Is there any best practices how to approach this?

Jose Gracia
  • 133
  • 6
  • If you are building the library in tree, you almost certainly want to use a libtool convenience library rather than appending a relative path to *_LIBADD. – William Pursell Mar 13 '23 at 12:56
  • https://docs.rs/libtool/latest/libtool/ – William Pursell Mar 13 '23 at 13:02
  • Thanks for the tip, William. That would have made my life easier. However, it does not address the issue with my VPATH builds ;) Or does it? – Jose Gracia Mar 13 '23 at 13:46
  • I think it actually does. Using libtool convenience libraries will almost certainly solve the problem. – William Pursell Mar 13 '23 at 13:52
  • Maybe I have been unclear here and I will update my question. The reasons why VPATH builds don't work here is because autotools does not know about the Rust source files and cannot copy/link them into the $(builddir). If I enumerate them in a `...librustfoo_a_SOURCES =`, autotools could do its magic. However, that is not practical in my case (not desirable at least ;). – Jose Gracia Mar 13 '23 at 14:18
  • Having a source enumeration does not itself automatically trigger any magic. What gets a VPATH build working is that you have (in the generated makefile, at least) correct, complete, explicit prerequisite lists for all your rules, *and* you use appropriate `make` automatic variables to refer to them in rules' recipes. Automake will arrange for all that in rules that it creates based on a `_SOURCES` variable, but as far as I am aware, it does not have any built-in support for doing that with Rust sources. – John Bollinger Mar 13 '23 at 23:52
  • And note well that having proper prerequisite lists for your rules also conveys all the usual direct benefits around (re)building only targets that are out of date, and not failing to recognize when targets need to be rebuilt. – John Bollinger Mar 13 '23 at 23:55

1 Answers1

1

I actually found a solution relying on cargo which works for me at the moment. But I am still interested in a more autotoolish way to accomplish this.

I don't know how to tell autotools what the Rust sources are, but it turns out to be easy to tell Rust where it should put its compilation outputs (--target-dir). When building .../librustfoo.a, cd into the $(srcdir) and redirect outputs into the appropriate target directory in the build tree as

rustfoo/target/release/librustfoo.a:
    cd $(srcdir)/rustfoo/; \
    cargo rustc --release -- --crate-type staticlib --target-dir $(abs_builddir)/rustfoo/target/
Jose Gracia
  • 133
  • 6