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
This commit is contained in:
parent
419a7a8f51
commit
98fd4e5557
|
@ -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)
|
||||
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
|
@ -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'])
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# on Ubuntu this test requires libgtest-dev
|
||||
project('gtest', 'cpp')
|
||||
|
||||
gtest = dependency('gtest', main : true, required : false)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue