rustc_target: Some more tests and fixes for linker arguments · rust-lang/rust@456f65e (original) (raw)

1

1

`use super::super::*;

`

``

2

`+

use std::assert_matches::assert_matches;

`

2

3

``

3

4

`// Test target self-consistency and JSON encoding/decoding roundtrip.

`

4

5

`pub(super) fn test_target(target: Target) {

`

`@@ -14,35 +15,105 @@ impl Target {

`

14

15

`assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");

`

15

16

`assert!(self.is_like_windows || !self.is_like_msvc);

`

16

17

``

17

``

`-

// Check that LLD with the given flavor is treated identically to the linker it emulates.

`

18

``

`-

// If your target really needs to deviate from the rules below, except it and document the

`

19

``

`-

// reasons.

`

20

``

`-

assert_eq!(

`

21

``

`-

self.linker_flavor == LinkerFlavor::Msvc

`

22

``

`-

|| self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link),

`

23

``

`-

self.lld_flavor == LldFlavor::Link,

`

24

``

`-

);

`

25

``

`-

assert_eq!(self.is_like_msvc, self.lld_flavor == LldFlavor::Link);

`

26

``

`-

for args in &[

`

``

18

`+

// Check that default linker flavor and lld flavor are compatible

`

``

19

`+

// with some other key properties.

`

``

20

`+

assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64));

`

``

21

`+

assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link));

`

``

22

`+

assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm));

`

``

23

`+

assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender));

`

``

24

`+

assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em));

`

``

25

`+

assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker));

`

``

26

`+

assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker));

`

``

27

+

``

28

`+

for args in [

`

27

29

`&self.pre_link_args,

`

28

30

`&self.late_link_args,

`

29

31

`&self.late_link_args_dynamic,

`

30

32

`&self.late_link_args_static,

`

31

33

`&self.post_link_args,

`

32

34

`] {

`

``

35

`+

for (&flavor, flavor_args) in args {

`

``

36

`+

assert!(!flavor_args.is_empty());

`

``

37

`+

// Check that flavors mentioned in link args are compatible with the default flavor.

`

``

38

`+

match (self.linker_flavor, self.lld_flavor) {

`

``

39

`+

(

`

``

40

`+

LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc,

`

``

41

`+

LldFlavor::Ld,

`

``

42

`+

) => {

`

``

43

`+

assert_matches!(

`

``

44

`+

flavor,

`

``

45

`+

LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc

`

``

46

`+

)

`

``

47

`+

}

`

``

48

`+

(LinkerFlavor::Gcc, LldFlavor::Ld64) => {

`

``

49

`+

assert_matches!(flavor, LinkerFlavor::Gcc)

`

``

50

`+

}

`

``

51

`+

(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {

`

``

52

`+

assert_matches!(

`

``

53

`+

flavor,

`

``

54

`+

LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link)

`

``

55

`+

)

`

``

56

`+

}

`

``

57

`+

(LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => {

`

``

58

`+

assert_matches!(

`

``

59

`+

flavor,

`

``

60

`+

LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc

`

``

61

`+

)

`

``

62

`+

}

`

``

63

`+

(LinkerFlavor::L4Bender, LldFlavor::Ld) => {

`

``

64

`+

assert_matches!(flavor, LinkerFlavor::L4Bender)

`

``

65

`+

}

`

``

66

`+

(LinkerFlavor::Em, LldFlavor::Wasm) => {

`

``

67

`+

assert_matches!(flavor, LinkerFlavor::Em)

`

``

68

`+

}

`

``

69

`+

(LinkerFlavor::BpfLinker, LldFlavor::Ld) => {

`

``

70

`+

assert_matches!(flavor, LinkerFlavor::BpfLinker)

`

``

71

`+

}

`

``

72

`+

(LinkerFlavor::PtxLinker, LldFlavor::Ld) => {

`

``

73

`+

assert_matches!(flavor, LinkerFlavor::PtxLinker)

`

``

74

`+

}

`

``

75

`+

flavors => unreachable!("unexpected flavor combination: {:?}", flavors),

`

``

76

`+

}

`

``

77

+

``

78

`+

// Check that link args for cc and non-cc versions of flavors are consistent.

`

``

79

`+

let check_noncc = |noncc_flavor| {

`

``

80

`+

if let Some(noncc_args) = args.get(&noncc_flavor) {

`

``

81

`+

for arg in flavor_args {

`

``

82

`+

if let Some(suffix) = arg.strip_prefix("-Wl,") {

`

``

83

`+

assert!(noncc_args.iter().any(|a| a == suffix));

`

``

84

`+

}

`

``

85

`+

}

`

``

86

`+

}

`

``

87

`+

};

`

``

88

`+

match self.linker_flavor {

`

``

89

`+

LinkerFlavor::Gcc => match self.lld_flavor {

`

``

90

`+

LldFlavor::Ld => {

`

``

91

`+

check_noncc(LinkerFlavor::Ld);

`

``

92

`+

check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));

`

``

93

`+

}

`

``

94

`+

LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),

`

``

95

`+

LldFlavor::Ld64 | LldFlavor::Link => {}

`

``

96

`+

},

`

``

97

`+

_ => {}

`

``

98

`+

}

`

``

99

`+

}

`

``

100

+

``

101

`+

// Check that link args for lld and non-lld versions of flavors are consistent.

`

``

102

`+

assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld)));

`

33

103

`assert_eq!(

`

34

104

` args.get(&LinkerFlavor::Msvc),

`

35

105

` args.get(&LinkerFlavor::Lld(LldFlavor::Link)),

`

36

106

`);

`

37

``

`-

if args.contains_key(&LinkerFlavor::Msvc) {

`

38

``

`-

assert_eq!(self.lld_flavor, LldFlavor::Link);

`

39

``

`-

}

`

40

107

`}

`

``

108

+

41

109

`assert!(

`

42

110

`(self.pre_link_objects_fallback.is_empty()

`

43

111

` && self.post_link_objects_fallback.is_empty())

`

44

112

` || self.crt_objects_fallback.is_some()

`

45

113

`);

`

``

114

+

``

115

`+

// If your target really needs to deviate from the rules below,

`

``

116

`+

// except it and document the reasons.

`

46

117

`// Keep the default "unknown" vendor instead.

`

47

118

`assert_ne!(self.vendor, "");

`

48

119

`if !self.can_use_os_unknown() {

`