update build yaml

This commit is contained in:
Skyler Lehmkuhl 2026-02-24 14:44:17 -05:00
commit 0b4aee51d7
6 changed files with 123 additions and 40 deletions

View File

@ -160,35 +160,17 @@ jobs:
grep -A4 'fn get_ffmpeg_target_os' "$BUILDRS" grep -A4 'fn get_ffmpeg_target_os' "$BUILDRS"
echo "MACOSX_DEPLOYMENT_TARGET=11.0" >> "$GITHUB_ENV" echo "MACOSX_DEPLOYMENT_TARGET=11.0" >> "$GITHUB_ENV"
- name: Clean stale nam-ffi build artifacts
shell: bash
run: |
rm -rf lightningbeam-ui/target/release/build/nam-ffi-*
rm -rf lightningbeam-ui/target/debug/build/nam-ffi-*
- name: Build release binary - name: Build release binary
shell: bash shell: bash
env: env:
FFMPEG_STATIC: "1" FFMPEG_STATIC: "1"
run: | run: |
cd lightningbeam-ui cd lightningbeam-ui
TARGET_FLAG=""
if [ -n "${{ matrix.target }}" ]; then if [ -n "${{ matrix.target }}" ]; then
cargo build -vv --release --bin lightningbeam-editor --target ${{ matrix.target }} 2>&1 | tee /tmp/build.log || { TARGET_FLAG="--target ${{ matrix.target }}"
echo "=== nam-ffi build output ==="
grep -A50 'running.*nam-ffi\|Compiling nam-ffi\|NeuralAudio' /tmp/build.log | head -80
echo "=== nam-ffi OUT_DIR contents ==="
find target -path '*/nam-ffi-*/out/build' -exec ls -R {} \; 2>/dev/null || echo "not found"
exit 1
}
else
cargo build -vv --release --bin lightningbeam-editor 2>&1 | tee /tmp/build.log || {
echo "=== nam-ffi build output ==="
grep -A50 'running.*nam-ffi\|Compiling nam-ffi\|NeuralAudio' /tmp/build.log | head -80
echo "=== nam-ffi OUT_DIR contents ==="
find target -path '*/nam-ffi-*/out/build' -exec ls -R {} \; 2>/dev/null || echo "not found"
exit 1
}
fi fi
cargo build --release --bin lightningbeam-editor $TARGET_FLAG
- name: Copy cross-compiled binary to release dir - name: Copy cross-compiled binary to release dir
if: matrix.target != '' if: matrix.target != ''

View File

