Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rustfmt always recompiles #110

Closed
marcusklaas opened this issue Jun 18, 2015 · 12 comments
Closed

Rustfmt always recompiles #110

marcusklaas opened this issue Jun 18, 2015 · 12 comments

Comments

@marcusklaas
Copy link
Contributor

Rustfmt always recompiles on my machine, even if no source code has been altered. Is this happening for other people as well? If so, why does it happen and how can we prevent it?

@cassiersg
Copy link
Contributor

It's also happening for me. It seems to be related to the build script. Commenting the line build=build.rs prevent the rebuild when nothing has changed. (I don't know why ?)

@marcusklaas
Copy link
Contributor Author

Interesting. Maybe it updates the last edit timestamp on default.toml in the root directory, which could trick Cargo into believing code may have changed?

Edit: I'll play around a bit with this.

@cassiersg
Copy link
Contributor

Commenting the line std::fs::copy(in_file, out_file).unwrap(); doesn't change anything. It's maybe a default behavior of Cargo to rebuild everything when there is a build script... needs more investigation.

@marcusklaas
Copy link
Contributor Author

Weird -- commenting out that line does the trick here...

Edit: I've hacked together this update version of build.rs. Seems to work better for now. But if I guess if commenting the copy doesn't work for you, then this surely won't either :/

// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Build script. Just copies default.toml from the src to the target dir.

use std::env;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::convert::AsRef;
use std::io::Read;

fn main() {
    let in_file = Path::new("src/default.toml");

    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let mut out_file = PathBuf::new();
    out_file.push(manifest_dir);
    out_file.push("default.toml");

    let same = are_same(&out_file, in_file);

    println!("config up to date: {:?}", same);

    if !same {
        std::fs::copy(in_file, &out_file).unwrap();
    }
}

fn are_same<P: AsRef<Path>, Q: AsRef<Path>>(lhs: P, rhs: Q) -> bool {
    let mut f1 = match File::open(lhs) {
        Err(..) => return false,
        Ok(file) => file
    };

    let mut f2 = match File::open(rhs) {
        Err(..) => return false,
        Ok(file) => file
    };

    let mut buf1 = Vec::new();
    let mut buf2 = Vec::new();

    if let Err(..) = f1.read_to_end(&mut buf1) {
        return false;
    }

    if let Err(..) = f2.read_to_end(&mut buf2) {
        return false;
    }

    &buf1[..] == &buf2[..]
}

@cassiersg
Copy link
Contributor

The source of trouble was a symlink rustfmt/rustfmt -> rustfmt/target/debug/rustfmt. Cargo seems to consider all files under rustfmt/ to decide when to rebuild.
Without this symlink, #111 fixes the bug.

@marcusklaas
Copy link
Contributor Author

Did you create this symlink by hand?

@marcusklaas
Copy link
Contributor Author

Unfortunately, https://github.com/nrc/rustfmt/pull/111 does not prevent recompilation one when of the test files in /tests/source/ or /tests/target/ changes... Any ideas on how we could fix that?

@cassiersg
Copy link
Contributor

Yes, I created the symlink by hand (for tests, because cargo run recompiled always).
I don't know how to avoid rebuild when a non-source file is touched, but I have maybe an explaination why it occurs: the build script is intended to build external dependencies, but cargo doesn't which files the script builds, so it takes a conservative approach : rebuild if any file changed. If you remove the build script from Cargo.toml, a change in test files doesn't trigger rebuild anymore.
I think the good thing would be to remove the build script, and use something like a deploy script, but it doesn't seem to exist (yet ?). There is maybe another way : cargo is made to recieve build commands from the stdout of the build script, there are maybe commands to indicate dependencies (But at first sight there isn't anything like this in the docs.)

@marcusklaas
Copy link
Contributor Author

Removing the build script sounds good to me. Maybe we can add the default.toml to the root directory in the repository and also add it to .gitignore, so that editing it will not register as a change to the repository.

@nrc
Copy link
Member

nrc commented Jun 22, 2015

Might be worth asking on #cargo about this, seems like there ought to be a solution.

@marcusklaas
Copy link
Contributor Author

It's a known issue: rust-lang/cargo#1162. No known workarounds at the moment. Maybe it's a nice issue to work on.

@cassiersg
Copy link
Contributor

Build script was removed by #165.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants