Skip to content

Rebuild if changed #765

@orenbenkiki

Description

@orenbenkiki

When using the cc crate...

what is the proper way to set up build.rs and/or Cargo.toml so that cargo will automatically recompile and relink the C/C++ files if they are changed since the last compilation? Maybe even list the local header files so changing them will trigger recompilation/relink as well?

Alternatively, what is the proper way to force cargo to recompile all the C/C++ files?

Right now I can always remove the target/{debug,release} directories to force recompilation but it seems like a hack.

Activity

dot-asm

dot-asm commented on Dec 20, 2022

@dot-asm
Contributor

build.rs is executed whenever any file from the cargo package --list output is changed. So if you didn't list your C files in the include directive in your Cargo.toml yet, it might be time. This is assuming that you'd eventually have to do that, as you're likely to publish your crate. If not, then you would find println!("cargo:rerun-if-changed=dir/ect/ory"); in your build.rs useful.

It should be noted that none of this is actually cc-rs-specific, it's how cargo works in general.

orenbenkiki

orenbenkiki commented on Dec 22, 2022

@orenbenkiki
Author

It sounds as though I should expect the C compiler to be invoked if any of the files in cargo package --list were changed. Did I understand this right?

Two points then:

  • Even if it did work this way, that would be sub-optimal.

    In principle there should be a separate list of files which trigger C compilation (which would make this a specific issue for the cc crate). Of course "ideally" there should be a list of dependencies for each separate .c file to be compiled (that is, the list of .h files it includes), so not all the .c files would be compiled, just these that needed to. I guess it is a matter of deciding "how much like make do we want cc to be".

    It isn't a huge deal as long as these files are small. I can live with "all C object files depend on all the package files".

  • More importantly, it doesn't seem to work for me.

    I ensured that cargo package --list did list the .c files. It did even without an explicit include directive in Cargo.toml, but I added one anyway and also listed the .h files in it.

    Regardless, if I touch any of the .c/.h files, then cc does not trigger re-compilation.

    I'm attaching a small with_c.zip file which demonstrates the problem - see RUNME.sh and the results I get in RUNME.log.

dot-asm

dot-asm commented on Dec 22, 2022

@dot-asm
Contributor

I should expect the C compiler to be invoked if any of the files in cargo package --list were changed.

As already implied, the question is when does cargo execute the build.rs. That's all to it. The fact that build.rs invokes C compiler is immaterial to the said decision.

it doesn't seem to work for me.

Ah! It ought to be one of the recent modifications that broke it. It does work if you specify the dependency as cc = "<=1.0.73"... Not that I insist on doing this, but at least there is an explanation for why it stopped working the described way.

Even if it did work this way, that would be sub-optimal.

It's by cargo's design, we have to accept it.

I guess it is a matter of deciding "how much like make do we want cc to be".

It sounds like you'd be better off using cmake-rs. Idea would be to have cargo detect a change and hand it off to cmake to identify what actually needs to be done. Replicating the make functionality in cc-rs would probably be deemed out of this project's scope...

dot-asm

dot-asm commented on Dec 22, 2022

@dot-asm
Contributor

one of the recent modifications that broke it.

More specifically emission of cargo:rerun-if-env-changed=<this-n-that> in 1.0.74. Collateral problem here is that one single rerun-if apparently puts aside the internal cargo decision making mechanism. You can suppress the referred directives with .emit_rerun_if_env_changed(false) method.

orenbenkiki

orenbenkiki commented on Dec 22, 2022

@orenbenkiki
Author

Thanks for the clarification. As long as my C code is trivial, cc will do the trick. For larger, more complex projects, cmake-rs might be better. Good to know the options.

Yes, using 1.0.73 does fix the issue for me. Thanks!

thomcc

thomcc commented on Dec 22, 2022

@thomcc
Member

I’m on vacation now, but I’ll investigate what broke in 1.0.74 when I get back.

Note that pinning a version like that will cause problems for your users down the line, since if another crate in the dependency graph depends on a later version of cc, cargo will error (it only duplicates versions if they would be semver incompatible).

orenbenkiki

orenbenkiki commented on Dec 22, 2022

@orenbenkiki
Author

Noted - thanks for the warning.

Happy holidays!

bw-itis-archival

bw-itis-archival commented on Feb 22, 2024

@bw-itis-archival

Is there anything more on this? I just ran into it in my project and it's quite a surprise when c files don't recompile (especially since they sometimes do - if you have errors and compilation fails, it will re-run on a new cargo build, but otherwise I need to cargo clean and rebuild all the rust code as well to get c to recompile).

I've tried adding .emit_rerun_if_env_changed(false) to the cc::Build chain in my build.rs but it doesn't seem to make any difference.

bw-itis-archival

bw-itis-archival commented on Feb 22, 2024

@bw-itis-archival

If I add println!("cargo:rerun-if-changed=src"); to build.rs this does trigger a rebuild on changes (all my .c and .h files are in src).

NobodyXu

NobodyXu commented on Feb 22, 2024

@NobodyXu
Collaborator

Maybe we could add a new function emit_rerun_if_src_changed for this that is set to false by default for backwards compatibility?

pinned this issue on Jun 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @orenbenkiki@thomcc@bw-itis-archival@dot-asm@NobodyXu

        Issue actions

          Rebuild if changed · Issue #765 · rust-lang/cc-rs