opus-cmake-sys 1.0.6

Bindings to libopus
Documentation
extern crate pkg_config;

use std::{ env, fs };
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
use cc;
use std::fmt::Debug;
use std::collections::VecDeque;

#[derive(PartialEq, Debug)]
enum Target {
    Unknown(String),
    Emscripten,
    Wasm32
}

fn main() {
    let target = match env::var("TARGET").expect("missing build target") {
        x if x.ends_with("-emscripten") => {
            Target::Emscripten
        },
        x if x == "wasm32-unknown-unknown" => {
            Target::Wasm32
        },
        target => {
            Target::Unknown(target)
        }
    };

    let out_dir = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&out_dir);

    let mut library_name: &str;

    if target == Target::Emscripten {
        library_name = "libopus.a";
    } else {
        #[cfg(windows)]
        let library_name_ = "opus.lib";

        #[cfg(not(windows))]
        let library_name_ = "libopus.a";

        library_name = library_name_;
    }

    if fs::metadata(out_dir.join("lib").join(library_name)).is_err() {
        build(out_dir, &target);
    }

    println!("cargo:root={}", out_dir.display());
    println!("cargo:rustc-flags=-L native={} -l static=opus", out_dir.join("lib").to_str().unwrap());
}

fn get_opus_sources(file: &str, key: &str) -> std::io::Result<VecDeque<String>> {
    let key_line = String::from(key) + " ";
    let mut files = VecDeque::new();
    let mut key_found = false;

    let right_trim: &[_] = &[' ', '\\'];
    for mut line in fs::read_to_string(file)?.split("\n") {
        line = line.trim();

        if key_found {
            files.push_back(String::from(line.trim_end_matches(right_trim)));

            if ! line.ends_with("\\") {
                break
            }
        } else if line.starts_with(key_line.as_str()) {
            key_found = true;
        }
    }

    Ok(files)
}

fn build(_out_dir: &Path, target: &Target) {
    let mut config = cmake::Config::new("libopus");
    config.define("OPUS_STACK_PROTECTOR", "OFF");
    config.define("OPUS_INSTALL_PKG_CONFIG_MODULE", "OFF");
    config.define("OPUS_INSTALL_CMAKE_CONFIG_MODULE", "OFF");
    config.define("OPUS_BUILD_SHARED_LIBRARY", "OFF");
    config.define("OPUS_USE_ALLOCA", "OFF");

    if *target == Target::Emscripten {
        println!("Using EMSCRIPTEN!");
        let emsdk = env::var("EMSDK").expect("Missing emsdk environment variable. You may want to execute 'emsdk activate latest'");

        config.define("CMAKE_C_FLAGS", "-emit-llvm -L /mnt/c/Users/WolverinDEV/.emscripten_cache/wasm/ -l c -I/mnt/d/git/web/emsdk/upstream/emscripten/system/include/libc --target=wasm32-unknown-unknown"); //  --target=wasm32

        /* do no specify the /c emcc thingy */
        config.define("CMAKE_ASM_FLAGS", "");
        config.define("CMAKE_CXX_FLAGS", "");

        config.define("CMAKE_TOOLCHAIN_FILE", emsdk + "/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake");
        config.very_verbose(true);

        env::set_var("EMCC_DEBUG", "1");
        env::set_var("CMAKE", "/mnt/c/Users/WolverinDEV/IdeaProjects/WebOpusSys-Test/emmake");
    } else if *target == Target::Wasm32 {
        /* do no specify the /c emcc thingy */
        config.define("CMAKE_CXX_FLAGS", "");
        config.define("CMAKE_C_FLAGS", " --target=wasm32-unknown-unknown-wasm -emit-llvm -L /mnt/c/Users/WolverinDEV/.emscripten_cache/wasm/ -l c -I/mnt/d/git/web/emsdk/upstream/emscripten/system/include/libc -I/mnt/d/git/web/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten");

        /* skip the tests since -emit-llvm isn't supported when emitting a binary */
        config.define("CMAKE_C_COMPILER_WORKS", "1");

        //env::set_var("CMAKE", "/mnt/c/Users/WolverinDEV/IdeaProjects/WebOpusSys-Test/emmake");
        config.define("CMAKE_TOOLCHAIN_FILE", "");
        config.very_verbose(true);
    }

    config.build();
}