diff --git a/Cargo.toml b/Cargo.toml index eeb10b9..f0f9c5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ failure = "*" [build-dependencies] cc = "^1.0" fs-utils = "*" - +glob = "^0.3" diff --git a/STAR b/STAR index 52e41b5..b78e0c1 160000 --- a/STAR +++ b/STAR @@ -1 +1 @@ -Subproject commit 52e41b5cee0dcc5248cd9a78af9985ed0b6bd07b +Subproject commit b78e0c15efeadd42f102dc1637803fed3d08625c diff --git a/build.rs b/build.rs index 91073a7..efd3e96 100644 --- a/build.rs +++ b/build.rs @@ -1,27 +1,24 @@ // Copyright (c) 2019 10x Genomics, Inc. All rights reserved. use fs_utils::copy::copy_directory; +use glob::glob; use std::env; use std::path::Path; use std::process::Command; fn libcxx() -> &'static str { match env::var("CXX") { - Ok(cxx) => { - match Path::new(&cxx).file_name().unwrap().to_str().unwrap() { - s if s.contains("clang++") => "c++", - s if s.contains("g++") => "stdc++", - s => panic!("unknown compiler: {}", s), - } - } - Err(_) => { - match env::var("TARGET") { - Ok(ref s) if s.contains("darwin") => "c++", - Ok(ref s) if s.contains("linux") => "stdc++", - Ok(ref s) => panic!("unknown target: {}", s), - Err(_) => panic!("TARGET is undefined"), - } - } + Ok(cxx) => match Path::new(&cxx).file_name().unwrap().to_str().unwrap() { + s if s.contains("clang++") => "c++", + s if s.contains("g++") => "stdc++", + s => panic!("unknown compiler: {}", s), + }, + Err(_) => match env::var("TARGET") { + Ok(ref s) if s.contains("darwin") => "c++", + Ok(ref s) if s.contains("linux") => "stdc++", + Ok(ref s) => panic!("unknown target: {}", s), + Err(_) => panic!("TARGET is undefined"), + }, } } @@ -48,7 +45,8 @@ fn main() { .arg("liborbit.a") .status() .unwrap() - .success() != true + .success() + != true { panic!("failed to build STAR"); } @@ -62,4 +60,14 @@ fn main() { println!("cargo:rustc-link-search=native={}", &out); println!("cargo:rustc-link-lib=static=orbit"); println!("cargo:rustc-link-lib=dylib={}", libcxx()); + + // so we don't rebuild every time + for star_source in glob("STAR/source/**/*").expect("error in glob(STAR/source)") { + let star_source = star_source + .as_ref() + .expect("error in glob(STAR/source)") + .to_str() + .expect("STAR source could not be made into valid unicode"); + println!("cargo:rerun-if-changed={}", star_source); + } } diff --git a/src/lib.rs b/src/lib.rs index 2367631..8bd3e75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,6 +63,11 @@ impl StarReference { let reference = unsafe { bindings::init_star_ref(length, c_args) }; + // recover stray CStrings to prevent leaked memory + nvec.into_iter().for_each(|ptr| unsafe { + CString::from_raw(ptr); + }); + let inner = InnerStarReference { reference, header, @@ -423,17 +428,15 @@ mod test { println!("{:?}", recs); } - #[test] fn test_multithreaded_alignment() { - let settings = StarSettings::new(ERCC_REF); let reference = StarReference::load(settings).unwrap(); let mut aligner1 = reference.get_aligner(); let mut aligner2 = reference.get_aligner(); let t1 = std::thread::spawn(move || { - for _ in 0 .. 100000 { + for _ in 0..100000 { let recs = aligner1.align_read(NAME, ERCC_READ_1, ERCC_QUAL_1); assert_eq!(recs.len(), 1); assert_eq!(recs[0].pos(), 50); @@ -442,7 +445,7 @@ mod test { }); let t2 = std::thread::spawn(move || { - for _ in 0 .. 100000 { + for _ in 0..100000 { let recs = aligner2.align_read(NAME, ERCC_READ_2, ERCC_QUAL_2); assert_eq!(recs.len(), 1); assert_eq!(recs[0].pos(), 500); @@ -454,7 +457,6 @@ mod test { assert!(t2.join().is_ok()); } - #[test] #[ignore] fn test_align_read() { @@ -520,7 +522,9 @@ mod test { let reference = StarReference::load(settings).unwrap(); let mut aligner = reference.get_aligner(); - let mut out = bam::Writer::from_path(&"test/test.bam", &reference.header(), bam::Format::BAM).unwrap(); + let mut out = + bam::Writer::from_path(&"test/test.bam", &reference.header(), bam::Format::BAM) + .unwrap(); let read = b"GTGCGGGGAGAAGTTTCAAGAAGGTTCTTATGGAAAAAAGGCTGTGAGCATAGAAAGCAGTCATAGGAGGTTGGGGAACTAGCTTGTCCCTCCCCACC"; let qual = b"GGGAGIGIIIGIIGGGGIIGGIGGAGGAGGAAG.GGIIIG