Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 178 additions & 7 deletions src/compiler/msvc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,13 +844,24 @@ pub fn parse_arguments(
// Clang is currently unable to generate PDB files
if debug_info && !is_clang {
match pdb {
Some(p) => outputs.insert(
"pdb",
ArtifactDescriptor {
path: p,
optional: false,
},
),
Some(p) => {
// Append the default .pdb prefix if none was given, like how MSVC does.
let path = if p.extension().is_none() {
let mut path = p;
path.set_extension("pdb");
path
} else {
p
};

outputs.insert(
"pdb",
ArtifactDescriptor {
path,
optional: false,
},
)
}
None => {
// -Zi and -ZI without -Fd defaults to vcxxx.pdb (where xxx depends on the
// MSVC version), and that's used for all compilations with the same
Expand Down Expand Up @@ -1999,6 +2010,166 @@ mod test {
assert!(!msvc_show_includes);
}

#[test]
fn test_parse_arguments_pdb_no_extension() {
// Test that .pdb extension is appended when /Fd argument lacks an extension
let args = ovec!["-c", "foo.c", "-Zi", "-Fdfoo", "-Fofoo.obj"];
let ParsedArguments {
input,
language,
outputs,
preprocessor_args,
msvc_show_includes,
common_args,
..
} = match parse_arguments(args) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
assert_eq!(Some("foo.c"), input.to_str());
assert_eq!(Language::C, language);
assert_map_contains!(
outputs,
(
"obj",
ArtifactDescriptor {
path: PathBuf::from("foo.obj"),
optional: false
}
),
(
"pdb",
ArtifactDescriptor {
path: PathBuf::from("foo.pdb"),
optional: false
}
)
);
assert!(preprocessor_args.is_empty());
assert_eq!(common_args, ovec!["-Zi", "-Fdfoo"]);
assert!(!msvc_show_includes);
}

#[test]
fn test_parse_arguments_pdb_with_extension() {
// Test that .pdb extension is NOT duplicated when already present
let args = ovec!["-c", "foo.c", "-Zi", "-Fdfoo.pdb", "-Fofoo.obj"];
let ParsedArguments {
input,
language,
outputs,
preprocessor_args,
msvc_show_includes,
common_args,
..
} = match parse_arguments(args) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
assert_eq!(Some("foo.c"), input.to_str());
assert_eq!(Language::C, language);
assert_map_contains!(
outputs,
(
"obj",
ArtifactDescriptor {
path: PathBuf::from("foo.obj"),
optional: false
}
),
(
"pdb",
ArtifactDescriptor {
path: PathBuf::from("foo.pdb"),
optional: false
}
)
);
assert!(preprocessor_args.is_empty());
assert_eq!(common_args, ovec!["-Zi", "-Fdfoo.pdb"]);
assert!(!msvc_show_includes);
}

#[test]
fn test_parse_arguments_pdb_custom_extension() {
// Test that custom extensions are preserved
let args = ovec!["-c", "foo.c", "-Zi", "-Fdfoo.db", "-Fofoo.obj"];
let ParsedArguments {
input,
language,
outputs,
preprocessor_args,
msvc_show_includes,
common_args,
..
} = match parse_arguments(args) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
assert_eq!(Some("foo.c"), input.to_str());
assert_eq!(Language::C, language);
assert_map_contains!(
outputs,
(
"obj",
ArtifactDescriptor {
path: PathBuf::from("foo.obj"),
optional: false
}
),
(
"pdb",
ArtifactDescriptor {
path: PathBuf::from("foo.db"),
optional: false
}
)
);
assert!(preprocessor_args.is_empty());
assert_eq!(common_args, ovec!["-Zi", "-Fdfoo.db"]);
assert!(!msvc_show_includes);
}

#[test]
fn test_parse_arguments_pdb_path_with_extension() {
// Test that .pdb is appended only to the filename when path is given
let args = ovec!["-c", "foo.c", "-Zi", "-Fdoutput/foo", "-Fofoo.obj"];
let ParsedArguments {
input,
language,
outputs,
preprocessor_args,
msvc_show_includes,
common_args,
..
} = match parse_arguments(args) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
assert_eq!(Some("foo.c"), input.to_str());
assert_eq!(Language::C, language);
assert_map_contains!(
outputs,
(
"obj",
ArtifactDescriptor {
path: PathBuf::from("foo.obj"),
optional: false
}
),
(
"pdb",
ArtifactDescriptor {
path: PathBuf::from("output/foo.pdb"),
optional: false
}
)
);
assert!(preprocessor_args.is_empty());
assert_eq!(common_args, ovec!["-Zi", "-Fdoutput/foo"]);
assert!(!msvc_show_includes);
}

#[test]
fn test_parse_arguments_external_include() {
// Parsing -external:I relies on -experimental:external being parsed
Expand Down
Loading