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

allow specifying a dockerfile to use for a target and implement "pre-build"ing #678

Merged
merged 1 commit into from
Jun 15, 2022

Conversation

Emilgardis
Copy link
Member

@Emilgardis Emilgardis commented Apr 3, 2022

Add optional target.{target}.dockerfile[.file], target.{target}.dockerfile.context and target.{target}.dockerfile.build-args to invoke docker/podman build before using an image.

also adds target.{target}.pre-build to allow pre-building as per #565

In total, this PR allows a user to do the following:

[build]
pre-build = [
    "dpkg --add-architecture $CROSS_DEB_ARCH", 
    "apt-get update && apt-get --assume-yes install libssl-dev:$CROSS_DEB_ARCH"
    ]
[target.x86_64-unknown-linux-gnu]
dockerfile = { file = "./Dockerfile.x86_64_ssl", context = "..", build-args = { ARG1 = "foo" }}
image = "my-image:latest"
pre-build = ["echo 'Hello world!'"]

fixes #565

@Emilgardis Emilgardis requested a review from a team as a code owner April 3, 2022 22:26
Emilgardis added a commit to Emilgardis/cross that referenced this pull request Apr 3, 2022
Emilgardis added a commit to Emilgardis/cross that referenced this pull request Apr 3, 2022
Emilgardis added a commit to Emilgardis/cross that referenced this pull request Apr 3, 2022
docs/cross_toml.md Outdated Show resolved Hide resolved
src/docker.rs Outdated
@@ -248,8 +250,51 @@ pub fn run(
}
}

let image = if let Some(dockerfile) = config.dockerfile(target)? {
let mut docker_build = docker_command("build")?;
Copy link
Member Author

Choose a reason for hiding this comment

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

Should maybe add a flag to allow specifying more flags for this command

Copy link
Contributor

Choose a reason for hiding this comment

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

We already have build-args, so we need anything else?

Copy link
Member Author

Choose a reason for hiding this comment

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

thinking like DOCKER_OPTS, I think a DOCKER_BUILD_OPTS is the best way to do it

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ok, that's a good suggestion. Maybe also consider then #770, since we handle more than just docker now? If we're introducing new environment variables, we don't need to worry about backwards compatibility.

src/docker.rs Outdated Show resolved Hide resolved
@Emilgardis Emilgardis force-pushed the dockerfile branch 3 times, most recently from afd44c2 to 14c7ff8 Compare April 4, 2022 10:16
@Emilgardis
Copy link
Member Author

I think this is a nice addition to #635

@Emilgardis Emilgardis mentioned this pull request Apr 5, 2022
@Emilgardis Emilgardis changed the title allow specifying a dockerfile to use for a target allow specifying a dockerfile to use for a target and implement "pre-build"ing Apr 5, 2022
@Emilgardis
Copy link
Member Author

I've made this also implement #565

I think I personally like this approach better to #635

CHANGELOG.md Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
src/cross_toml.rs Outdated Show resolved Hide resolved
src/cross_toml.rs Outdated Show resolved Hide resolved
@Emilgardis Emilgardis force-pushed the dockerfile branch 3 times, most recently from 2bf937d to 876fcbd Compare April 7, 2022 19:33
README.md Outdated Show resolved Hide resolved
@Emilgardis
Copy link
Member Author

We can also add a label to our images to signal that an image is intended for cross, and that way we can return those with the tools in #767

not sure what to label them though, org.cross-rs.for-cross-target=<target> ?
(i just bought that domain so we can use it :) )

@Emilgardis Emilgardis marked this pull request as draft June 8, 2022 14:46
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/docker.rs Outdated Show resolved Hide resolved
src/docker.rs Outdated Show resolved Hide resolved
src/docker.rs Outdated
@@ -248,8 +250,51 @@ pub fn run(
}
}

let image = if let Some(dockerfile) = config.dockerfile(target)? {
let mut docker_build = docker_command("build")?;
Copy link
Contributor

Choose a reason for hiding this comment

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

We already have build-args, so we need anything else?

src/cross_toml.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
src/docker.rs Outdated
}

