Open dehlen opened 2 months ago
:warning: | Newer Version of React Native is Available! |
---|---|
:information_source: | You are on a supported minor version, but it looks like there's a newer patch available - 0.74.5. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases. |
:warning: | Newer Version of React Native is Available! |
---|---|
:information_source: | You are on a supported minor version, but it looks like there's a newer patch available - undefined. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases. |
Checked with the latest version (0.75.2) and the issue persists.
Hi @dehlen thanks for opening the issue. This is the code that sets up ccache and the scripts
IIUC, you are in a situation where ccache is present but in a path that is not accessible by Xcode, correct?
Does it work if you build from command line using yarn ios
?
Yes that works since its run from the terminal where my path is set. Ccache is installed via homebrew and the installation directory is part of my terminal path. However macOS applications do not inherit the path and therefore ccache can not be found. I think what would mitigate this problem would be to add a user defined setting like CCHACHE_BINARY go the targets from the ruby script as part of the post_install hook where the path is found and printed out. Then update the shell script to use this variable instead of calling exec ccache.
I recognize that you can build the project without modifications however to build it in Xcode itself and not from the Terminal is broken for me when enabling cchache and i think this could potentially be fixed.
@dehlen thanks for the additional information. The issue can surely be fixed. As of now, we are a bit busy with the rollout of the New Architecture which has the highest priority, so we need to wait a bit for this to happen on our side. However, if you had some spare cycle and you'd like to try and submit a PR, I can help out and make sure we merge it.
I'll give it a shot. I won't be able to have a look at this before next week but will comment back with a PR next week.
Sorry to comment again without having a PR ready for you. I just had a look at the problem. I think the .xcode.env (and .local) files would be the right place to input a new environment variable (CCACHE_BINARY). I can do this in scripts/cocoapods/utils.rb:create_xcode_env_if_missing. I would create a export for .xcode.env with export CCACHE_BINARY=$(command -v ccache)
and for the local variant echo 'export CCACHE_BINARY=#{ccache_path}' > #{file_path}.local
if ccache is available. I then would assume calling the ccache scripts via with-environment.sh ccache_script
would work.
I would choose this behaviour for the following reasons:
command -v ccache
is used. If it is not in the PATH one has the ability to overwrite this in the .xcode.env.local. So no changes for existing users of this feature, unless you want to support this use case.CCACHE_BINARY="${CCACHE_BINARY:-$(command -v ccache || true)}"
if [ -z "$CCACHE_BINARY" ]; then
echo "[Error] Could not find ccache. It looks like that the .xcode.env or .xcode.env.local " \
"files are misconfigured. Please check that they are exporting a valid CCACHE_BINARY " \
"variable, pointing to the ccache executable."
exit 1
fi
However I am not quite sure why I can't make it run like that. Somehow when switching the CC, CXX, LD and LDPLUSPLUS variables to something like /absolute/path/to/with-environment.sh "/absolute/path/to/clang/or/clang++-script.sh"
errors our for me although I added the CCACHE_BINARY export to my environment. Executing the with-environment.sh. I then tried to call with-environment.sh directly from the clang scripts without changing the way CC, CXX, LD and LDPLUSPLUS are configured like this:
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
REACT_NATIVE_CCACHE_CONFIGPATH=$SCRIPT_DIR/ccache.conf
# Provide our config file if none is already provided
export CCACHE_CONFIGPATH="${CCACHE_CONFIGPATH:-$REACT_NATIVE_CCACHE_CONFIGPATH}"
WITH_ENVIRONMENT="$SCRIPT_DIR/with-environment.sh"
. "$WITH_ENVIRONMENT"
CCACHE_BINARY="${CCACHE_BINARY:-$(command -v ccache || true)}"
if [ -z "$CCACHE_BINARY" ]; then
echo "[Error] Could not find ccache. It looks like that the .xcode.env or .xcode.env.local " \
"files are misconfigured. Please check that they are exporting a valid CCACHE_BINARY " \
"variable, pointing to the ccache executable."
exit 1
fi
exec "$CCACHE_BINARY" clang "$@"
However this does not work as well. The environment variables are not found f.e. PODS_ROOT is not found and therefore with-environment.sh does not find the xcode env files. I am willing to investigate a bit further but I feel like I am missing the kownledge regarding environment variables in Xcode and shell scripting to find a quick solution for now. I could pass the ccache path directly to the clang scripts however I am not sure whether this would be an acceptable solution?
Hi @dehlen, thanks for investigating the solution.
The with-environment.sh
should be effectively the best approach.
I don't know why it is not working for the CC
, etc. settings... might it be because they expect a single script/executable with no parameters? It might be that Xcode uses that executable as starting point and passes extra parameters that do not work properly.
Having the error might help.
Xcode passes parameters to ccache which is why I tried to call with-environment.sh from inside the ccache scripts. They pass all variables to ccache via $@. I will recreate my last approach and comment with the error messages.
EDIT: To make it even easier to debug I did the following things:
#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
REACT_NATIVE_CCACHE_CONFIGPATH=$SCRIPT_DIR/ccache.conf
export CCACHE_CONFIGPATH="${CCACHE_CONFIGPATH:-$REACT_NATIVE_CCACHE_CONFIGPATH}"
echo "PODS_ROOT"
echo "$PODS_ROOT"
ENV_PATH="$PODS_ROOT/../.xcode.env" if [ -f "$ENV_PATH" ]; then source "$ENV_PATH" fi
LOCAL_ENV_PATH="${ENV_PATH}.local" if [ -f "$LOCAL_ENV_PATH" ]; then source "$LOCAL_ENV_PATH" fi
exec "$CCACHE_BINARY" clang(++) "$@"
So I basically copy and pasted the relevant parts of with-environment.sh into the clang scripts to source the environment files. However the clang scripts do not received the PODS_ROOT environment, it is empty. Therefore sourcing does not work and the script fails. The same happens when running with-environment.sh instead of copy & pasting it directly into the script. PODS_ROOT is available as a user defined setting however the script does not receive these variables and I am not quite sure why. I tried changing the bang from `#!/bin/sh` to `#!/bin/bash` as with-environment.sh uses bash but this did not change anything.
I added a printenv to the script to see what environment values are available inside the ccache script:
CA_DEBUG_TRANSACTIONS=1
SHELL=/bin/zsh
TMPDIR=/var/folders/x3/lr5jdrkx0_34k92lf27vt5_c0000gq/T/
CCACHE_CONFIGPATH=/my/project/path/node_modules/react-native/scripts/xcode/ccache.conf
LLBUILD_LANE_ID=6
USER=MyUserName
LD_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/../SharedFrameworks/
COMMAND_MODE=unix2003
LLBUILD_BUILD_ID=3364094211
UsePerConfigurationBuildLocations=YES
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.VSXXhHK684/Listeners
__CF_USER_TEXT_ENCODING=0x1F7:0x0:0x3
PATH=/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin
__CFBundleIdentifier=com.apple.dt.Xcode
PWD=/my/project/path/Pods
XPC_FLAGS=0x0
XPC_SERVICE_NAME=0
SHLVL=1
HOME=/My/Home/Dir
LOGNAME=MyUserName
LLBUILD_TASK_ID=1030006014a
LLBUILD_CONTROL_FD=21
CA_ASSERT_MAIN_THREAD_TRANSACTIONS=1
_=/usr/bin/printenv
If I append the CCACHE_BINARY path like so for CC, LD, etc.:
ccache_clang_sh = "CCACHE_BINARY=#{ccache_path} #{ccache_clang_sh_path}"
ccache_clangpp_sh = "CCACHE_BINARY=#{ccache_path} #{ccache_clangpp_sh_path}"
this also fails with this error message:
error: unable to spawn process 'CCACHE_BINARY=/opt/homebrew/bin/ccache /my/project/path/node_modules/react-native/scripts/xcode/ccache-clang.sh' (No such file or directory)
At this point the only thing I could think of is adding this to the ccache scripts (which is obviously working for my case but most certainly will not work for everyone):
export PATH="$PATH:/usr/local/bin:/opt/homebrew/bin/"
Another option might be to echo a warning if ccache can't be found and use clang or clang++ directly in that case. While this does not solve the issue at hand at least it would not result in a build issue. The user could then write some custom post_install hook or change the CC,LD environment variables to fix the problem locally. What do you think about this? I am not 100% sure which way would be preferred. Also it might be of course totally possible to find a better solution I haven't found yet. Open for any suggestions.
The warning can be a good alternative, but I'm afraid that people might not see it.
Issue persists at 0.76.0
and what more, in a project that uses C++ turbomodules, it prevents from diagnosing upgrading issues (in my case 0.74.2 to 0.76.0).
After following the upgrade guide at https://react-native-community.github.io/upgrade-helper/?from=0.74.2&to=0.76.0
, and doing pod install etc, the compilation process triggered by react-native run-ios
(and xcode) fails with xcode error 65.
To diagnose the error, we need to go run the build process from XCode, but the reason above blocks me from doing that.
Description
When opening Xcode not from the command line (via xed f.e.) but directly from Finder/Dock and the ccache option is enabled the build will fail because ccache can not be found even though it is installed. The issue exists because the PATH most certainly won't include the ccache binary (f.e. when installed via homebrew, it is located at /opt/homebrew/bin/ccache but Xcodes PATH does not include it). When setting the project up for ccache, the existence of ccache is checked. However this runs as part of pod install in a terminal environment with a potentially different PATH env variable. To fix this I think the ccache path found at pod install time should be passed to the ccache-clang and ccache-clang++.sh scripts.
Steps to reproduce
An error message will be visible stating: [root_path]/node_modules/react-native/scripts/xcode/ccache-clang.sh: line 14: exec: ccache: not found Command CompileC failed with a nonzero exit code
React Native Version
0.74.2
Affected Platforms
Build - MacOS
Output of
npx react-native info
Stacktrace or Logs
Reproducer
https://github.com/dehlen/rn-ccache-bug
Screenshots and Videos
No response