| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmTryCompileCommand.h" |
| |
| #include <cm/optional> |
| |
| #include "cmConfigureLog.h" |
| #include "cmCoreTryCompile.h" |
| #include "cmExecutionStatus.h" |
| #include "cmMakefile.h" |
| #include "cmMessageType.h" |
| #include "cmRange.h" |
| #include "cmState.h" |
| #include "cmStateTypes.h" |
| #include "cmStringAlgorithms.h" |
| #include "cmValue.h" |
| #include "cmake.h" |
| |
| namespace { |
| #ifndef CMAKE_BOOTSTRAP |
| void WriteTryCompileEvent(cmConfigureLog& log, cmMakefile const& mf, |
| cmTryCompileResult const& compileResult) |
| { |
| // Keep in sync with cmFileAPIConfigureLog's DumpEventKindNames. |
| static const std::vector<unsigned long> LogVersionsWithTryCompileV1{ 1 }; |
| |
| if (log.IsAnyLogVersionEnabled(LogVersionsWithTryCompileV1)) { |
| log.BeginEvent("try_compile-v1"); |
| log.WriteBacktrace(mf); |
| cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult); |
| log.EndEvent(); |
| } |
| } |
| #endif |
| } |
| |
| bool cmTryCompileCommand(std::vector<std::string> const& args, |
| cmExecutionStatus& status) |
| { |
| cmMakefile& mf = status.GetMakefile(); |
| |
| if (args.size() < 3) { |
| mf.IssueMessage( |
| MessageType::FATAL_ERROR, |
| "The try_compile() command requires at least 3 arguments."); |
| return false; |
| } |
| |
| if (mf.GetCMakeInstance()->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) { |
| mf.IssueMessage( |
| MessageType::FATAL_ERROR, |
| "The try_compile() command is not supported in --find-package mode."); |
| return false; |
| } |
| |
| cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE; |
| cmValue tt = mf.GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE"); |
| if (cmNonempty(tt)) { |
| if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) { |
| targetType = cmStateEnums::EXECUTABLE; |
| } else if (*tt == |
| cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) { |
| targetType = cmStateEnums::STATIC_LIBRARY; |
| } else { |
| mf.IssueMessage( |
| MessageType::FATAL_ERROR, |
| cmStrCat("Invalid value '", *tt, |
| "' for CMAKE_TRY_COMPILE_TARGET_TYPE. Only '", |
| cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE), |
| "' and '", |
| cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY), |
| "' are allowed.")); |
| return false; |
| } |
| } |
| |
| cmCoreTryCompile tc(&mf); |
| cmCoreTryCompile::Arguments arguments = |
| tc.ParseArgs(cmMakeRange(args), false); |
| if (!arguments) { |
| return true; |
| } |
| |
| cm::optional<cmTryCompileResult> compileResult = |
| tc.TryCompileCode(arguments, targetType); |
| #ifndef CMAKE_BOOTSTRAP |
| if (compileResult && !arguments.NoLog) { |
| if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) { |
| WriteTryCompileEvent(*log, mf, *compileResult); |
| } |
| } |
| #endif |
| |
| // if They specified clean then we clean up what we can |
| if (tc.SrcFileSignature) { |
| if (!mf.GetCMakeInstance()->GetDebugTryCompile()) { |
| tc.CleanupFiles(tc.BinaryDirectory); |
| } |
| } |
| return true; |
| } |