Repository: mesonbuild/meson

Issue:
No host machine compiler for subproject linking to dependency in other subproject
**Describe the bug**
When using c-subproject in the dependencies of cpp-subproject, I get an error about no host machine compiler for the c language. The base project is also cpp.

```text
subprojects/animationwindow/meson.build:7:0: ERROR: No host machine compiler for 'subprojects/SDL2-2.0.20/src/SDL.c'
```

This **doesn't** happen if:

* I define `c` as one of the languages in the cpp-subproject
* I remove animationwindow, and have SDL as the only subproject

It does not however matter whether or not i define `c` as one of the languages in base project, neither if animationwindow is present or not

**To Reproduce**
structure:

├── subprojects
│   ├── cpp-subproject (animationwindow
│   └── c-subproject (sdl)
├── main.cpp
└── meson.build

E.g. SDL and animationwindow are parallell, not nested.

meson.build
```meson
project('testproject', 'cpp',
  version : '0.1',
  default_options : ['warning_level=2',
                     'cpp_std=c++17',
                     'c_std=c17',
                     'default_library=static'])

sdl2_dep = dependency('sdl2')
animationwindow_dep = dependency('animationwindow', fallback: ['animationwindow', 'animationwindow_dep'])

src = ['main.cpp']

exe = executable('program', src, dependencies : [animationwindow_dep, sdl2_dep])
```

subprojects/animationwindow.cpp
```meson
project('animationwindow', 'cpp', default_options: ['cpp_std=c++17', 'default_library=static', 'buildtype=debugoptimized'])

sdl2_dep = dependency('sdl2')

build_files = ['src/notfinished.cpp']
incdir = include_directories('include')
animationwindow = static_library('animationwindow', build_files, include_directories: incdir, dependencies: [sdl2_dep], install: true)
install_subdir('include', install_dir: '.')
install_subdir('src', install_dir: '.')

animationwindow_dep = declare_dependency(link_with: animationwindow, include_directories: incdir)
```

subprojects/sdl2.wrap
```ini
[wrap-file]
directory = SDL2-2.0.20
source_url = https://libsdl.org/release/SDL2-2.0.20.tar.gz
source_filename = SDL2-2.0.20.tar.gz
source_hash = c56aba1d7b5b0e7e999e4a7698c70b63a3394ff9704b5f6e1c57e0c16f04dd06
patch_filename = sdl2_2.0.20-5_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_2.0.20-5/get_patch
patch_hash = b0a3700820b2553ae228963f5a6168525404e65d579528957e872c19235deb22
wrapdb_version = 2.0.20-5

[provide]
sdl2 = sdl2_dep
```

**Expected behavior**
Expected to `meson setup debug` without any issues.

**system parameters**
* This is a native build
* on a m1 Mac running macos monterey 12.4
* meson 0.63.0 from homebrew
* python 3.8.9



Discussion:
Perhaps a pointer to resolving this: I had this same issue on a Windows machine, and was able to resolve it by changing the project languages of (here) subprojects/animationwindow/meson.build to ['c', 'cpp'], despite the issue occurring in the SDL dependency referenced by that file.
After a bit of testing, I figured out that this happens when:
- the sdl2 subproject creates a dependency object with:
  -  an ***uninstalled*** static library
  - that is link_whole, not link_with (this happens due to promotion)
- the animationwindow subproject links to this in another static library that is ***installed***

A successful configuration results in the objects of the sdl2 dependency (`libsdl2.a`) getting directly included in `libanimationwindow.a`, as they are needed at install time to be functional. It looks like by including the *objects* (effectively extract_all_objects() and including that as additional sources) the interpreter sees 

```python
mesonlib.File(is_built=False, subdir='subprojects/SDL2-2.0.20/src', fname='SDL.c')
```

It's not clear to me why we use this internal representation as "another source file". It means that even though the parent project isn't actually responsible for compiling anything here, it still checks the compiler. A build.BuildTarget should NOT need to check for a suitable compiler for an extracted object.
I think this is a regression since https://mesonbuild.com/Release-notes-for-0-63-0.html#persubproject-languages because we used to share the compilers list across all subprojects. @xclaesse what an interesting fallout. :(

Resolving patch:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -39,7 +39,7 @@
     MesonBugException
 )
 from .compilers import (
-    is_object, clink_langs, sort_clink, lang_suffixes, all_languages,
+    is_object, clink_langs, sort_clink, all_languages,
     is_known_suffix, detect_static_linker
 )
 from .interpreterbase import FeatureNew, FeatureDeprecated
