Skip to content

Commit 5bd21a9

Browse files
mensindajpakkane
authored andcommitted
cmake: Fix dependencies with try_compile (closes mesonbuild#5605)
1 parent 555847f commit 5bd21a9

File tree

2 files changed

+55
-11
lines changed

2 files changed

+55
-11
lines changed

mesonbuild/cmake/executor.py

+52-11
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
if TYPE_CHECKING:
2525
from ..dependencies.base import ExternalProgram
2626

27-
import re, os, ctypes
27+
import re, os, shutil, ctypes
2828

2929
class CMakeExecutor:
3030
# The class's copy of the CMake path. Avoids having to search for it
@@ -162,6 +162,41 @@ def call_with_fake_build(self, args: List[str], build_dir: str, env=None):
162162

163163
os.makedirs(build_dir, exist_ok=True)
164164

165+
# Try to set the correct compiler for C and C++
166+
# This step is required to make try_compile work inside CMake
167+
fallback = os.path.realpath(__file__) # A file used as a fallback wehen everything else fails
168+
compilers = self.environment.coredata.compilers[MachineChoice.BUILD]
169+
170+
def make_abs(exe: str, lang: str):
171+
if os.path.isabs(exe):
172+
return exe
173+
174+
p = shutil.which(exe)
175+
if p is None:
176+
mlog.debug('Failed to find a {} compiler for CMake. This might cause CMake to fail.'.format(lang))
177+
p = fallback
178+
return p
179+
180+
def choose_compiler(lang: str):
181+
exe_list = []
182+
if lang in compilers:
183+
exe_list = compilers[lang].get_exelist()
184+
else:
185+
comp_obj = self.environment.compiler_from_language(lang, MachineChoice.BUILD)
186+
if comp_obj is not None:
187+
exe_list = comp_obj.get_exelist()
188+
189+
if len(exe_list) == 1:
190+
return make_abs(exe_list[0], lang), ''
191+
elif len(exe_list) == 2:
192+
return make_abs(exe_list[1], lang), make_abs(exe_list[0], lang)
193+
else:
194+
mlog.debug('Failed to find a {} compiler for CMake. This might cause CMake to fail.'.format(lang))
195+
return fallback, ''
196+
197+
c_comp, c_launcher = choose_compiler('c')
198+
cxx_comp, cxx_launcher = choose_compiler('cpp')
199+
165200
# Reset the CMake cache
166201
with open('{}/CMakeCache.txt'.format(build_dir), 'w') as fp:
167202
fp.write('CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1\n')
@@ -170,32 +205,38 @@ def call_with_fake_build(self, args: List[str], build_dir: str, env=None):
170205
comp_dir = '{}/CMakeFiles/{}'.format(build_dir, self.cmakevers)
171206
os.makedirs(comp_dir, exist_ok=True)
172207

173-
c_comp = '{}/CMakeCCompiler.cmake'.format(comp_dir)
174-
cxx_comp = '{}/CMakeCXXCompiler.cmake'.format(comp_dir)
208+
c_comp_file = '{}/CMakeCCompiler.cmake'.format(comp_dir)
209+
cxx_comp_file = '{}/CMakeCXXCompiler.cmake'.format(comp_dir)
175210

176-
if not os.path.exists(c_comp):
177-
with open(c_comp, 'w') as fp:
211+
if not os.path.exists(c_comp_file):
212+
with open(c_comp_file, 'w') as fp:
178213
fp.write('''# Fake CMake file to skip the boring and slow stuff
179-
set(CMAKE_C_COMPILER "{}") # Just give CMake a valid full path to any file
214+
set(CMAKE_C_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
215+
set(CMAKE_C_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
180216
set(CMAKE_C_COMPILER_ID "GNU") # Pretend we have found GCC
181217
set(CMAKE_COMPILER_IS_GNUCC 1)
182218
set(CMAKE_C_COMPILER_LOADED 1)
183219
set(CMAKE_C_COMPILER_WORKS TRUE)
184220
set(CMAKE_C_ABI_COMPILED TRUE)
221+
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
222+
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
185223
set(CMAKE_SIZEOF_VOID_P "{}")
186-
'''.format(os.path.realpath(__file__), ctypes.sizeof(ctypes.c_voidp)))
224+
'''.format(c_comp, c_launcher, ctypes.sizeof(ctypes.c_voidp)))
187225

188-
if not os.path.exists(cxx_comp):
189-
with open(cxx_comp, 'w') as fp:
226+
if not os.path.exists(cxx_comp_file):
227+
with open(cxx_comp_file, 'w') as fp:
190228
fp.write('''# Fake CMake file to skip the boring and slow stuff
191-
set(CMAKE_CXX_COMPILER "{}") # Just give CMake a valid full path to any file
229+
set(CMAKE_CXX_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
230+
set(CMAKE_CXX_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
192231
set(CMAKE_CXX_COMPILER_ID "GNU") # Pretend we have found GCC
193232
set(CMAKE_COMPILER_IS_GNUCXX 1)
194233
set(CMAKE_CXX_COMPILER_LOADED 1)
195234
set(CMAKE_CXX_COMPILER_WORKS TRUE)
196235
set(CMAKE_CXX_ABI_COMPILED TRUE)
236+
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
237+
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP)
197238
set(CMAKE_SIZEOF_VOID_P "{}")
198-
'''.format(os.path.realpath(__file__), ctypes.sizeof(ctypes.c_voidp)))
239+
'''.format(cxx_comp, cxx_launcher, ctypes.sizeof(ctypes.c_voidp)))
199240

200241
return self.call(args, build_dir, env)
201242

test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
find_package(ZLIB)
22

3+
include(CMakeFindDependencyMacro)
4+
find_dependency(Threads)
5+
36
if(ZLIB_FOUND OR ZLIB_Found)
47
set(SomethingLikeZLIB_FOUND ON)
58
set(SomethingLikeZLIB_LIBRARIES ${ZLIB_LIBRARY})

0 commit comments

Comments
 (0)