Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/embed-manifest/src/embed/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 4 kB image not shown  

Quelle  mod.rs

  Sprache: Rust
 

use std::env;
use std::fs::{self, File};
use std::io::{self, stdout, BufWriter, Cursor, Write};
use std::path::{Path, PathBuf};

use crate::manifest::ManifestBuilder;

use self::coff::{resource_data_entry, resource_directory_id_entry, resource_directory_table, CoffWriter, MachineType};
use self::error::Error;

mod coff;
pub mod error;

#[cfg(test)]
mod test;

/// Embeds the manifest described by `manifest` by converting it to XML,
/// then saving it to a file and passing the correct options to the linker
/// on MSVC targets, or by building a static library and instructing Cargo
/// to link the executable against it on GNU targets.
pub fn embed_manifest(manifest: ManifestBuilder) -> Result<(), Error> {
    let out_dir = get_out_dir()?;
    let target = get_target()?;
    if matches!(target.os, TargetOs::WindowsMsvc) {
        let manifest_file = out_dir.join("manifest.xml");
        write!(BufWriter::new(File::create(&manifest_file)?), "{}", manifest)?;
        link_manifest_msvc(&manifest_file, &mut stdout().lock())
    } else {
        let manifest_data = manifest.to_string();
        link_manifest_gnu(manifest_data.as_bytes(), &out_dir, target.arch, &mut stdout().lock())
    }
}

/// Directly embeds the manifest in the provided `file` by passing the correct
/// options to the linker on MSVC targets, or by building a static library
/// and instructing Cargo to link the executable against it on GNU targets.
pub fn embed_manifest_file<P: AsRef<Path>>(file: P) -> Result<(), io::Error> {
    let out_dir = get_out_dir()?;
    let target = get_target()?;
    if matches!(target.os, TargetOs::WindowsMsvc) {
        Ok(link_manifest_msvc(file.as_ref(), &mut stdout().lock())?)
    } else {
        let manifest = fs::read(file.as_ref())?;
        Ok(link_manifest_gnu(&manifest, &out_dir, target.arch, &mut stdout().lock())?)
    }
}

fn get_out_dir() -> Result<PathBuf, io::Error> {
    match env::var_os("OUT_DIR") {
        Some(dir) => Ok(PathBuf::from(dir)),
        None => env::current_dir(),
    }
}

enum TargetOs {
    WindowsGnu,
    WindowsMsvc,
}

struct Target {
    arch: MachineType,
    os: TargetOs,
}

fn get_target() -> Result<Target, Error> {
    match env::var("TARGET") {
        Ok(target) => parse_target(&target),
        _ => Err(Error::unknown_target()),
    }
}

fn parse_target(target: &str) -> Result<Target, Error> {
    let mut iter = target.splitn(3'-');
    let arch = match iter.next() {
        Some("i686") => MachineType::I386,
        Some("aarch64") => MachineType::Aarch64,
        Some("x86_64") => MachineType::X86_64,
        _ => return Err(Error::unknown_target()),
    };
    if iter.next() != Some("pc") {
        return Err(Error::unknown_target());
    }
    let os = match iter.next() {
        Some("windows-gnu") => TargetOs::WindowsGnu,
        Some("windows-gnullvm") => TargetOs::WindowsGnu,
        Some("windows-msvc") => TargetOs::WindowsMsvc,
        _ => return Err(Error::unknown_target()),
    };
    Ok(Target { arch, os })
}

fn link_manifest_msvc<W: Write>(manifest_path: &Path, out: &mut W) -> Result<(), Error> {
    writeln!(out, "cargo:rustc-link-arg-bins=/MANIFEST:EMBED")?;
    writeln!(
        out,
        "cargo:rustc-link-arg-bins=/MANIFESTINPUT:{}",
        manifest_path.canonicalize()?.display()
    )?;
    writeln!(out, "cargo:rustc-link-arg-bins=/MANIFESTUAC:NO")?;
    Ok(())
}

fn link_manifest_gnu<W: Write>(manifest: &[u8], out_dir: &Path, arch: MachineType, out: &style='color:red'>mut W) -> Result<(), Error> {
    // Generate a COFF object file containing the manifest in a .rsrc section.
    let object_data = create_object_file(manifest, arch)?;
    let path = out_dir.join("embed-manifest.o");
    fs::create_dir_all(out_dir)?;
    fs::write(&path, object_data)?;

    // Link the manifest with the executable.
    writeln!(out, "cargo:rustc-link-arg-bins={}", path.display())?;
    Ok(())
}

fn create_object_file(manifest: &[u8], arch: MachineType) -> Result<Vec<u8>, io::Error> {
    // Start object file with .rsrc section.
    let mut obj = CoffWriter::new(Cursor::new(Vec::with_capacity(4096)), arch)?;

    // Create resource directories for type ID 24, name ID 1, language ID 1033.
    obj.add_data(&resource_directory_table(1))?;
    obj.add_data(&resource_directory_id_entry(2424true))?;
    obj.add_data(&resource_directory_table(1))?;
    obj.add_data(&resource_directory_id_entry(148true))?;
    obj.add_data(&resource_directory_table(1))?;
    obj.add_data(&resource_directory_id_entry(103372false))?;

    // Add resource data entry with relocated address.
    let address = obj.add_data(&resource_data_entry(88, manifest.len() as u32))?;

    // Add the manifest data.
    obj.add_data(manifest)?;
    obj.align_to(8)?;

    // Write manifest data relocation at the end of the section.
    obj.add_relocation(address)?;

    // Finish writing file and return the populated object data.
    Ok(obj.finish()?.into_inner())
}

Messung V0.5 in Prozent
C=92 H=92 G=91

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.