@ -1817,6 +1817,8 @@ dependencies = [
[[package]] [[package]]
name = "ecolor" name = "ecolor"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71ddb8ac7643d1dba1bb02110e804406dd459a838efcb14011ced10556711a8e"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"emath", "emath",
@ -1826,6 +1828,8 @@ dependencies = [
[[package]] [[package]]
name = "eframe" name = "eframe"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "457481173e6db5ca9fa2be93a58df8f4c7be639587aeb4853b526c6cf87db4e6"
dependencies = [ dependencies = [
"ahash 0.8.12", "ahash 0.8.12",
"bytemuck", "bytemuck",
@ -1861,6 +1865,8 @@ dependencies = [
[[package]] [[package]]
name = "egui" name = "egui"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9b567d356674e9a5121ed3fedfb0a7c31e059fe71f6972b691bcd0bfc284e3"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"ahash 0.8.12", "ahash 0.8.12",
@ -1879,6 +1885,8 @@ dependencies = [
[[package]] [[package]]
name = "egui-wgpu" name = "egui-wgpu"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e4d209971c84b2352a06174abdba701af1e552ce56b144d96f2bd50a3c91236"
dependencies = [ dependencies = [
"ahash 0.8.12", "ahash 0.8.12",
"bytemuck", "bytemuck",
@ -1897,6 +1905,8 @@ dependencies = [
[[package]] [[package]]
name = "egui-winit" name = "egui-winit"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec6687e5bb551702f4ad10ac428bab12acf9d53047ebb1082d4a0ed8c6251a29"
dependencies = [ dependencies = [
"accesskit_winit", "accesskit_winit",
"arboard", "arboard",
@ -1926,6 +1936,8 @@ dependencies = [
[[package]] [[package]]
name = "egui_extras" name = "egui_extras"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d01d34e845f01c62e3fded726961092e70417d66570c499b9817ab24674ca4ed"
dependencies = [ dependencies = [
"ahash 0.8.12", "ahash 0.8.12",
"egui", "egui",
@ -1941,6 +1953,8 @@ dependencies = [
[[package]] [[package]]
name = "egui_glow" name = "egui_glow"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6420863ea1d90e750f75075231a260030ad8a9f30a7cef82cdc966492dc4c4eb"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"egui", "egui",
@ -1973,6 +1987,8 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]] [[package]]
name = "emath" name = "emath"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "491bdf728bf25ddd9ad60d4cf1c48588fa82c013a2440b91aa7fc43e34a07c32"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"serde", "serde",
@ -2048,6 +2064,8 @@ dependencies = [
[[package]] [[package]]
name = "epaint" name = "epaint"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "009d0dd3c2163823a0abdb899451ecbc78798dec545ee91b43aff1fa790bab62"
dependencies = [ dependencies = [
"ab_glyph", "ab_glyph",
"ahash 0.8.12", "ahash 0.8.12",
@ -2065,6 +2083,8 @@ dependencies = [
[[package]] [[package]]
name = "epaint_default_fonts" name = "epaint_default_fonts"
version = "0.33.3" version = "0.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c4fbe202b6578d3d56428fa185cdf114a05e49da05f477b3c7f0fbb221f1862"
[[package]] [[package]]
name = "equator" name = "equator"
@ -4030,7 +4050,7 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
dependencies = [ dependencies = [
"proc-macro-crate 3.4.0", "proc-macro-crate 1.3.1",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.110", "syn 2.0.110",
@ -7124,7 +7144,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.48.0",
] ]
[[package]] [[package]]
@ -8122,3 +8142,35 @@ dependencies = [
"syn 2.0.110", "syn 2.0.110",
"winnow 0.7.13", "winnow 0.7.13",
] ]
[[patch.unused]]
name = "ecolor"
version = "0.33.2"
[[patch.unused]]
name = "eframe"
version = "0.33.2"
[[patch.unused]]
name = "egui"
version = "0.33.2"
[[patch.unused]]
name = "egui-wgpu"
version = "0.33.2"
[[patch.unused]]
name = "egui-winit"
version = "0.33.2"
[[patch.unused]]
name = "egui_extras"
version = "0.33.2"
[[patch.unused]]
name = "emath"
version = "0.33.2"
[[patch.unused]]
name = "epaint"
version = "0.33.2"

View File

@ -1,6 +1,9 @@
@echo off @echo off
REM Build script for Windows REM Build script for Windows
REM Requires: FFmpeg 8.0.0 dev files in C:\ffmpeg, LLVM installed REM Requires: FFmpeg 8.0.0 dev files in C:\ffmpeg, LLVM installed, VS Build Tools
REM Set up MSVC environment
call "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
REM FFmpeg location (headers + libs + DLLs) REM FFmpeg location (headers + libs + DLLs)
if not defined FFMPEG_DIR set FFMPEG_DIR=C:\ffmpeg if not defined FFMPEG_DIR set FFMPEG_DIR=C:\ffmpeg

View File

@ -1,13 +1,26 @@
use std::env; use std::env;
use std::path::Path;
/// Canonicalize a path without the \\?\ prefix on Windows
fn clean_canonicalize(p: &Path) -> String {
let canon = p.canonicalize().unwrap();
let s = canon.to_str().unwrap();
s.strip_prefix(r"\\?\").unwrap_or(s).to_string()
}
fn main() { fn main() {
let mut cfg = cmake::Config::new("../vendor/NeuralAudio"); let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let wrapper_dir = Path::new(&manifest_dir).join("cmake");
let neural_audio_dir = Path::new(&manifest_dir).join("../vendor/NeuralAudio");
let mut cfg = cmake::Config::new(&wrapper_dir);
// Force single-config generator on Unix to avoid libraries landing in Release/ subdirs // Force single-config generator on Unix to avoid libraries landing in Release/ subdirs
if !cfg!(target_os = "windows") { if !cfg!(target_os = "windows") {
cfg.generator("Unix Makefiles"); cfg.generator("Unix Makefiles");
} }
let dst = cfg let dst = cfg
.define("CMAKE_BUILD_TYPE", "Release") .define("CMAKE_BUILD_TYPE", "Release")
.define("NEURALAUDIO_SOURCE_DIR", clean_canonicalize(&neural_audio_dir))
.define("BUILD_NAMCORE", "OFF") .define("BUILD_NAMCORE", "OFF")
.define("BUILD_STATIC_RTNEURAL", "OFF") .define("BUILD_STATIC_RTNEURAL", "OFF")
.define("BUILD_UTILS", "OFF") .define("BUILD_UTILS", "OFF")
@ -19,12 +32,13 @@ fn main() {
let build_dir = dst.join("build"); let build_dir = dst.join("build");
// Static libraries land in the build subdirectories // The wrapper CMakeLists adds NeuralAudio as a subdirectory, so libraries
// Search both direct and Release/ paths for multi-config generator compatibility // are nested under build/NeuralAudio/{NeuralAudioCAPI,NeuralAudio}/
println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudioCAPI").display()); // Also search Release/ paths for multi-config generator compatibility (Windows)
println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudioCAPI").join("Release").display()); println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudio").join("NeuralAudioCAPI").display());
println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudio").display()); println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudio").join("NeuralAudioCAPI").join("Release").display());
println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudio").join("Release").display()); println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudio").join("NeuralAudio").display());
println!("cargo:rustc-link-search=native={}", build_dir.join("NeuralAudio").join("NeuralAudio").join("Release").display());
println!("cargo:rustc-link-lib=static=NeuralAudioCAPI"); println!("cargo:rustc-link-lib=static=NeuralAudioCAPI");
println!("cargo:rustc-link-lib=static=NeuralAudio"); println!("cargo:rustc-link-lib=static=NeuralAudio");

View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.5)
project(NeuralAudioStatic)
# Override add_library to force STATIC even when SHARED is specified
macro(add_library name)
set(_args ${ARGN})
list(FIND _args "SHARED" _shared_idx)
if(NOT _shared_idx EQUAL -1)
list(REMOVE_AT _args ${_shared_idx})
_add_library(${name} STATIC ${_args})
else()
_add_library(${name} ${_args})
endif()
endmacro()
add_subdirectory(${NEURALAUDIO_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/NeuralAudio)

View File

@ -1,9 +1,14 @@
use std::ffi::CString;
use std::path::Path; use std::path::Path;
#[cfg(windows)]
type WChar = u16;
#[cfg(not(windows))]
type WChar = u32;
#[allow(dead_code)] #[allow(dead_code)]
mod ffi { mod ffi {
use std::os::raw::{c_char, c_float, c_int}; use super::WChar;
use std::os::raw::{c_float, c_int};
#[repr(C)] #[repr(C)]
pub struct NeuralModel { pub struct NeuralModel {
@ -11,7 +16,7 @@ mod ffi {
} }
unsafe extern "C" { unsafe extern "C" {
pub fn CreateModelFromFile(model_path: *const c_char) -> *mut NeuralModel; pub fn CreateModelFromFile(model_path: *const WChar) -> *mut NeuralModel;
pub fn DeleteModel(model: *mut NeuralModel); pub fn DeleteModel(model: *mut NeuralModel);
pub fn SetLSTMLoadMode(load_mode: c_int); pub fn SetLSTMLoadMode(load_mode: c_int);
@ -37,14 +42,12 @@ mod ffi {
#[derive(Debug)] #[derive(Debug)]
pub enum NamError { pub enum NamError {
NullPath,
ModelLoadFailed(String), ModelLoadFailed(String),
} }
impl std::fmt::Display for NamError { impl std::fmt::Display for NamError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
NamError::NullPath => write!(f, "Path contains null byte"),
NamError::ModelLoadFailed(path) => write!(f, "Failed to load NAM model: {}", path), NamError::ModelLoadFailed(path) => write!(f, "Failed to load NAM model: {}", path),
} }
} }
@ -56,12 +59,25 @@ pub struct NamModel {
impl NamModel { impl NamModel {
pub fn from_file(path: &Path) -> Result<Self, NamError> { pub fn from_file(path: &Path) -> Result<Self, NamError> {
let path_str = path.to_string_lossy(); let wide: Vec<WChar> = {
let c_path = CString::new(path_str.as_bytes()).map_err(|_| NamError::NullPath)?; #[cfg(windows)]
{
use std::os::windows::ffi::OsStrExt;
path.as_os_str().encode_wide().chain(std::iter::once(0)).collect()
}
#[cfg(not(windows))]
{
path.to_string_lossy()
.chars()
.map(|c| c as WChar)
.chain(std::iter::once(0))
.collect()
}
};
let ptr = unsafe { ffi::CreateModelFromFile(c_path.as_ptr()) }; let ptr = unsafe { ffi::CreateModelFromFile(wide.as_ptr()) };
if ptr.is_null() { if ptr.is_null() {
return Err(NamError::ModelLoadFailed(path_str.into_owned())); return Err(NamError::ModelLoadFailed(path.display().to_string()));
} }
Ok(NamModel { ptr }) Ok(NamModel { ptr })