sourcegear-bridge-build 0.5.0

Build script support for SourceGear Bridge, a binding generator for .NET
Documentation

use std::path::Path;
use std::process::Command;

const INITIAL_CSPROJ : &str =
r#"
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <TrimmerSingleWarn>false</TrimmerSingleWarn>
    <PublishAOT>True</PublishAOT>
  </PropertyGroup>

  <ItemGroup>
      <PackageReference Include="sourcegear.bridge.nativeaot.rust" Version="[__SGBRIDGE_VERSION__]" />
  </ItemGroup>

  <Import Project="$(sgbridge_dir_for_crate)\deps.proj" Condition="exists('$(sgbridge_dir_for_crate)\deps.proj')" />

</Project>
"#;

#[derive(Debug)]
pub enum MyError {
    IO(std::io::Error),
    Cmd(std::process::ExitStatus),
}

impl From<std::io::Error> for MyError {
    fn from(err: std::io::Error) -> MyError {
        MyError::IO(err)
    }
}

pub fn run() -> Result<(),MyError>
{
    let cur_dir = std::env::current_dir()?;
    let sgbridge_dir_for_crate = Path::new(&cur_dir).join("sgbridge");

    let out_dir = std::env::var_os("OUT_DIR").unwrap();
    let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
    let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();

    //println!("OUT_DIR: {:?}", out_dir);
    //println!("CARGO_CFG_TARGET_OS: {:?}", &os);
    //println!("CARGO_CFG_TARGET_ARCH: {:?}", &arch);

    let path_out_csproj = Path::new(&out_dir).join("dotnet.csproj");
    let csproj_content = INITIAL_CSPROJ.replace("__SGBRIDGE_VERSION__", env!("CARGO_PKG_VERSION"));
    std::fs::write(&path_out_csproj, csproj_content)?;

    let rid = 
        if (os == "windows") && (arch == "x86_64") 
        {
            "win-x64"
        } 
        else if (os == "linux") && (arch == "x86_64") 
        {
            "linux-x64"
        }
        else if (os == "macos") && (arch == "x86_64") 
        {
            "osx-x64"
        }
        else if (os == "macos") && (arch == "aarch64") 
        {
            "osx-arm64"
        }
        else
        {
            "TODO"
        };

    println!("cargo:rerun-if-changed=build.rs");

    let path_deps = Path::new(&sgbridge_dir_for_crate).join("deps.proj");
    let path_config = Path::new(&sgbridge_dir_for_crate).join("config.xml");

    println!("cargo:rerun-if-changed={}",path_deps.display());
    println!("cargo:rerun-if-changed={}",path_config.display());

    let dir_prop = format!("sgbridge_dir_for_crate={}", sgbridge_dir_for_crate.display());
    let status = Command::new("dotnet")
        .args(&["publish", "--property", &dir_prop, "--property", "NativeLib=Static", "-r", rid])
        .current_dir(&out_dir)
        .status()?;
    if status.success() {
        return Ok(());
    } else {
        return Err(MyError::Cmd(status));
    }

}