Repository: spack/spack

Issue:
spack env activate does not set gcc env variables
### Steps to reproduce

Create gcc-env environment that includes gcc in the specs then...

```console
spack env activate gcc-env
```

The gcc env variables (CXX, CC, etc.) are not set

However:

```console
spack load gcc
```

Set the variables correctly

### Error message

No error message, but the following command, for example, shows no output

```console
env | grep CXX
```

### Information on your system

❯ spack debug report
* Spack: 0.19.0 (a86911246a8c5571ca210ff25fc990b8eb297a5c)
* Python: 3.6.8
* Platform: linux-rhel7-zen2
* Concretizer: clingo

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output


Discussion:
This issue was discussed in the Spack Slack chat.

@robertu94 and @scheibelp have investigated the source of this problem and might want to add their findings.

Thank you!
The underlying issue seems to be in gcc's `setup_run_envionment` function. 

https://github.com/spack/spack/blob/b9f48da560374ea9ace74cf1bd630846ca1d00bf/var/spack/repos/builtin/packages/gcc/package.py#L999-L1001

Essentially when calling `spack env activate .`, `self.prefix` which is part of `binpath` here is set to the path of the view.  By adding a print of relevent local variables we can see:


```console
gcc re.compile('^()gcc()$') /tmp/foo/.spack-env/view/./bin/gcc True
g++ re.compile('^()g\\+\\+()$') /tmp/foo/.spack-env/view/./bin/g++ True
gfortran re.compile('^()gfortran()$') /tmp/foo/.spack-env/view/./bin/gfortran True
gfortran re.compile('^()gfortran()$') /tmp/foo/.spack-env/view/./bin/gfortran True
gcc re.compile('^()gcc()$') /tmp/foo/.spack-env/view/./bin/gcc True
g++ re.compile('^()g\\+\\+()$') /tmp/foo/.spack-env/view/./bin/g++ True
gfortran re.compile('^()gfortran()$') /tmp/foo/.spack-env/view/./bin/gfortran True
gfortran re.compile('^()gfortran()$') /tmp/foo/.spack-env/view/./bin/gfortran True
```

However when calling `spack load` **even in an environment**, `self.prefix` is set to wherever the package is stored in `$SPACK_ROOT/opt/spack/...`

```console
gcc re.compile('^()gcc()$') /home/runderwood/git/contrib/spack/opt/spack/linux-fedora37-icelake/gcc-12.2.1/gcc-12.2.0-fuc63lu3bwthtsy5bdzu2rzuv566awqv/bin/gcc False
g++ re.compile('^()g\\+\\+()$') /home/runderwood/git/contrib/spack/opt/spack/linux-fedora37-icelake/gcc-12.2.1/gcc-12.2.0-fuc63lu3bwthtsy5bdzu2rzuv566awqv/bin/g++ False
gfortran re.compile('^()gfortran()$') /home/runderwood/git/contrib/spack/opt/spack/linux-fedora37-icelake/gcc-12.2.1/gcc-12.2.0-fuc63lu3bwthtsy5bdzu2rzuv566awqv/bin/gfortran False
gfortran re.compile('^()gfortran()$') /home/runderwood/git/contrib/spack/opt/spack/linux-fedora37-icelake/gcc-12.2.1/gcc-12.2.0-fuc63lu3bwthtsy5bdzu2rzuv566awqv/bin/gfortran False
```

However since in the view _most_ of the files are links, we always `continue` in the loop here rather than setting the environment variables.  This seems to be the way that it is because when GCC is external on some systems (I believe Ubuntu, but don't quote me here), gcc installs links to itself with different names, and we only want to use the real one that isn't a link.

@scheibelp thinks that the fix should be in `user_environment.environment_modifications_for_spec`
Some information from another package that I think might be relevant. llvm also sets these variables (only with the +clang variant, which is however True by default). No symlink check is performed in this case:

https://github.com/spack/spack/blob/6a44a146afcea1fd69c3f638e7096e329bfaa916/var/spack/repos/builtin/packages/llvm/package.py#L540

Following the discussion on the Q/A, a topic for discussion could be: what happens if two packages in the environment (for example gcc and llvm) both add the environment variables?
> Following the discussion on the Q/A, a topic for discussion could be: what happens if two packages in the environment (for example gcc and llvm) both add the environment variables?

In this case (with `env.set`) the last definition wins which I am guessing would either be clang or undefined.  It would be clang if `clang ^ gcc`, but otherwise it would be the one ordered last in the dag which may be harder to predict.  That's probably not great UX, and should probably generate a warning and eventually give a user a way to de-conflict this in a more obviously deterministic way.

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/gcc/package.py b/var/spack/repos/builtin/packages/gcc/package.py
--- a/var/spack/repos/builtin/packages/gcc/package.py
+++ b/var/spack/repos/builtin/packages/gcc/package.py
@@ -1016,7 +1016,9 @@ def setup_run_environment(self, env):
                     continue
 
                 abspath = os.path.join(bin_path, filename)
-                if os.path.islink(abspath):
+
+                # Skip broken symlinks (https://github.com/spack/spack/issues/41327)
+                if not os.path.exists(abspath):
                     continue
 
                 # Set the proper environment variable


Test patch: