diff --git a/src/bin/cook.rs b/src/bin/cook.rs index e9ed47e856e1c101aa1392a2f9478ec837751e5d..43c188dd65246346fe530334a7d01913940f7ce0 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -282,6 +282,21 @@ fn build(recipe_dir: &Path, source_dir: &Path, build: &BuildRecipe) -> Result<Pa let sysroot_dir_tmp = recipe_dir.join("sysroot.tmp"); create_dir_clean(&sysroot_dir_tmp)?; + // Make sure sysroot/include exists + fs::create_dir(sysroot_dir_tmp.join("include")).map_err(|err| format!( + "failed to create '{}/include': {}\n{:#?}", + sysroot_dir_tmp.display(), + err, + err + ))?; + // Make sure sysroot/lib exists + fs::create_dir(sysroot_dir_tmp.join("lib")).map_err(|err| format!( + "failed to create '{}/lib': {}\n{:#?}", + sysroot_dir_tmp.display(), + err, + err + ))?; + for dependency in build.dependencies.iter() { let public_path = "build/public.key"; //TODO: sanitize name @@ -315,64 +330,95 @@ fn build(recipe_dir: &Path, source_dir: &Path, build: &BuildRecipe) -> Result<Pa create_dir_clean(&build_dir)?; } + let pre_script = r#"# Common pre script +# This puts cargo build artifacts in the build directory +export CARGO_TARGET_DIR="${COOKBOOK_BUILD}/target" + +# This adds the sysroot includes for most C compilation +#TODO: check paths for spaces! +export CFLAGS="-I${COOKBOOK_SYSROOT}/include" + +# This adds the sysroot libraries and compiles binaries statically for most C compilation +#TODO: check paths for spaces! +export LDFLAGS="-L${COOKBOOK_SYSROOT}/lib --static" + +# These ensure that pkg-config gets the right flags from the sysroot +export PKG_CONFIG_ALLOW_CROSS=1 +export PKG_CONFIG_PATH= +export PKG_CONFIG_LIBDIR="${COOKBOOK_SYSROOT}/lib/pkgconfig" +export PKG_CONFIG_SYSROOT_DIR="${COOKBOOK_SYSROOT}" + +# cargo template +COOKBOOK_CARGO="redoxer" +COOKBOOK_CARGO_FLAGS=( + --path "${COOKBOOK_SOURCE}" + --root "${COOKBOOK_STAGE}" +) +function cookbook_cargo { + "${COOKBOOK_CARGO}" install "${COOKBOOK_CARGO_FLAGS[@]}" +} + +# configure template +COOKBOOK_CONFIGURE="${COOKBOOK_SOURCE}/configure" +COOKBOOK_CONFIGURE_FLAGS=( + --host="${TARGET}" + --prefix="" + --disable-shared + --enable-static +) +COOKBOOK_MAKE="make" +function cookbook_configure { + "${COOKBOOK_CONFIGURE}" "${COOKBOOK_CONFIGURE_FLAGS[@]}" + "${COOKBOOK_MAKE}" -j "$(nproc)" + "${COOKBOOK_MAKE}" install DESTDIR="${COOKBOOK_STAGE}" +} +"#; + + let post_script = r#"# Common post script +# Strip binaries +if [ -d "${COOKBOOK_STAGE}/bin" ] +then + find "${COOKBOOK_STAGE}/bin" -type f -exec "${TARGET}-strip" -v {} ';' +fi + +# Remove libtool files +if [ -d "${COOKBOOK_STAGE}/lib" ] +then + find "${COOKBOOK_STAGE}/lib" -type f -name '*.la' -exec rm -fv {} ';' +fi +"#; + //TODO: better integration with redoxer (library instead of binary) //TODO: configurable target - match &build.kind { - BuildKind::Cargo => { - let mut command = Command::new("redoxer"); - command.arg("install"); - //TODO: --debug if desired - command.arg("--path").arg(&source_dir); - command.arg("--root").arg(&stage_dir_tmp); - command.env("CARGO_TARGET_DIR", &build_dir); - run_command(command)?; - }, - BuildKind::Configure => { - //TODO: Add more configurability, convert script to Rust - let mut command = Command::new("redoxer"); - command.arg("env"); - command.arg("bash").arg("-ex"); - //TODO: remove unwraps - command.env("COOKBOOK_STAGE", &stage_dir_tmp.canonicalize().unwrap()); - command.env("COOKBOOK_SOURCE", &source_dir.canonicalize().unwrap()); - command.env("COOKBOOK_SYSROOT", &sysroot_dir.canonicalize().unwrap()); - command.current_dir(&build_dir); - run_command_stdin(command, r#" - export CFLAGS="-I'${COOKBOOK_SYSROOT}/include'" - export LDFLAGS="-L'${COOKBOOK_SYSROOT}/lib' --static" - "${COOKBOOK_SOURCE}/configure" \ - --host="${TARGET}" \ - --prefix="" \ - --disable-shared \ - --enable-static - make -j "$(nproc)" - make install DESTDIR="${COOKBOOK_STAGE}" - - # Strip binaries - if [ -d "${COOKBOOK_STAGE}/bin" ] - then - find "${COOKBOOK_STAGE}/bin" -type f -exec "${TARGET}-strip" -v {} ';' - fi - - # Remove libtool files - if [ -d "${COOKBOOK_STAGE}/lib" ] - then - find "${COOKBOOK_STAGE}/lib" -type f -name '*.la' -exec rm -fv {} ';' - fi - "#.as_bytes())?; - }, - BuildKind::Custom { script } => { - let mut command = Command::new("redoxer"); - command.arg("env"); - command.arg("bash").arg("-ex"); - //TODO: remove unwraps - command.env("COOKBOOK_STAGE", &stage_dir_tmp.canonicalize().unwrap()); - command.env("COOKBOOK_SOURCE", &source_dir.canonicalize().unwrap()); - command.env("COOKBOOK_SYSROOT", &sysroot_dir.canonicalize().unwrap()); - command.current_dir(&build_dir); - run_command_stdin(command, script.as_bytes())?; - }, - } + //TODO: Add more configurability, convert scripts to Rust? + let script = match &build.kind { + BuildKind::Cargo => "cookbook_cargo", + BuildKind::Configure => "cookbook_configure", + BuildKind::Custom { script } => script + }; + + let command = { + let mut command = Command::new("redoxer"); + command.arg("env"); + command.arg("bash").arg("-ex"); + + //TODO: remove unwraps + let cookbook_build = build_dir.canonicalize().unwrap(); + let cookbook_recipe = recipe_dir.canonicalize().unwrap(); + let cookbook_stage = stage_dir_tmp.canonicalize().unwrap(); + let cookbook_source = source_dir.canonicalize().unwrap(); + let cookbook_sysroot = sysroot_dir.canonicalize().unwrap(); + command.current_dir(&cookbook_build); + command.env("COOKBOOK_BUILD", &cookbook_build); + command.env("COOKBOOK_RECIPE", &cookbook_recipe); + command.env("COOKBOOK_STAGE", &cookbook_stage); + command.env("COOKBOOK_SOURCE", &cookbook_source); + command.env("COOKBOOK_SYSROOT", &cookbook_sysroot); + command + }; + + let full_script = format!("{}\n{}\n{}", pre_script, script, post_script); + run_command_stdin(command, full_script.as_bytes())?; // Move stage.tmp to stage atomically rename(&stage_dir_tmp, &stage_dir)?;