match self {
Dockerfile::File { path, .. } => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be preferable to handle the FROM {{image}} ourselves? That way the users can just add the components they want afterwards? Not sure about this but I think it might be easier.

Copy link
Member Author

@Emilgardis Emilgardis Jun 8, 2022

Choose a reason for hiding this comment

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

I don't understand this comment I think.

do you mean for pre-build, we do something like

FROM {image}
{instructions}

where {instructions} is the entries newline separated?

Copy link
Contributor

@Alexhuszagh Alexhuszagh Jun 8, 2022

Choose a reason for hiding this comment

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

Yeah, say we have a Dockerfile as follows for bindgen support:

RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
    libclang-3.9-dev clang-3.9

We want to use the same base Dockerfile for all images, so we'd rather not have to create a new Dockerfile for all targets. For the target armv7-unknown-linux-gnueabihf, this will automatically get transformed to:

FROM ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:main
RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
    libclang-3.9-dev clang-3.9

And this way all we need to do is ensure the name is provided in our Cross.toml for all targets. Also, then we could concatenate the pre-build steps and this into a single file and avoid having to add the pre-build tag. If we also have pre-build hooks, this would then become:

FROM ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:main
RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
    libclang-3.9-dev clang-3.9
ARG CROSS_CMD
RUN eval "${{CROSS_CMD}}"

Copy link
Member Author

Choose a reason for hiding this comment

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

I fail to see the point, you could already do that with

pre-build = ["apt-get update && apt-get install --assume-yes --no-install-recommends libclang-3.9-dev clang-3.9"]

I see another solution though, make a target.<target>.dockerfile.provide-base that would do it instead with the image you provide. But I still don't see the benefit

Copy link
Contributor

Choose a reason for hiding this comment

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

That's just a simple example: if something requires the ENV keyword or similar (like, say we want vcpkg for providing dependencies of cross-compiled C/C++ libraries), we can't simply use pre-build hooks.

Copy link
Contributor

Choose a reason for hiding this comment

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

A more complex example would be:

RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
    libclang-3.9-dev clang-3.9
RUN git clone https://github.com/Microsoft/vcpkg.git && ./vcpkg/bootstrap-vcpkg.sh
ENV PATH /path/to/vcpkg/bin/dir/:$PATH

# do more stuff here, maybe add an ARG, etc.
# everything is platform generic.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could have pre-build hooks encompass this functionality (RUN isn't implicit anymore, and then all this can be easily encompassed there)? That way you can provide a complete Dockerfile, or just add extra commands to the existing one?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've implemented this (i think, not fully tested), but with allowing the user to tell cross to insert FROM with target.TARGET.dockerfile.provide-base.

Copy link
Member Author

Choose a reason for hiding this comment

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

and removed with f98a6e6

instead we provide a build arg

ARG CROSS_BUILD_IMAGE that will be whatever cross would use

@Alexhuszagh
Copy link
Contributor

We can also add a label to our images to signal that an image is intended for cross, and that way we can return those with the tools in #767

not sure what to label them though, org.cross-rs.for-cross-target=<target> ? (i just bought that domain so we can use it :) )

I think that's a good idea, and we can then add extracting the label if needed for the list/remove images commands.

@Emilgardis Emilgardis force-pushed the dockerfile branch 2 times, most recently from f198b74 to e56d9be Compare June 12, 2022 20:57
Copy link
Member Author

@Emilgardis Emilgardis left a comment

Choose a reason for hiding this comment

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

Would it make sense to allow the following

[target.aarch64-unknown-linux-gnu.pre-build]
lines = ["/lib.sh"]

[[target.aarch64-unknown-linux-gnu.pre-build.copy]]
files = ["scripts/lib.sh"]
location = "/"

src/docker/shared.rs Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
@Emilgardis Emilgardis force-pushed the dockerfile branch 2 times, most recently from 1a0a942 to 3c7f900 Compare June 15, 2022 11:32
@Emilgardis
Copy link
Member Author

this should be ready now, I'm happy with the functionality.

Copy link
Contributor

@Alexhuszagh Alexhuszagh left a comment

Choose a reason for hiding this comment

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

Minor comments, otherwise looks great.

docs/cross_toml.md Outdated Show resolved Hide resolved
content: format!(
r#"
FROM {image}
ARG CROSS_DEB_ARCH=
Copy link
Contributor

@Alexhuszagh Alexhuszagh Jun 15, 2022

Choose a reason for hiding this comment

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

This (CROSS_DEB_ARCH) should probably be added to the wiki?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've added it to the readme, will definitely add it to the wiki

Copy link
Member Author

Choose a reason for hiding this comment

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

scratch that, I haven't... wiki seems good

src/docker/shared.rs Show resolved Hide resolved
src/file.rs Show resolved Hide resolved
src/extensions.rs Show resolved Hide resolved
src/cross_toml.rs Outdated Show resolved Hide resolved
src/cross_toml.rs Show resolved Hide resolved
src/cross_toml.rs Outdated Show resolved Hide resolved
src/cross_toml.rs Show resolved Hide resolved
src/docker/shared.rs Outdated Show resolved Hide resolved
@Emilgardis Emilgardis force-pushed the dockerfile branch 2 times, most recently from d113ac1 to 0bfc338 Compare June 15, 2022 21:38
@Emilgardis
Copy link
Member Author

all done!

@Alexhuszagh
Copy link
Contributor

Went over all the changes from the comments, and it looks good. Once this merges I'll be adding additional documentation to the wiki.

bors r+

@bors
Copy link
Contributor

bors bot commented Jun 15, 2022

Build succeeded:

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

Successfully merging this pull request may close these issues.

Add pre-build hook
2 participants