Skip to content

Commit 4694a3b

Browse files
Linker for Windows (#538)
* Add a linker option to trigger a custom linker (for example clang or cc as linker/driver) * Use tempfile while compiling * Change the path of the called command, still fails on windows * windows linker finds libs in build directory Co-authored-by: Ghaith Hachem <ghaith.hachem@bachmann.info>
1 parent da291f1 commit 4694a3b

12 files changed

+375
-97
lines changed

Cargo.lock

+54
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ serde_json = "1"
3232
toml = "0.5"
3333
lazy_static = "1.4.0"
3434
shell-words = "1.1.0"
35+
which = "4.2.5"
36+
tempfile = "3"
3537

3638
[dev-dependencies]
3739
num = "0.4"

src/build.rs

+8-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use crate::diagnostics::Diagnostic;
2-
use crate::diagnostics::ErrNo;
3-
use crate::make_absolute;
42
use crate::resolve_environment_variables;
53
use crate::FormatOption;
64
use serde::{Deserialize, Serialize};
@@ -40,17 +38,21 @@ impl Project {
4038
files: self
4139
.files
4240
.into_iter()
43-
.map(|it| make_absolute(&it, root))
41+
.map(|it| if it.is_absolute() { it } else { root.join(it) })
4442
.collect(),
4543
libraries: self
4644
.libraries
4745
.into_iter()
4846
.map(|it| Libraries {
49-
path: make_absolute(&it.path, root),
47+
path: if it.path.is_absolute() {
48+
it.path
49+
} else {
50+
root.join(it.path)
51+
},
5052
include_path: it
5153
.include_path
5254
.into_iter()
53-
.map(|it| make_absolute(&it, root))
55+
.map(|it| if it.is_absolute() { it } else { root.join(it) })
5456
.collect(),
5557
..it
5658
})
@@ -67,34 +69,16 @@ impl Project {
6769
}
6870
}
6971

70-
pub fn get_project_from_file(build_config: &Path, root: &Path) -> Result<Project, Diagnostic> {
72+
pub fn get_project_from_file(build_config: &Path) -> Result<Project, Diagnostic> {
7173
//read from file
7274
let content = fs::read_to_string(build_config)?;
7375

7476
//convert file to Object
7577
let project = Project::try_parse(&content)?;
7678

77-
check_libs_exist(&project.libraries, root)?;
7879
Ok(project)
7980
}
8081

81-
fn check_libs_exist(libraries: &[Libraries], root: &Path) -> Result<(), Diagnostic> {
82-
for library in libraries {
83-
let path = root.join(&library.path);
84-
let path = path.join(&format!("lib{}.so", library.name));
85-
if !path.is_file() {
86-
return Err(Diagnostic::GeneralError {
87-
message: format!(
88-
"The library could not be found at : {}",
89-
path.to_string_lossy()
90-
),
91-
err_no: ErrNo::general__io_err,
92-
});
93-
}
94-
}
95-
Ok(())
96-
}
97-
9882
#[cfg(test)]
9983
mod tests {
10084
use std::path::PathBuf;

src/cli.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ pub struct CompileParameters {
161161
)]
162162
pub error_format: ErrorFormat,
163163

164+
#[clap(
165+
name = "linker",
166+
long,
167+
help = "Define a custom (cc compatible) linker command",
168+
global = true
169+
)]
170+
pub linker: Option<String>,
171+
164172
#[clap(subcommand)]
165173
pub commands: Option<SubCommands>,
166174
}
@@ -624,7 +632,9 @@ mod cli_tests {
624632
"--target",
625633
"targettest",
626634
"--target",
627-
"othertarget"
635+
"othertarget",
636+
"--linker",
637+
"cc"
628638
))
629639
.unwrap();
630640
if let Some(commands) = parameters.commands {
@@ -633,6 +643,7 @@ mod cli_tests {
633643
build_config,
634644
build_location,
635645
lib_location,
646+
..
636647
} => {
637648
assert_eq!(build_config, Some("src/ProjectPlc.json".to_string()));
638649
assert_eq!(build_location, Some("bin/build".to_string()));
@@ -647,6 +658,7 @@ mod cli_tests {
647658
parameters.target,
648659
vec!["targettest".to_string(), "othertarget".to_string()]
649660
);
661+
assert_eq!(parameters.linker, Some("cc".to_string()));
650662
}
651663
}
652664

0 commit comments

Comments
 (0)