Repository: mesonbuild/meson

Issue:
(Spurious?) RuntimeError: No specified compiler can handle file impl/json/jsmn.c
With 0.44.0, I get this error:

```
RuntimeError: No specified compiler can handle file impl/json/jsmn.c
```

This in a project which is mostly C++, but it uses this one `.c` file, defined as:

```
jsmn = declare_dependency( sources: ['impl/json/jsmn.c'], compile_args: [ '-DJSMN_STRICT=1', '-DJSMN_PARENT_LINKS=1' ])
```

The project statement at the top was:

```
project('name','cpp',default_options : ['cpp_std=c++11','b_pch=false'])
```

Previous versions of Meson didn't report any errors, but I figured I'd have to add `'c'` to the list. I tried:

```
project('name',['cpp','c'],default_options : ['cpp_std=c++11','b_pch=false'])
```

which gave me the error message I quoted at the top of this report.


Discussion:
Can you please reduce this to a small test case so we can reproduce it?

Resolving patch:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -365,9 +365,9 @@ def __init__(self, name, subdir, subproject, is_cross, sources, objects, environ
         # 1. Pre-existing objects provided by the user with the `objects:` kwarg
         # 2. Compiled objects created by and extracted from another target
         self.process_objectlist(objects)
-        self.process_compilers()
         self.process_kwargs(kwargs, environment)
         self.check_unknown_kwargs(kwargs)
+        self.process_compilers()
         if not any([self.sources, self.generated, self.objects, self.link_whole]):
             raise InvalidArguments('Build target %s has no sources.' % name)
         self.process_compilers_late()
@@ -500,6 +500,13 @@ def process_compilers(self):
                 # which is what we need.
                 if not is_object(s):
                     sources.append(s)
+        for d in self.external_deps:
+            if hasattr(d, 'held_object'):
+                d = d.held_object
+            for s in d.sources:
+                if isinstance(s, (str, File)):
+                    sources.append(s)
+
         # Sources that were used to create our extracted objects
         for o in self.objects:
             if not isinstance(o, ExtractedObjects):
@@ -690,8 +697,7 @@ def process_kwargs(self, kwargs, environment):
                     raise InvalidArguments('Arguments to d_import_dirs must be include_directories.')
             dfeatures['import_dirs'] = dfeature_import_dirs
         if dfeatures:
-            if 'd' in self.compilers:
-                self.d_features = dfeatures
+            self.d_features = dfeatures
 
         self.link_args = extract_as_list(kwargs, 'link_args')
         for i in self.link_args:


Test patch:
diff --git a/test cases/common/179 source in dep/bar.cpp b/test cases/common/179 source in dep/bar.cpp
new file mode 100644
--- /dev/null
+++ b/test cases/common/179 source in dep/bar.cpp	
@@ -0,0 +1,5 @@
+extern "C" int foo();
+
+int main(int, char**) {
+    return foo() != 42;
+}
diff --git a/test cases/common/179 source in dep/foo.c b/test cases/common/179 source in dep/foo.c
new file mode 100644
--- /dev/null
+++ b/test cases/common/179 source in dep/foo.c	
@@ -0,0 +1,3 @@
+int foo() {
+    return 42;
+}
diff --git a/test cases/common/179 source in dep/meson.build b/test cases/common/179 source in dep/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/common/179 source in dep/meson.build	
@@ -0,0 +1,6 @@
+project('foo', 'c', 'cpp')
+
+dep = declare_dependency(sources : 'foo.c')
+
+executable('bar', 'bar.cpp',
+  dependencies : dep)