To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

aot.rs 5.53 KB
Newer Older
qinsoon's avatar
qinsoon committed
1
use testutil::*;
qinsoon's avatar
qinsoon committed
2
3
use ast::ir::MuName;
use runtime;
qinsoon's avatar
qinsoon committed
4
use vm::VM;
qinsoon's avatar
qinsoon committed
5
use compiler::backend;
qinsoon's avatar
qinsoon committed
6

qinsoon's avatar
qinsoon committed
7
8
use std::path::PathBuf;
use std::process::Command;
qinsoon's avatar
qinsoon committed
9
use std::process::Output;
qinsoon's avatar
qinsoon committed
10

11
12
fn link_executable_internal (files: Vec<PathBuf>, lib: &Vec<String>, libpath: &Vec<String>, out: PathBuf) -> PathBuf {
    let mut cc = Command::new(get_test_clang_path());
qinsoon's avatar
qinsoon committed
13
14

    for file in files {
qinsoon's avatar
qinsoon committed
15
        info!("link with {:?}", file.as_path());
16
17
18
19
20
21
22
23
24
        cc.arg(file.as_path());
    }

    // external libs
    for path in libpath.iter() {
        cc.arg(format!("-L{}", path));
    }
    for l in lib.iter() {
        cc.arg(format!("-l{}", l));
qinsoon's avatar
qinsoon committed
25
26
    }

qinsoon's avatar
qinsoon committed
27
    info!("output as {:?}", out.as_path());
qinsoon's avatar
qinsoon committed
28
    if cfg!(target_os = "linux") {
29
30
31
32
        cc.arg("-ldl");
        cc.arg("-lrt");
        cc.arg("-lm");
        cc.arg("-lpthread");
qinsoon's avatar
qinsoon committed
33
    }
34

qinsoon's avatar
qinsoon committed
35
    // so we can find symbols in itself
36
37
38
    cc.arg("-rdynamic");
    cc.arg("-o");
    cc.arg(out.as_os_str());
qinsoon's avatar
qinsoon committed
39

40
    assert!(exec(cc).status.success());
qinsoon's avatar
qinsoon committed
41
42
43
44

    out
}

45
fn link_dylib_internal (files: Vec<PathBuf>, lib: &Vec<String>, libpath: &Vec<String>, out: PathBuf) -> PathBuf {
qinsoon's avatar
qinsoon committed
46
47
48
    let mut object_files : Vec<PathBuf> = vec![];

    for file in files {
49
        let mut cc = Command::new(get_test_clang_path());
qinsoon's avatar
qinsoon committed
50

51
52
        cc.arg("-c");
        cc.arg("-fPIC");
qinsoon's avatar
qinsoon committed
53
54
55
56

        let mut out = file.clone();
        out.set_extension("o");

57
58
59
        cc.arg(file.as_os_str());
        cc.arg("-o");
        cc.arg(out.as_os_str());
qinsoon's avatar
qinsoon committed
60
61

        object_files.push(out);
62
63
64
65
66
        exec(cc);
    }

    let mut cc = Command::new(get_test_clang_path());

67
68
69
70
71
72
73
74
75
    // include mu static lib
    let libmu_path = if cfg!(debug_assertions) {
        "target/debug/libmu.a"
    } else {
        "target/release/libmu.a"
    };
    let libmu = get_path_under_mu(libmu_path);
    cc.arg(format!("{}", libmu.to_str().unwrap()));

76
77
78
79
80
81
    // external libs
    for path in libpath.iter() {
        cc.arg(format!("-L{}", path));
    }
    for l in lib.iter() {
        cc.arg(format!("-l{}", l));
qinsoon's avatar
qinsoon committed
82
83
    }

84
85
86
87
88
    cc.arg("-shared");
    cc.arg("-fPIC");
    cc.arg("-Wl");
    cc.arg("-undefined");
    cc.arg("dynamic_lookup");
qinsoon's avatar
qinsoon committed
89
    for obj in object_files {
90
        cc.arg(obj.as_os_str());
qinsoon's avatar
qinsoon committed
91
    }
92

93
94
    cc.arg("-o");
    cc.arg(out.as_os_str());
qinsoon's avatar
qinsoon committed
95

96
    exec(cc);
qinsoon's avatar
qinsoon committed
97
98
99
100

    out
}

qinsoon's avatar
qinsoon committed
101
102
fn get_path_for_mu_func (f: MuName, vm: &VM) -> PathBuf {
    let mut ret = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
qinsoon's avatar
qinsoon committed
103
104
105
106
107
108
    ret.push(f);
    ret.set_extension("s");

    ret
}

qinsoon's avatar
qinsoon committed
109
110
fn get_path_for_mu_context (vm: &VM) -> PathBuf {
    let mut ret = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
qinsoon's avatar
qinsoon committed
111
112
113
114
    ret.push(backend::AOT_EMIT_CONTEXT_FILE);
    ret
}

