@@ -3,15 +3,54 @@ use std::env;
33/// Print necessary link arguments for the library depending on the build
44/// configuration (static or shared)
55pub fn print_linker_args ( ) {
6- let shared_build = env:: var ( "RUST_SHARED_BUILD" ) . expect ( "RUST_SHARED_BUILD not set in Makefile?" ) ;
7- if shared_build == "1" {
8- let build_shared_args =
9- env:: var ( "BLDSHARED_ARGS" ) . expect ( "BLDSHARED_ARGS not set in Makefile?" ) ;
10- // TODO(emmatyping): Ideally, we would not need to split the args here and take shlex
11- // as a dependency.
12- for arg in shlex:: split ( & build_shared_args) . expect ( "Invalid BUILDSHARED_ARGS" ) {
13- println ! ( "cargo:rustc-link-arg={}" , arg) ;
6+ println ! ( "cargo:rerun-if-env-changed=RUST_SHARED_BUILD" ) ;
7+ println ! ( "cargo:rerun-if-env-changed=BLDSHARED_EXE" ) ;
8+ println ! ( "cargo:rerun-if-env-changed=BLDSHARED_ARGS" ) ;
9+ println ! ( "cargo:rerun-if-env-changed=CARGO_CFG_TARGET_OS" ) ;
10+
11+ let target_os = env:: var ( "CARGO_CFG_TARGET_OS" ) . unwrap_or_default ( ) ;
12+ // Apple framework builds for iOS have PY_ENABLE_SHARED=0 but still require
13+ // BLDSHARED-derived framework/link flags for extension modules.
14+ let shared_build = env:: var ( "RUST_SHARED_BUILD" ) . unwrap_or_default ( ) == "1"
15+ || target_os == "ios" ;
16+ if shared_build {
17+ if let Ok ( build_shared_exe) = env:: var ( "BLDSHARED_EXE" ) {
18+ // BLDSHARED_EXE starts with the linker executable, so we only pass
19+ // the trailing arguments through to rustc.
20+ print_link_args ( & build_shared_exe, true ) ;
21+ }
22+ if let Ok ( build_shared_args) = env:: var ( "BLDSHARED_ARGS" ) {
23+ print_link_args ( & build_shared_args, false ) ;
1424 }
25+ return ;
26+ }
27+
28+ // Static python builds on macOS still load extension symbols from the
29+ // interpreter at runtime.
30+ if target_os == "macos" {
31+ println ! ( "cargo:rustc-link-arg=-undefined" ) ;
32+ println ! ( "cargo:rustc-link-arg=dynamic_lookup" ) ;
33+ }
34+ }
35+
36+ fn print_link_args ( raw : & str , skip_first : bool ) {
37+ let mut args = shlex:: split ( raw) . expect ( "Invalid linker args" ) ;
38+ if skip_first && !args. is_empty ( ) {
39+ args. remove ( 0 ) ;
40+ }
41+
42+ let build_dir = env:: var ( "PYTHON_BUILD_DIR" ) . ok ( ) ;
43+ let mut i = 0 ;
44+ while i < args. len ( ) {
45+ if args[ i] == "-F"
46+ && i + 1 < args. len ( )
47+ && args[ i + 1 ] == "."
48+ && let Some ( dir) = & build_dir
49+ {
50+ args[ i + 1 ] = dir. clone ( ) ;
51+ }
52+
53+ println ! ( "cargo:rustc-link-arg={}" , args[ i] ) ;
54+ i += 1 ;
1555 }
16- // Static linker configuration is in cpython-rust-staticlib
1756}
0 commit comments