summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hirsch, Ph.D <scivision@users.noreply.github.com>2019-11-27 01:35:15 -0500
committerMichael Hirsch, Ph.D <10931741+scivision@users.noreply.github.com>2019-12-09 11:15:58 -0500
commit98fd4e5557cb21affd2e2c124a132953b471a748 (patch)
treeb350f0499b18795c89378790074a790488a3c351
parent419a7a8f51fb68cdd40f7005394590a0963d3f32 (diff)
downloadmeson-98fd4e5557cb21affd2e2c124a132953b471a748.tar.gz
cmake: add project language to cmakelists.txt
cmake: get language from Meson project if not specified as depedency(..., langugage: ...) deps: add threads method:cmake dependency('threads', method: 'cmake') is useful for cmake unit tests or those who just want to find threads using cmake. cmake: project(... Fortran) generally also requires C language
-rw-r--r--mesonbuild/dependencies/base.py53
-rw-r--r--mesonbuild/dependencies/data/CMakeLists.txt6
-rw-r--r--mesonbuild/dependencies/misc.py38
-rw-r--r--mesonbuild/mesonlib.py4
-rw-r--r--test cases/cmake/14 fortran threads/meson.build9
-rw-r--r--test cases/frameworks/1 boost/meson.build1
-rw-r--r--test cases/frameworks/2 gtest/meson.build1
-rw-r--r--test cases/linuxlike/13 cmake dependency/meson.build4
8 files changed, 101 insertions, 15 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 8e7179a68..cbc9f65d1 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -1037,7 +1037,23 @@ class CMakeDependency(ExternalDependency):
# one module
return module
- def __init__(self, name: str, environment: Environment, kwargs, language=None):
+ def __init__(self, name: str, environment: Environment, kwargs, language: str = None):
+ if language is 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'
+ 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'
+
super().__init__('cmake', environment, language, kwargs)
self.name = name
self.is_libtool = False
@@ -1460,9 +1476,40 @@ class CMakeDependency(ExternalDependency):
build_dir = Path(self.cmake_root_dir) / 'cmake_{}'.format(self.name)
build_dir.mkdir(parents=True, exist_ok=True)
- # Copy the CMakeLists.txt
+ # Insert language parameters into the CMakeLists.txt and write new CMakeLists.txt
src_cmake = Path(__file__).parent / 'data' / cmake_file
- shutil.copyfile(str(src_cmake), str(build_dir / 'CMakeLists.txt')) # str() is for Python 3.5
+ cmake_txt = src_cmake.read_text()
+
+ # In general, some Fortran CMake find_package() also require C language enabled,
+ # even if nothing from C is directly used. An easy Fortran example that fails
+ # without C language is
+ # find_package(Threads)
+ # 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']
+
+ 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)
return str(build_dir)
diff --git a/mesonbuild/dependencies/data/CMakeLists.txt b/mesonbuild/dependencies/data/CMakeLists.txt
index 64f5b235c..b52a69a85 100644
--- a/mesonbuild/dependencies/data/CMakeLists.txt
+++ b/mesonbuild/dependencies/data/CMakeLists.txt
@@ -1,4 +1,8 @@
-cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )
+# fail noisily if attempt to use this file without setting:
+# cmake_minimum_required(VERSION ${CMAKE_VERSION})
+# project(... LANGUAGES ...)
+
+cmake_policy(SET CMP0000 NEW)
set(PACKAGE_FOUND FALSE)
set(_packageName "${NAME}")
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index bfd450c4f..d773eb7ba 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -22,6 +22,7 @@ import sysconfig
from .. import mlog
from .. import mesonlib
from ..environment import detect_cpu_family
+from ..mesonlib import listify
from .base import (
DependencyException, DependencyMethods, ExternalDependency,
@@ -109,15 +110,34 @@ class ThreadDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('threads', environment, None, kwargs)
self.name = 'threads'
- self.is_found = True
- # Happens if you are using a language with threads
- # concept without C, such as plain Cuda.
- if self.clib_compiler is None:
- self.compile_args = []
- self.link_args = []
- else:
- self.compile_args = self.clib_compiler.thread_flags(environment)
- self.link_args = self.clib_compiler.thread_link_flags(environment)
+ self.is_found = False
+ methods = listify(self.methods)
+ if DependencyMethods.AUTO in methods:
+ self.is_found = True
+ # Happens if you are using a language with threads
+ # concept without C, such as plain Cuda.
+ if self.clib_compiler is None:
+ self.compile_args = []
+ self.link_args = []
+ else:
+ self.compile_args = self.clib_compiler.thread_flags(environment)
+ self.link_args = self.clib_compiler.thread_link_flags(environment)
+ return
+
+ if DependencyMethods.CMAKE in methods:
+ # for unit tests and for those who simply want
+ # dependency('threads', method: 'cmake')
+ cmakedep = CMakeDependency('Threads', environment, kwargs)
+ if cmakedep.found():
+ self.compile_args = cmakedep.get_compile_args()
+ self.link_args = cmakedep.get_link_args()
+ self.version = cmakedep.get_version()
+ self.is_found = True
+ return
+
+ @staticmethod
+ def get_methods():
+ return [DependencyMethods.AUTO, DependencyMethods.CMAKE]
class BlocksDependency(ExternalDependency):
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 0d8ec3cff..5c3fc45cf 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -976,7 +976,9 @@ def replace_if_different(dst, dst_tmp):
else:
os.unlink(dst_tmp)
-def listify(item, flatten=True, unholder=False):
+def listify(item: typing.Any,
+ flatten: bool = True,
+ unholder: bool = False) -> typing.List[typing.Any]:
'''
Returns a list with all args embedded in a list if they are not a list.
This function preserves order.
diff --git a/test cases/cmake/14 fortran threads/meson.build b/test cases/cmake/14 fortran threads/meson.build
new file mode 100644
index 000000000..f160ca806
--- /dev/null
+++ b/test cases/cmake/14 fortran threads/meson.build
@@ -0,0 +1,9 @@
+project('FortranThreads')
+
+if not add_languages('fortran', required: false)
+ error('MESON_SKIP_TEST: Fortran language not available.')
+endif
+
+# want to be sure that CMake can find dependencies where even if the
+# project isn't C, the C language is required to find the library.
+threads = dependency('threads', method: 'cmake', required: true)
diff --git a/test cases/frameworks/1 boost/meson.build b/test cases/frameworks/1 boost/meson.build
index 8f45dc7fe..4526c300c 100644
--- a/test cases/frameworks/1 boost/meson.build
+++ b/test cases/frameworks/1 boost/meson.build
@@ -1,3 +1,4 @@
+# this test requires the following on Ubuntu: libboost-{system,python,log,thread,test}-dev
project('boosttest', 'cpp',
default_options : ['cpp_std=c++11'])
diff --git a/test cases/frameworks/2 gtest/meson.build b/test cases/frameworks/2 gtest/meson.build
index 3f30215de..2d93b5294 100644
--- a/test cases/frameworks/2 gtest/meson.build
+++ b/test cases/frameworks/2 gtest/meson.build
@@ -1,3 +1,4 @@
+# on Ubuntu this test requires libgtest-dev
project('gtest', 'cpp')
gtest = dependency('gtest', main : true, required : false)
diff --git a/test cases/linuxlike/13 cmake dependency/meson.build b/test cases/linuxlike/13 cmake dependency/meson.build
index 682d6d84f..775355025 100644
--- a/test cases/linuxlike/13 cmake dependency/meson.build
+++ b/test cases/linuxlike/13 cmake dependency/meson.build
@@ -1,3 +1,5 @@
+# this test can ONLY be run successfully from run_project_test.py
+# due to use of setup_env.json
project('external CMake dependency', 'c')
if not find_program('cmake', required: false).found()
@@ -37,7 +39,7 @@ depf2 = dependency('ZLIB', required : false, method : 'cmake', modules : 'dfggh:
assert(depf2.found() == false, 'Invalid CMake targets should fail')
# Try to find cmMesonTestDep in a custom prefix
-
+# setup_env.json is used by run_project_tests.py:_run_test to point to ./cmake_pref_env/
depPrefEnv = dependency('cmMesonTestDep', required : true, method : 'cmake')
# Try to find a dependency with a custom CMake module