Repository: mesonbuild/meson

Issue:
regression in 0.53. meson cannot handle CheckCXXSourceRuns.cmake
Hi there,

**Describe the bug**

I'm trying to link with project that uses CMake and it checks supported CPU instructions via [CHECK_CXX_SOURCE_RUNS](https://cmake.org/cmake/help/v3.0/module/CheckCXXSourceRuns.html). Meson 0.52 were handling it without any problems, but 0.53 cannot.

Here is cmake file that causes issue [CPUID.cmake](https://github.com/opencv/dldt/blob/2019/inference-engine/src/extension/cmake/CPUID.cmake)

**To Reproduce**

You should install that project and use this meson.build:

```meson
project('mytestproject', ['c', 'cpp'])

inference_engine_dep = dependency('InferenceEngine', version: '>=2.0.0', required: true, method : 'cmake', modules: ['IE::inference_engine'])
```

**Expected behavior**

After running `meson build/` you must see following output:

```sh
Run-time dependency inferenceengine (modules: IE::inference_engine) found: YES 2.1.0
```

**system parameters**
* This is just a plain native build
* Operating system is Ubuntu 18.04
* Python version is 3.6.9
* meson version is 0.53.0



Discussion:
Should be fixed by #6444

Resolving patch:
diff --git a/mesonbuild/cmake/__init__.py b/mesonbuild/cmake/__init__.py
--- a/mesonbuild/cmake/__init__.py
+++ b/mesonbuild/cmake/__init__.py
@@ -25,6 +25,7 @@
     'CMakeTraceLine',
     'CMakeTraceParser',
     'parse_generator_expressions',
+    'language_map',
 ]
 
 from .common import CMakeException
@@ -32,5 +33,5 @@
 from .executor import CMakeExecutor
 from .fileapi import CMakeFileAPI
 from .generator import parse_generator_expressions
-from .interpreter import CMakeInterpreter
+from .interpreter import CMakeInterpreter, language_map
 from .traceparser import CMakeTarget, CMakeTraceLine, CMakeTraceParser
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -79,6 +79,8 @@
     'c': 'C',
     'cpp': 'CXX',
     'cuda': 'CUDA',
+    'objc': 'OBJC',
+    'objcpp': 'OBJCXX',
     'cs': 'CSharp',
     'java': 'Java',
     'fortran': 'Fortran',
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -1061,21 +1061,26 @@ def _original_module_name(self, module: str) -> str:
         return module
 
     def __init__(self, name: str, environment: Environment, kwargs, language: str = None):
+        # Gather a list of all languages to support
+        self.language_list = []  # type: T.List[str]
         if language is None:
+            compilers = None
             if kwargs.get('native', False):
-                if 'c' in environment.coredata.compilers.build.keys():
-                    language = 'c'
-                elif 'cpp' in environment.coredata.compilers.build.keys():
-                    language = 'cpp'
-                elif 'fortran' in environment.coredata.compilers.build.keys():
-                    language = 'fortran'
+                compilers = environment.coredata.compilers.build
             else:
-                if 'c' in environment.coredata.compilers.host.keys():
-                    language = 'c'
-                elif 'cpp' in environment.coredata.compilers.host.keys():
-                    language = 'cpp'
-                elif 'fortran' in environment.coredata.compilers.host.keys():
-                    language = 'fortran'
+                compilers = environment.coredata.compilers.host
+
+            candidates = ['c', 'cpp', 'fortran', 'objc', 'objcxx']
+            self.language_list += [x for x in candidates if x in compilers]
+        else:
+            self.language_list += [language]
+
+        # Add additional languages if required
+        if 'fortran' in self.language_list:
+            self.language_list += ['c']
+
+        # Ensure that the list is unique
+        self.language_list = list(set(self.language_list))
 
         super().__init__('cmake', environment, language, kwargs)
         self.name = name
@@ -1510,29 +1515,19 @@ def _setup_cmake_dir(self, cmake_file: str) -> str:
         # To make this general to
         # any other language that might need this, we use a list for all
         # languages and expand in the cmake Project(... LANGUAGES ...) statement.
-        if self.language is None:
-            cmake_language = ['NONE']
-        elif self.language == 'c':
-            cmake_language = ['C']
-        elif self.language == 'cpp':
-            cmake_language = ['CXX']
-        elif self.language == 'cs':
-            cmake_language = ['CSharp']
-        elif self.language == 'cuda':
-            cmake_language = ['CUDA']
-        elif self.language == 'fortran':
-            cmake_language = ['C', 'Fortran']
-        elif self.language == 'objc':
-            cmake_language = ['OBJC']
-        elif self.language == 'objcpp':
-            cmake_language = ['OBJCXX']
+        from ..cmake import language_map
+        cmake_language = [language_map[x] for x in self.language_list if x in language_map]
+        if not cmake_language:
+            cmake_language += ['NONE']
 
         cmake_txt = """
 cmake_minimum_required(VERSION ${{CMAKE_VERSION}})
 project(MesonTemp LANGUAGES {})
 """.format(' '.join(cmake_language)) + cmake_txt
 
-        (build_dir / 'CMakeLists.txt').write_text(cmake_txt)
+        cm_file = build_dir / 'CMakeLists.txt'
+        cm_file.write_text(cmake_txt)
+        mlog.cmd_ci_include(cm_file.absolute().as_posix())
 
         return str(build_dir)
 


Test patch:
diff --git a/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake b/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake
--- a/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake	
+++ b/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake	
@@ -1,6 +1,43 @@
 find_package(ZLIB)
 
 include(CMakeFindDependencyMacro)
+include(CheckCXXSourceRuns)
+include(CheckCSourceRuns)
+
+check_cxx_source_runs(
+"
+#include <iostream>
+
+using namespace std;
+
+int main(void) {
+  cout << \"Hello World\" << endl;
+  return 0;
+}
+"
+CXX_CODE_RAN
+)
+
+check_c_source_runs(
+"
+#include <stdio.h>
+
+int main(void) {
+  printf(\"Hello World\");
+  return 0;
+}
+"
+C_CODE_RAN
+)
+
+if(NOT CXX_CODE_RAN)
+  message(FATAL_ERROR "Running CXX source code failed")
+endif()
+
+if(NOT C_CODE_RAN)
+  message(FATAL_ERROR "Running C source code failed")
+endif()
+
 find_dependency(Threads)
 
 if(ZLIB_FOUND OR ZLIB_Found)
diff --git a/test cases/linuxlike/13 cmake dependency/meson.build b/test cases/linuxlike/13 cmake dependency/meson.build
--- a/test cases/linuxlike/13 cmake dependency/meson.build	
+++ b/test cases/linuxlike/13 cmake dependency/meson.build	
@@ -1,6 +1,6 @@
 # this test can ONLY be run successfully from run_project_test.py
 # due to use of setup_env.json
-project('external CMake dependency', 'c')
+project('external CMake dependency', ['c', 'cpp'])
 
 if not find_program('cmake', required: false).found()
   error('MESON_SKIP_TEST cmake binary not available.')