mod.rs 3.47 KB
Newer Older
1
// Copyright 2017 The Australian National University
2
//
3 4 5
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9 10 11 12 13 14 15 16 17 18 19 20
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This module contains utility functions for linking generated code and
//! running tests for Zebu.

extern crate libloading as ll;

use ast::ir::*;
21
use compiler::*;
22 23
use std::sync::Arc;

24
use std::os::unix::process::ExitStatusExt;
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
use std::path::PathBuf;
use std::process::Command;
use std::process::Output;

/// linking utilities for ahead-of-time compilation
pub mod aot;

/// gets a C compiler (for assembling and linking generated assembly code)
/// This function will check CC environment variable and return it.
/// Otherwise, it returns the default C compiler (clang).
fn get_c_compiler() -> String {
    use std::env;

    match env::var("CC") {
        Ok(val) => val,
40
        Err(_) => "clang".to_string(),
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
    }
}

/// concatenates the given path related to Zebu root path
/// This function will check MU_ZEBU environment variable and use it as Zebu root path.
/// Otherwise, it uses the current directory as Zebu root path.
fn get_path_under_zebu(str: &'static str) -> PathBuf {
    use std::env;

    match env::var("MU_ZEBU") {
        Ok(v) => {
            let mut ret = PathBuf::from(v);
            ret.push(str);
            ret
        }
56
        Err(_) => PathBuf::from(str),
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
    }
}

/// executes the executable of the given path, checks its exit status
/// panics if this executable does not finish normally
pub fn exec_path(executable: PathBuf) -> Output {
    let run = Command::new(executable.as_os_str());
    exec_cmd(run)
}

/// executes the executable of the given path, does not check exit status
pub fn exec_path_nocheck(executable: PathBuf) -> Output {
    let run = Command::new(executable.as_os_str());
    exec_cmd_nocheck(run)
}

/// executes the given command, checks its exit status,
/// panics if this command does not finish normally
fn exec_cmd(cmd: Command) -> Output {
    let output = exec_cmd_nocheck(cmd);
Javad Ebrahimian Amiri's avatar
Javad Ebrahimian Amiri committed
77
    if !output.status.success() {
78
        println!("{}", String::from_utf8(output.stderr.clone()).unwrap());
Javad Ebrahimian Amiri's avatar
Javad Ebrahimian Amiri committed
79
    }
80 81 82 83 84 85 86 87 88
    assert!(output.status.success());
    output
}

/// executes the given command, does not check exit status
fn exec_cmd_nocheck(mut cmd: Command) -> Output {
    info!("executing: {:?}", cmd);
    let output = match cmd.output() {
        Ok(res) => res,
89
        Err(e) => panic!("failed to execute: {}", e),
90 91 92 93 94 95 96 97
    };

    info!("---out---");
    info!("{}", String::from_utf8_lossy(&output.stdout));
    info!("---err---");
    info!("{}", String::from_utf8_lossy(&output.stderr));

    if output.status.signal().is_some() {
98 99 100 101
        info!(
            "terminated by a signal: {}",
            output.status.signal().unwrap()
        );
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    }

    output
}

/// returns a name for dynamic library
#[cfg(target_os = "macos")]
pub fn get_dylib_name(name: &'static str) -> String {
    format!("lib{}.dylib", name)
}

/// returns a name for dynamic library
#[cfg(target_os = "linux")]
pub fn get_dylib_name(name: &'static str) -> String {
    format!("lib{}.so", name)
117
}