@@ -950,12 +950,15 @@ def process_compilers(self) -> T.List[str]:
         for o in self.objects:
             if not isinstance(o, ExtractedObjects):
                 continue
-            for s in o.srclist:
+            compsrcs = o.classify_all_sources(o.srclist, [])
+            for comp in compsrcs:
                 # Don't add Vala sources since that will pull in the Vala
                 # compiler even though we will never use it since we are
                 # dealing with compiled C code.
-                if not s.endswith(lang_suffixes['vala']):
-                    sources.append(s)
+                if comp.language == 'vala':
+                    continue
+                if comp.language not in self.compilers:
+                    self.compilers[comp.language] = comp
         if sources:
             # For each source, try to add one compiler that can compile it.
             #


Test patch:
diff --git a/test cases/common/253 subproject extracted objects/foo.c b/test cases/common/253 subproject extracted objects/foo.c
new file mode 100644
--- /dev/null
+++ b/test cases/common/253 subproject extracted objects/foo.c	
@@ -0,0 +1,11 @@
+#if defined _WIN32 || defined __CYGWIN__
+  #define DLL_IMPORT __declspec(dllimport)
+#else
+  #define DLL_IMPORT
+#endif
+
+int DLL_IMPORT cppfunc(void);
+
+int otherfunc(void) {
+    return cppfunc() != 42;
+}
diff --git a/test cases/common/253 subproject extracted objects/meson.build b/test cases/common/253 subproject extracted objects/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/common/253 subproject extracted objects/meson.build	
@@ -0,0 +1,5 @@
+project('link to extracted objects', 'c')
+
+sublib = subproject('myobjects').get_variable('sublib')
+
+mainlib = static_library('foo', 'foo.c', install: true, link_with: sublib)
diff --git a/test cases/common/253 subproject extracted objects/subprojects/myobjects/cpplib.cpp b/test cases/common/253 subproject extracted objects/subprojects/myobjects/cpplib.cpp
new file mode 100644
--- /dev/null
+++ b/test cases/common/253 subproject extracted objects/subprojects/myobjects/cpplib.cpp	
@@ -0,0 +1,6 @@
+#define BUILDING_DLL
+#include "cpplib.h"
+
+extern "C" int DLL_PUBLIC cppfunc(void) {
+    return 42;
+}
diff --git a/test cases/common/253 subproject extracted objects/subprojects/myobjects/cpplib.h b/test cases/common/253 subproject extracted objects/subprojects/myobjects/cpplib.h
new file mode 100644
--- /dev/null
+++ b/test cases/common/253 subproject extracted objects/subprojects/myobjects/cpplib.h	
@@ -0,0 +1,12 @@
+/* See http://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support */
+#if defined(_WIN32) || defined(__CYGWIN__)
+  #ifdef BUILDING_DLL
+    #define DLL_PUBLIC __declspec(dllexport)
+  #else
+    #define DLL_PUBLIC __declspec(dllimport)
+  #endif
+#else
+    #define DLL_PUBLIC __attribute__ ((visibility ("default")))
+#endif
+
+extern "C" int DLL_PUBLIC cppfunc(void);
diff --git a/test cases/common/253 subproject extracted objects/subprojects/myobjects/meson.build b/test cases/common/253 subproject extracted objects/subprojects/myobjects/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/common/253 subproject extracted objects/subprojects/myobjects/meson.build	
@@ -0,0 +1,3 @@
+project('myobjects', 'cpp')
+
+sublib = static_library('sublib', 'cpplib.cpp')
diff --git a/test cases/common/253 subproject extracted objects/test.json b/test cases/common/253 subproject extracted objects/test.json
new file mode 100644
--- /dev/null
+++ b/test cases/common/253 subproject extracted objects/test.json	
@@ -0,0 +1,5 @@
+{
+  "installed": [
+    { "type": "file", "file": "usr/lib/libfoo.a"  }
+  ]
+}