// NB: Verbose mode: cargo test -vv use std::env; use std::io::Write; use std::path::Path; use std::process::{Command, Stdio}; fn cmd (dir: &Path, cmd: &str) { println! ("", cmd, dir.to_string_lossy()); let status = Command::new ("sh") .arg ("-c") .arg (cmd) .current_dir (dir) .stdout (Stdio::inherit()) .stderr (Stdio::inherit()) .status() .expect ("!sh"); if !status.success() {panic! ("cmd] exit code {:?}", status.code())} println! ("");} fn main() { let out_dir = env::var ("OUT_DIR") .expect ("!OUT_DIR"); let out_dir = Path::new (&out_dir); let sources = out_dir.join ("vtd-xml-c"); if !sources.exists() {cmd (out_dir, "git clone --depth=1 https://github.com/dlo9/vtd-xml-c.git")} assert! (sources.exists()); let target = env::var ("TARGET") .expect ("!TARGET"); println! ("target: {}", target); cmd (&sources, "perl -i.tmp -pe 's/CFLAGS=\\s/CFLAGS=-fPIC /' makefile"); cmd (&sources, "perl -i.tmp -pe 's/\\tctags/\t#ctags/' makefile"); if target.ends_with ("-windows-gnu") { cmd (&sources, "perl -i.tmp -pe 's/-lm//' makefile");} cmd (&sources, "make -j 4"); { let mut shims = std::fs::File::create (sources.join ("shims.c")) .expect ("!create"); shims.write (b" #include \"customTypes.h\" _thread struct exception_context the_exception_context[1]; int vtd_try_catch_shim (void (*rust_cb) (void*), void* dugout, exception* ex_out) { exception e; int exception_raised = 0; Try {rust_cb (dugout);} Catch (e) {exception_raised = 1; if (ex_out) *ex_out = e;} return exception_raised;} #include \"vtdNav.h\" VTDNav* cloneNav_shim (VTDNav *vn) {return vn->__cloneNav(vn);} VTDNav* duplicateNav_shim (VTDNav *vn) {return vn->__duplicateNav (vn);} void recoverNode_shim (VTDNav *vn, int index) {vn->__recoverNode (vn, index);} void freeVTDNav_shim (VTDNav *vn) {vn->__freeVTDNav(vn);}; Boolean toElement_shim (VTDNav *vn, navDir direction) {return vn->__toElement (vn, direction);} Boolean toElement2_shim (VTDNav *vn, navDir direction, UCSChar *en) {return vn->__toElement2 (vn, direction, en);} int getCurrentIndex_shim (VTDNav *vn) {return getCurrentIndex (vn);} // We need the shims because the MSYS2 version of iconv uses the 'lib' prefix, e.g. 'libiconv_open' instead of 'iconv_open'. #include iconv_t iconv_open_shim (const char *tocode, const char *fromcode) {return iconv_open (tocode, fromcode);} size_t iconv_shim (iconv_t cd, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft) { return iconv (cd, inbuf, inbytesleft, outbuf, outbytesleft);} int iconv_close_shim (iconv_t cd) {return iconv_close (cd);} #include int is_errno_einval() {return errno == EINVAL;} int is_errno_e2big() {return errno == E2BIG;} ") .expect ("!write"); } cmd (&sources, "gcc -ggdb -fPIC \ -Og -fomit-frame-pointer -fforce-addr -march=core2 \ -c shims.c -o shims.o"); // NB: We should always repack the library in order to include any shim updates. let lib = sources.join ("libvtdxml.a"); let _ = std::fs::remove_file (&lib); cmd (&sources, "ar rcs libvtdxml.a shims.o \ arrayList.o fastIntBuffer.o fastLongBuffer.o contextBuffer.o vtdNav.o vtdGen.o autoPilot.o XMLChar.o helper.o lex.yy.o l8.tab.o \ literalExpr.o numberExpr.o pathExpr.o filterExpr.o binaryExpr.o unaryExpr.o funcExpr.o locationPathExpr.o intHash.o unionExpr.o \ decoder.o XMLModifier.o nodeRecorder.o indexHandler.o bookMark.o elementFragmentNs.o transcoder.o textIter.o variableExpr.o cachedExpr.o"); println! ("cargo:rustc-link-lib=static=vtdxml"); if target.ends_with ("-windows-gnu") { println! ("cargo:rustc-link-lib=iconv");} println! ("cargo:rustc-link-search=native={}", sources.to_string_lossy());}