Skip to content

When cross-compiling, also build target-arch tarballs for libstd. (Closes: #42320) #45322

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

Merged
merged 1 commit into from
Nov 6, 2017

Conversation

infinity0
Copy link
Contributor

@infinity0 infinity0 commented Oct 16, 2017

Half of the logic is actually in there already in install.rs:install_std but it fails with an error like:

sh: 0: Can't open /<>/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-powerpc64le-unknown-linux-gnu/install.sh

because the target-arch dist tarball wasn't built as well. This commit fixes that so the overall install works.

There is one minor bug in the existing code which this commit doesn't fix - the install.log from multiple runs of the installer gets clobbered, which seems like it might interfere with the uninstall process (I didn't look very deeply into this, because it doesn't affect what I need to do.) The actual installed files under DESTDIR seem fine though - either they are installed under an arch-specific path, or the multiple runs will clobber the same path with the same arch-independent file.

@rust-highfive
Copy link
Contributor

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 16, 2017
@nikomatsakis
Copy link
Contributor

r? @alexcrichton -- I know nothing of this code.

@infinity0
Copy link
Contributor Author

Updated the commit, previous one was based on faulty testing not cleaning out all build products. This one is also "more obvious" in what it does.

However it will (harmlessly) try to install both native and foreign architectures twice, which I haven't figured out how to avoid:

[..]
Install std stage2 (Some("x86_64-unknown-linux-gnu"))
running: "sh" "/build/rustc-we5rHS/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-x86_64-unknown-linux-gnu/install.sh" "--prefix=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr" "--sysconfdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/etc" "--docdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/doc/rust" "--bindir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/bin" "--libdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib" "--mandir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/man" "--disable-ldconfig"
install: creating uninstall script at /build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib/rustlib/uninstall.sh
install: installing component 'rust-std-x86_64-unknown-linux-gnu'

    std is standing at the ready.

Install std stage2 (Some("powerpc64le-unknown-linux-gnu"))
running: "sh" "/build/rustc-we5rHS/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-powerpc64le-unknown-linux-gnu/install.sh" "--prefix=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr" "--sysconfdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/etc" "--docdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/doc/rust" "--bindir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/bin" "--libdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib" "--mandir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/man" "--disable-ldconfig"
install: creating uninstall script at /build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib/rustlib/uninstall.sh
install: installing component 'rust-std-powerpc64le-unknown-linux-gnu'

    std is standing at the ready.

< Std { stage: 2, target: "x86_64-unknown-linux-gnu", host: "x86_64-unknown-linux-gnu" }
> Std { stage: 2, target: "powerpc64le-unknown-linux-gnu", host: "x86_64-unknown-linux-gnu" }
  c Assemble { target_compiler: Compiler { stage: 2, host: "x86_64-unknown-linux-gnu" } }
  c Std { compiler: Compiler { stage: 2, host: "x86_64-unknown-linux-gnu" }, target: "x86_64-unknown-linux-gnu" }
  c Assemble { target_compiler: Compiler { stage: 2, host: "x86_64-unknown-linux-gnu" } }
  c Std { compiler: Compiler { stage: 2, host: "x86_64-unknown-linux-gnu" }, target: "powerpc64le-unknown-linux-gnu" }
Install std stage2 (Some("x86_64-unknown-linux-gnu"))
running: "sh" "/build/rustc-we5rHS/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-x86_64-unknown-linux-gnu/install.sh" "--prefix=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr" "--sysconfdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/etc" "--docdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/doc/rust" "--bindir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/bin" "--libdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib" "--mandir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/man" "--disable-ldconfig"
install: uninstalling component 'rust-std-x86_64-unknown-linux-gnu'
install: creating uninstall script at /build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib/rustlib/uninstall.sh
install: installing component 'rust-std-x86_64-unknown-linux-gnu'

    std is standing at the ready.

Install std stage2 (Some("powerpc64le-unknown-linux-gnu"))
running: "sh" "/build/rustc-we5rHS/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-powerpc64le-unknown-linux-gnu/install.sh" "--prefix=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr" "--sysconfdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/etc" "--docdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/doc/rust" "--bindir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/bin" "--libdir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib" "--mandir=/build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/share/man" "--disable-ldconfig"
install: uninstalling component 'rust-std-powerpc64le-unknown-linux-gnu'
install: creating uninstall script at /build/rustc-we5rHS/rustc-1.21.0+dfsg1/debian/tmp/usr/lib/rustlib/uninstall.sh
install: installing component 'rust-std-powerpc64le-unknown-linux-gnu'

    std is standing at the ready.

What I have in config.toml is:

build = "x86_64-unknown-linux-gnu"
host = ["powerpc64le-unknown-linux-gnu"]
target = ["powerpc64le-unknown-linux-gnu"]

compiler: builder.compiler(self.stage, self.host),
target: self.target
});
for target in &builder.build.targets {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels wrong to me. In general, we shouldn't have to think about targets within build steps, instead the step should be configured to run for all targets. Perhaps the actual change should be on the previous line, where only_hosts: true is currently -- maybe that should be false? I'm not too certain what we're trying to accomplish here, either, but mostly am happy to take changes as long as @alexcrichton is happy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That may be better, however I was not sure of the exact meaning of that flag. Let me try to explain this commit: I was only mirroring the already-existing logic in install_std further above, which explicitly calls install_sh over all targets. Because it does this, I thought that it should also explicitly call ensure(dist::Std ...) explicitly over all targets.

You are right that it would be neater to do this declaratively though, to declare "depends on all architectures" on a meta-level outside of the step definitions. This would also allow (and maybe require) install_std to not loop over all target arches.

If I understand correctly, the overall goal of "x.py install" is to install all targets' libstd into DESTDIR. Now there is a further issue that actually rustbuild supports multiple hosts, so in fact this process is run for all hosts, installing into the same DESTDIR, which might explain the 2x2 issue I described in my other post. In more detail:

From the documentation of config.toml.example, it seems that rust turns my config

build = "x86_64-unknown-linux-gnu"
host = ["powerpc64le-unknown-linux-gnu"]
target = ["powerpc64le-unknown-linux-gnu"]

effectively into

build = "x86_64-unknown-linux-gnu"
host = [build + "powerpc64le-unknown-linux-gnu"]
target = host + ["powerpc64le-unknown-linux-gnu"]

and this is what gets run in the "install" process. (Hopefully someone can confirm; I'm just guessing here based on what the documentation says.) So "install" gets run for all hosts, and each of these installs all targets' libstd, at least after my patch is applied to fix the errors.

Obviously this is not ideal (multiple /usr/bin/rustc gets installed into the same location, etc), but this currently does not affect me negatively, so I'm prepared to defer the solution to this for another day - since the $build architecture install process gets run first, the foreign architecture (what I'm actually interested in) ends up clobbering all the previous files, and I end up with what I actually want. I'm also not interested in the $build-architecture libstd, but that gets installed into a architecture-specific path so I can just ignore it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That all seems correct to me -- I'm happy to take this for now, I think, since it seems to be following the pre-existing logic we have in the install step anyway. Going to leave to @alexcrichton's final approval, but sounds good to me.

@infinity0 infinity0 force-pushed the master branch 2 times, most recently from d5d50ad to 6642f76 Compare October 16, 2017 22:36
@alexcrichton
Copy link
Member

Thanks for the PR @infinity0! I agree with @Mark-Simulacrum that this may not be precisely the best solution here, but I think you've got a good idea with calling ensure just before we actually run the install steps as that'll make for sure that the distribution artifacts are available.

For installing and multiple configured hosts, I don't think we've basically ever had a way to get that to work. If you've got suggestions of how to support it, they'd be most welcome! Otherwise for now you'll need to run ./x.py install with --target and --host arguments I believe.

@carols10cents
Copy link
Member

@alexcrichton is there something that needs to be done on this PR before you'll r+?

@infinity0
Copy link
Contributor Author

infinity0 commented Oct 23, 2017

I forgot to mention, I'd be happy adding something to the install target documentation. I was not passing --host or --target but rather had a config.toml with build = $native, host = [$foreign], target = [$foreign] for a cross-build. Based on my testing with this patch, this is sufficient to ensure that the $foreign compiler and libraries are installed, which is what I wanted.

I'm not sure how it's "supposed" to work for cross-builds however. So if what I'm doing only works "by accident" then it would be good either to make it formal or fix it and the docs up properly.

@alexcrichton
Copy link
Member

@infinity0 what do you think about calling ensure just before a std artifact is needed? I think that'd be a bit more of a targeted solution to this, right?

Also I'd imagine that if you want to install a cross-compiler you'd probably want to pass --host and --target to the ./x.py install command. Otherwise we have 2 host compilers and 2 standard libraries to install, and we don't currently have a way of support that (into one installation root).

@infinity0
Copy link
Contributor Author

Sorry, I did not quite understand that comment. Do you mean I should combine the two loops - the one I added plus the existing one inside install_std - into one single loop?

@alexcrichton
Copy link
Member

Sorry yeah what I mean is that we have a suite of installation functions, and they should all ensure what they're installing just before they install it. I believe that'd amount to basically just collapsing into one loop.

@shepmaster shepmaster added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 3, 2017
@infinity0
Copy link
Contributor Author

I've made those changes, please review!

This fixes cross-compile installation. Half of the logic is actually in there
already in install.rs:install_std but it fails with an error like:

sh: 0: Can't open /<<BUILDDIR>>/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-powerpc64le-unknown-linux-gnu/install.sh

because the target-arch dist tarball wasn't built as well.
@alexcrichton
Copy link
Member

@bors: r+

Thanks!

@bors
Copy link
Collaborator

bors commented Nov 6, 2017

📌 Commit 32cf6e6 has been approved by alexcrichton

@bors
Copy link
Collaborator

bors commented Nov 6, 2017

⌛ Testing commit 32cf6e6 with merge dbe8055...

bors added a commit that referenced this pull request Nov 6, 2017
When cross-compiling, also build target-arch tarballs for libstd. (Closes: #42320)

Half of the logic is actually in there already in install.rs:install_std but it fails with an error like:

sh: 0: Can't open /<<BUILDDIR>>/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-powerpc64le-unknown-linux-gnu/install.sh

because the target-arch dist tarball wasn't built as well. This commit fixes that so the overall install works.

There is one minor bug in the existing code which this commit doesn't fix - the install.log from multiple runs of the installer gets clobbered, which seems like it might interfere with the uninstall process (I didn't look very deeply into this, because it doesn't affect what I need to do.) The actual installed files under DESTDIR seem fine though - either they are installed under an arch-specific path, or the multiple runs will clobber the same path with the same arch-independent file.
@bors
Copy link
Collaborator

bors commented Nov 6, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing dbe8055 to master...

@bors bors merged commit 32cf6e6 into rust-lang:master Nov 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants