Rebuild after modifying environment variables that the C compiler reads
Cargo has the ability to specify that a build script depends on specific environment variables using cargo:rerun-if-env-changed=NAME, but no such mechanism exist for C compilers (that I know of).
This means that when you update an environment variable that your C compiler reads, you have to run cargo clean before the change takes effect. It would be nice if cc could prevent this by outputting a list of known variables that the C compiler it is about to invoke may read.
A list of the major ones I've found so far in Clang/LLVM (see also their limited docs about it):
SDKROOTon Apple targetsVCINSTALLDIR/VCToolsInstallDiron WindowsINCLUDE/CPATH/C_INCLUDE_PATH/C_PLUS_INCLUDE_PATH/OBJC_INCLUDE_PATH/OBJCPLUS_INCLUDE_PATHMACOSX_DEPLOYMENT_TARGET/IPHONEOS_DEPLOYMENT_TARGET/TVOS_DEPLOYMENT_TARGET/WATCHOS_DEPLOYMENT_TARGET/XROS_DEPLOYMENT_TARGETon Apple targets
Note that some of these may need to be handled by rustc/cargo itself.
Clang/LLVM read a bunch more, but they're mostly for debugging, or for stuff like setting up the terminal width, so I don't think those are applicable.
Additionally, C compilers usually rely on a few fundamental ones like PATH, PWD and PATHEXT on Windows that I would honestly expect cargo to handle, though I get why it may be difficult to do right.
MACOSX_DEPLOYMENT_TARGET/IPHONEOS_DEPLOYMENT_TARGET/TVOS_DEPLOYMENT_TARGET/WATCHOS_DEPLOYMENT_TARGET
Also XROS_DEPLOYMENT_TARGET (visionOS).
cc @madsmtm can we close this now #1103 is merged?
Hmm, while #1103 does improve this situation, it does not really address the underlying issue of the C compiler itself using these variables.
What I mean is that it only works because we're reading e.g. SDKROOT in cc right now, but if that was to change, this would break again.
What I really want is something like:
let _ = self.getenv("SDKROOT");
let _ = self.getenv("INCLUDE");
let _ = self.getenv("CPATH");
let _ = self.getenv("MACOSX_DEPLOYMENT_TARGET");
let _ = self.getenv("IPHONEOS_DEPLOYMENT_TARGET");
let _ = self.getenv("TVOS_DEPLOYMENT_TARGET");
// ...
To run sometime before we invoke the compiler (I guess it could perhaps be slightly more granular than this, if we knew that the compiler doesn't read some of these on certain targets / with certain build flags, but you get the idea).