ctp-rust 1.0.0

Safe Rust bindings for CTP (Comprehensive Transaction Platform) and its variations for Chinese financial markets
use std::env;
use std::path::PathBuf;

fn main() {
    // 获取当前构建目标
    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();

    // 公共 include 目录
    let include_path = PathBuf::from("libs/ctp/include");

    // 根据平台和架构选择 lib 目录和库文件
    let (lib_path, lib_suffix) = match (target_os.as_str(), target_arch.as_str()) {
        ("macos", "x86_64") => (PathBuf::from("libs/ctp/lib/mac64"), "dylib"),
        ("macos", "aarch64") => {
            // Apple Silicon Mac,如果没有专用库则尝试使用x86_64版本
            let arm_path = PathBuf::from("libs/ctp/lib/mac_arm64");
            if arm_path.exists() {
                (arm_path, "dylib")
            } else {
                println!("cargo:warning=未找到ARM64版本的CTP库,使用x86_64版本(可能需要Rosetta)");
                (PathBuf::from("libs/ctp/lib/mac64"), "dylib")
            }
        }
        ("linux", "x86_64") => (PathBuf::from("libs/ctp/lib/linux64"), "so"),
        ("linux", "aarch64") => {
            // ARM64 Linux,如果没有专用库则报错
            let arm_path = PathBuf::from("libs/ctp/lib/linux_arm64");
            if arm_path.exists() {
                (arm_path, "so")
            } else {
                panic!("不支持ARM64 Linux平台,CTP库仅支持x86_64架构");
            }
        }
        _ => panic!("不支持的平台: {} {}", target_os, target_arch),
    };

    // 检查库文件是否存在
    if !lib_path.exists() {
        panic!("CTP库目录不存在: {}", lib_path.display());
    }

    // 检查头文件是否存在
    if !include_path.exists() {
        panic!("CTP头文件目录不存在: {}", include_path.display());
    }

    // 验证必要的库文件是否存在
    let md_lib = lib_path.join(format!("thostmduserapi_se.{}", lib_suffix));
    let trader_lib = lib_path.join(format!("thosttraderapi_se.{}", lib_suffix));

    let has_md_lib = md_lib.exists();
    let has_trader_lib = trader_lib.exists();

    if !has_md_lib && !has_trader_lib {
        println!("cargo:warning=CTP库文件不存在,将跳过动态链接。如需完整功能,请将CTP库文件放置在正确位置。");
        println!("cargo:warning=行情API库: {}", md_lib.display());
        println!("cargo:warning=交易API库: {}", trader_lib.display());

        // 在测试模式下不进行链接
        println!("cargo:rustc-cfg=feature=\"test_mode\"");
        println!("cargo:warning=构建目标: {} {}", target_os, target_arch);
        println!("cargo:warning=测试模式:将跳过CTP库链接");
        return;
    }

    // 输出给 Cargo,让 Rust 知道去哪里找库
    println!("cargo:rustc-link-search=native={}", lib_path.display());

    // 设置条件编译标志
    if has_md_lib {
        println!("cargo:rustc-cfg=feature=\"md_api\"");
        println!("cargo:rustc-link-lib=dylib=thostmduserapi_se");
        println!("cargo:warning=找到行情API库: {}", md_lib.display());
    } else {
        println!("cargo:warning=行情API库不存在: {}", md_lib.display());
    }

    if has_trader_lib {
        println!("cargo:rustc-cfg=feature=\"trader_api\"");
        println!("cargo:rustc-link-lib=dylib=thosttraderapi_se");
        println!("cargo:warning=找到交易API库: {}", trader_lib.display());
    } else {
        println!("cargo:warning=交易API库不存在: {}", trader_lib.display());
    }

    // 如果没有任何库文件,启用测试模式
    if !has_md_lib && !has_trader_lib {
        println!("cargo:rustc-cfg=feature=\"test_mode\"");
    }

    // 在macOS上可能需要额外的系统库
    if target_os == "macos" {
        println!("cargo:rustc-link-lib=dylib=c++");
        println!("cargo:rustc-link-lib=framework=Security");
        println!("cargo:rustc-link-lib=framework=SystemConfiguration");
    }

    // 在Linux上可能需要额外的系统库
    if target_os == "linux" {
        println!("cargo:rustc-link-lib=dylib=stdc++");
        println!("cargo:rustc-link-lib=dylib=pthread");
        println!("cargo:rustc-link-lib=dylib=dl");
    }

    // 设置rpath以便运行时能找到动态库
    if target_os == "macos" {
        println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path");
        println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_path.display());
    } else if target_os == "linux" {
        println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN");
        println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_path.display());
    }

    // rerun 规则
    println!("cargo:rerun-if-changed={}", include_path.display());
    println!("cargo:rerun-if-changed={}", lib_path.display());
    println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_OS");
    println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH");

    // 输出构建信息
    println!("cargo:warning=构建目标: {} {}", target_os, target_arch);
    println!("cargo:warning=使用库目录: {}", lib_path.display());
}