qinsoon's avatar
qinsoon committed
115
116
pub fn link_primordial (funcs: Vec<MuName>, out: &str, vm: &VM) -> PathBuf {
    let emit_dir = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
qinsoon's avatar
qinsoon committed
117
118
119
120
121
122
123
124

    let files : Vec<PathBuf> = {
        use std::fs;

        let mut ret = vec![];

        // all interested mu funcs
        for func in funcs {
qinsoon's avatar
qinsoon committed
125
            ret.push(get_path_for_mu_func(func, vm));
qinsoon's avatar
qinsoon committed
126
127
128
        }

        // mu context
qinsoon's avatar
qinsoon committed
129
        ret.push(get_path_for_mu_context(vm));
qinsoon's avatar
qinsoon committed
130
131

        // copy primoridal entry
132
133
134
135
136
137
138
139
140
        let source   = get_path_under_mu(runtime::PRIMORDIAL_ENTRY);
        let dest = {
            let mut ret = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
            ret.push("main.c");

            ret
        };

        trace!("copying from {:?} to {:?}", source, dest);
141
142
143
144
        match fs::copy(source.as_path(), dest.as_path()) {
            Ok(_)  => {},
            Err(e) => panic!("failed to copy: {}", e)
        }
145

qinsoon's avatar
qinsoon committed
146
147
148
149
        // include the primordial C main
        ret.push(dest);

        // include mu static lib
150
151
152
153
154
155
        let libmu_path = if cfg!(debug_assertions) {
            "target/debug/libmu.a"
        } else {
            "target/release/libmu.a"
        };
        let libmu = get_path_under_mu(libmu_path);
qinsoon's avatar
qinsoon committed
156
157
158
159
160
161
162
163
        ret.push(libmu);

        ret
    };

    let mut out_path = emit_dir.clone();
    out_path.push(out);

164
165
166
167
    link_executable_internal(files,
                             &vm.vm_options.flag_bootimage_external_lib,
                             &vm.vm_options.flag_bootimage_external_libpath,
                             out_path)
qinsoon's avatar
qinsoon committed
168
169
}

qinsoon's avatar
qinsoon committed
170
171
172
173
174
175
pub fn execute(executable: PathBuf) -> Output {
    let run = Command::new(executable.as_os_str());
    exec(run)
}

pub fn execute_nocheck(executable: PathBuf) -> Output {
qinsoon's avatar
qinsoon committed
176
    let run = Command::new(executable.as_os_str());
qinsoon's avatar
qinsoon committed
177
    exec_nocheck(run)
qinsoon's avatar
qinsoon committed
178
179
}

qinsoon's avatar
qinsoon committed
180
pub fn link_dylib (funcs: Vec<MuName>, out: &str, vm: &VM) -> PathBuf {
qinsoon's avatar
qinsoon committed
181
182
183
184
    let files = {
        let mut ret = vec![];

        for func in funcs {
qinsoon's avatar
qinsoon committed
185
            ret.push(get_path_for_mu_func(func, vm));
qinsoon's avatar
qinsoon committed
186
187
        }

qinsoon's avatar
qinsoon committed
188
        ret.push(get_path_for_mu_context(vm));
qinsoon's avatar
qinsoon committed
189
190
191
192

        ret
    };

qinsoon's avatar
qinsoon committed
193
    let mut out_path = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
qinsoon's avatar
qinsoon committed
194
195
    out_path.push(out);

196
197
198
199
    link_dylib_internal(files,
                        &vm.vm_options.flag_bootimage_external_lib,
                        &vm.vm_options.flag_bootimage_external_libpath,
                        out_path)
200
201
}

qinsoon's avatar
qinsoon committed
202
pub fn link_dylib_with_extra_srcs(funcs: Vec<MuName>, srcs: Vec<String>, out: &str, vm: &VM) -> PathBuf{
203
204
205
206
    let files = {
        let mut ret = vec![];

        for func in funcs {
qinsoon's avatar
qinsoon committed
207
            ret.push(get_path_for_mu_func(func, vm));
208
209
210
        }

        for src in srcs {
John Zhang's avatar
fix    
John Zhang committed
211
            ret.push(PathBuf::from(src));
212
213
        }

qinsoon's avatar
qinsoon committed
214
        ret.push(get_path_for_mu_context(vm));
215
216
217
218

        ret
    };

qinsoon's avatar
qinsoon committed
219
    let mut out_path = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
220
221
    out_path.push(out);

222
223
224
225
    link_dylib_internal(files,
                        &vm.vm_options.flag_bootimage_external_lib,
                        &vm.vm_options.flag_bootimage_external_libpath,
                        out_path)
226
}