blob: 2a531e17aa8b7b8eef52baa39a89ead5a2a2df81 [file] [log] [blame]
Patrick Williamsdb4c27e2022-08-05 08:10:29 -05001From 8e9892f08b1248dc03862da86915c2745e0ff7ec Mon Sep 17 00:00:00 2001
2From: "Andrew J. Hesford" <ajh@sideband.org>
3Date: Fri, 15 Jul 2022 10:33:02 -0400
4Subject: [PATCH] build_rust: remove linker handling that broke cross
5 compilation
6
7Upstream-Status: Submitted [https://github.com/PyO3/setuptools-rust/pull/269]
8Signed-off-by: Alexander Kanavin <alex@linutronix.de>
9---
10 setuptools_rust/build.py | 151 ++-------------------------------------
11 1 file changed, 7 insertions(+), 144 deletions(-)
12
13diff --git a/setuptools_rust/build.py b/setuptools_rust/build.py
14index 4fe594b..e81ed8f 100644
15--- a/setuptools_rust/build.py
16+++ b/setuptools_rust/build.py
17@@ -113,23 +113,10 @@ def build_extension(
18 self, ext: RustExtension, forced_target_triple: Optional[str] = None
19 ) -> List["_BuiltModule"]:
20
21- target_info = self._detect_rust_target(forced_target_triple)
22- if target_info is not None:
23- target_triple = target_info.triple
24- cross_lib = target_info.cross_lib
25- linker = target_info.linker
26- # We're ignoring target_info.linker_args for now because we're not
27- # sure if they will always do the right thing. Might help with some
28- # of the OS-specific logic if it does.
29-
30- else:
31- target_triple = None
32- cross_lib = None
33- linker = None
34-
35+ target_triple = self._detect_rust_target(forced_target_triple)
36 rustc_cfgs = get_rustc_cfgs(target_triple)
37
38- env = _prepare_build_environment(cross_lib)
39+ env = _prepare_build_environment()
40
41 if not os.path.exists(ext.path):
42 raise DistutilsFileError(
43@@ -150,9 +137,6 @@ def build_extension(
44
45 rustflags = []
46
47- if linker is not None:
48- rustflags.extend(["-C", "linker=" + linker])
49-
50 if ext._uses_exec_binding():
51 command = [self.cargo, "build", "--manifest-path", ext.path, *cargo_args]
52
53@@ -407,45 +391,12 @@ def _py_limited_api(self) -> _PyLimitedApi:
54
55 def _detect_rust_target(
56 self, forced_target_triple: Optional[str] = None
57- ) -> Optional["_TargetInfo"]:
58+ ) -> Optional[str]:
59 assert self.plat_name is not None
60- cross_compile_info = _detect_unix_cross_compile_info()
61- if cross_compile_info is not None:
62- cross_target_info = cross_compile_info.to_target_info()
63- if forced_target_triple is not None:
64- if (
65- cross_target_info is not None
66- and not cross_target_info.is_compatible_with(forced_target_triple)
67- ):
68- self.warn(
69- f"Forced Rust target `{forced_target_triple}` is not "
70- f"compatible with deduced Rust target "
71- f"`{cross_target_info.triple}` - the built package "
72- f" may not import successfully once installed."
73- )
74-
75- # Forcing the target in a cross-compile environment; use
76- # the cross-compile information in combination with the
77- # forced target
78- return _TargetInfo(
79- forced_target_triple,
80- cross_compile_info.cross_lib,
81- cross_compile_info.linker,
82- cross_compile_info.linker_args,
83- )
84- elif cross_target_info is not None:
85- return cross_target_info
86- else:
87- raise DistutilsPlatformError(
88- "Don't know the correct rust target for system type "
89- f"{cross_compile_info.host_type}. Please set the "
90- "CARGO_BUILD_TARGET environment variable."
91- )
92-
93- elif forced_target_triple is not None:
94+ if forced_target_triple is not None:
95 # Automatic target detection can be overridden via the CARGO_BUILD_TARGET
96 # environment variable or --target command line option
97- return _TargetInfo.for_triple(forced_target_triple)
98+ return forced_target_triple
99
100 # Determine local rust target which needs to be "forced" if necessary
101 local_rust_target = _adjusted_local_rust_target(self.plat_name)
102@@ -457,7 +408,7 @@ def _detect_rust_target(
103 # check for None first to avoid calling to rustc if not needed
104 and local_rust_target != get_rust_host()
105 ):
106- return _TargetInfo.for_triple(local_rust_target)
107+ return local_rust_target
108
109 return None
110
111@@ -547,91 +498,6 @@ class _BuiltModule(NamedTuple):
112 path: str
113
114
115-class _TargetInfo(NamedTuple):
116- triple: str
117- cross_lib: Optional[str]
118- linker: Optional[str]
119- linker_args: Optional[str]
120-
121- @staticmethod
122- def for_triple(triple: str) -> "_TargetInfo":
123- return _TargetInfo(triple, None, None, None)
124-
125- def is_compatible_with(self, target: str) -> bool:
126- if self.triple == target:
127- return True
128-
129- # the vendor field can be ignored, so x86_64-pc-linux-gnu is compatible
130- # with x86_64-unknown-linux-gnu
131- if _replace_vendor_with_unknown(self.triple) == target:
132- return True
133-
134- return False
135-
136-
137-class _CrossCompileInfo(NamedTuple):
138- host_type: str
139- cross_lib: Optional[str]
140- linker: Optional[str]
141- linker_args: Optional[str]
142-
143- def to_target_info(self) -> Optional[_TargetInfo]:
144- """Maps this cross compile info to target info.
145-
146- Returns None if the corresponding target information could not be
147- deduced.
148- """
149- # hopefully an exact match
150- targets = get_rust_target_list()
151- if self.host_type in targets:
152- return _TargetInfo(
153- self.host_type, self.cross_lib, self.linker, self.linker_args
154- )
155-
156- # the vendor field can be ignored, so x86_64-pc-linux-gnu is compatible
157- # with x86_64-unknown-linux-gnu
158- without_vendor = _replace_vendor_with_unknown(self.host_type)
159- if without_vendor is not None and without_vendor in targets:
160- return _TargetInfo(
161- without_vendor, self.cross_lib, self.linker, self.linker_args
162- )
163-
164- return None
165-
166-
167-def _detect_unix_cross_compile_info() -> Optional["_CrossCompileInfo"]:
168- # See https://github.com/PyO3/setuptools-rust/issues/138
169- # This is to support cross compiling on *NIX, where plat_name isn't
170- # necessarily the same as the system we are running on. *NIX systems
171- # have more detailed information available in sysconfig. We need that
172- # because plat_name doesn't give us information on e.g., glibc vs musl.
173- host_type = sysconfig.get_config_var("HOST_GNU_TYPE")
174- build_type = sysconfig.get_config_var("BUILD_GNU_TYPE")
175-
176- if not host_type or host_type == build_type:
177- # not *NIX, or not cross compiling
178- return None
179-
180- if "apple-darwin" in host_type and (build_type and "apple-darwin" in build_type):
181- # On macos and the build and host differ. This is probably an arm
182- # Python which was built on x86_64. Don't try to handle this for now.
183- # (See https://github.com/PyO3/setuptools-rust/issues/192)
184- return None
185-
186- stdlib = sysconfig.get_path("stdlib")
187- assert stdlib is not None
188- cross_lib = os.path.dirname(stdlib)
189-
190- bldshared = sysconfig.get_config_var("BLDSHARED")
191- if not bldshared:
192- linker = None
193- linker_args = None
194- else:
195- [linker, _, linker_args] = bldshared.partition(" ")
196-
197- return _CrossCompileInfo(host_type, cross_lib, linker, linker_args)
198-
199-
200 def _replace_vendor_with_unknown(target: str) -> Optional[str]:
201 """Replaces vendor in the target triple with unknown.
202
203@@ -644,7 +510,7 @@ def _replace_vendor_with_unknown(target: str) -> Optional[str]:
204 return "-".join(components)
205
206
207-def _prepare_build_environment(cross_lib: Optional[str]) -> Dict[str, str]:
208+def _prepare_build_environment() -> Dict[str, str]:
209 """Prepares environment variables to use when executing cargo build."""
210
211 # Make sure that if pythonXX-sys is used, it builds against the current
212@@ -665,9 +531,6 @@ def _prepare_build_environment(cross_lib: Optional[str]) -> Dict[str, str]:
213 }
214 )
215
216- if cross_lib:
217- env.setdefault("PYO3_CROSS_LIB_DIR", cross_lib)
218-
219 env.pop("CARGO", None)
220 return env
221