Commit a0d64ecf authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'try_compile-lang-std'

f72ba42b try_compile: Add policy CMP0067 to honor language standards
45aa03b9 try_compile: Add options to specify language standards
3bb2051e try_compile: Stop processing when test build system fails to generate
parents 0478314e f72ba42b
......@@ -35,7 +35,11 @@ Try Compiling Source Files
[COMPILE_DEFINITIONS <defs>...]
[LINK_LIBRARIES <libs>...]
[OUTPUT_VARIABLE <var>]
[COPY_FILE <fileName> [COPY_FILE_ERROR <var>]])
[COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
[<LANG>_STANDARD <std>]
[<LANG>_STANDARD_REQUIRED <bool>]
[<LANG>_EXTENSIONS <bool>]
)
Try building an executable from one or more source files. The success or
failure of the ``try_compile``, i.e. ``TRUE`` or ``FALSE`` respectively, is
......@@ -82,6 +86,18 @@ The options are:
``OUTPUT_VARIABLE <var>``
Store the output from the build process the given variable.
``<LANG>_STANDARD <std>``
Specify the :prop_tgt:`C_STANDARD` or :prop_tgt:`CXX_STANDARD`
target property of the generated project.
``<LANG>_STANDARD_REQUIRED <bool>``
Specify the :prop_tgt:`C_STANDARD_REQUIRED` or
:prop_tgt:`CXX_STANDARD_REQUIRED` target property of the generated project.
``<LANG>_EXTENSIONS <bool>``
Specify the :prop_tgt:`C_EXTENSIONS` or :prop_tgt:`CXX_EXTENSIONS`
target property of the generated project.
In this version all files in ``<bindir>/CMakeFiles/CMakeTmp`` will be
cleaned automatically. For debugging, ``--debug-trycompile`` can be
passed to ``cmake`` to avoid this clean. However, multiple sequential
......@@ -119,3 +135,17 @@ the type of target used for the source file signature.
Set the :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable to specify
variables that must be propagated into the test project. This variable is
meant for use only in toolchain files.
If :policy:`CMP0067` is set to ``NEW``, or any of the ``<LANG>_STANDARD``,
``<LANG>_STANDARD_REQUIRED``, or ``<LANG>_EXTENSIONS`` options are used,
then the language standard variables are honored:
* :variable:`CMAKE_C_STANDARD`
* :variable:`CMAKE_C_STANDARD_REQUIRED`
* :variable:`CMAKE_C_EXTENSIONS`
* :variable:`CMAKE_CXX_STANDARD`
* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
* :variable:`CMAKE_CXX_EXTENSIONS`
Their values are used to set the corresponding target properties in
the generated project (unless overridden by an explicit option).
......@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
Policies Introduced by CMake 3.8
================================
.. toctree::
:maxdepth: 1
CMP0067: Honor language standard in try_compile() source-file signature. </policy/CMP0067>
Policies Introduced by CMake 3.7
================================
......
CMP0067
-------
Honor language standard in :command:`try_compile` source-file signature.
The :command:`try_compile` source file signature is intended to allow
callers to check whether they will be able to compile a given source file
with the current toolchain. In order to match compiler behavior, any
language standard mode should match. However, CMake 3.7 and below did not
do this. CMake 3.8 and above prefer to honor the language standard settings
for ``C`` and ``CXX`` (C++) using the values of the variables:
* :variable:`CMAKE_C_STANDARD`
* :variable:`CMAKE_C_STANDARD_REQUIRED`
* :variable:`CMAKE_C_EXTENSIONS`
* :variable:`CMAKE_CXX_STANDARD`
* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
* :variable:`CMAKE_CXX_EXTENSIONS`
This policy provides compatibility for projects that do not expect
the language standard settings to be used automatically.
The ``OLD`` behavior of this policy is to ignore language standard
setting variables when generating the ``try_compile`` test project.
The ``NEW`` behavior of this policy is to honor language standard
setting variables.
This policy was introduced in CMake version 3.8. Unlike most policies,
CMake version |release| does *not* warn by default when this policy
is not set and simply uses OLD behavior. See documentation of the
:variable:`CMAKE_POLICY_WARNING_CMP0067 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
variable to control the warning.
.. include:: DEPRECATED.txt
try_compile-lang-std
--------------------
* The :command:`try_compile` command source file signature gained new options
to specify the language standard to use in the generated test project.
* The :command:`try_compile` command source file signature now honors
language standard variables like :variable:`CMAKE_CXX_STANDARD`.
See policy :policy:`CMP0067`.
......@@ -17,6 +17,8 @@ warn by default:
policy :policy:`CMP0065`.
* ``CMAKE_POLICY_WARNING_CMP0066`` controls the warning for
policy :policy:`CMP0066`.
* ``CMAKE_POLICY_WARNING_CMP0067`` controls the warning for
policy :policy:`CMP0067`.
This variable should not be set by a project in CMake code. Project
developers running CMake may set this variable in their cache to
......
......@@ -46,6 +46,25 @@ static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
static void writeProperty(FILE* fout, std::string const& targetName,
std::string const& prop, std::string const& value)
{
fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
cmOutputConverter::EscapeForCMake(prop).c_str(),
cmOutputConverter::EscapeForCMake(value).c_str());
}
std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
bool warnCMP0067)
{
std::string value = this->Makefile->GetSafeDefinition(var);
if (warnCMP0067 && !value.empty()) {
value.clear();
this->WarnCMP0067.push_back(var);
}
return value;
}
int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool isTryRun)
{
......@@ -87,6 +106,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string outputVariable;
std::string copyFile;
std::string copyFileError;
std::string cStandard;
std::string cxxStandard;
std::string cStandardRequired;
std::string cxxStandardRequired;
std::string cExtensions;
std::string cxxExtensions;
std::vector<std::string> targets;
std::string libsToLink = " ";
bool useOldLinkLibs = true;
......@@ -94,6 +119,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool didOutputVariable = false;
bool didCopyFile = false;
bool didCopyFileError = false;
bool didCStandard = false;
bool didCxxStandard = false;
bool didCStandardRequired = false;
bool didCxxStandardRequired = false;
bool didCExtensions = false;
bool didCxxExtensions = false;
bool useSources = argv[2] == "SOURCES";
std::vector<std::string> sources;
......@@ -106,6 +137,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
DoingOutputVariable,
DoingCopyFile,
DoingCopyFileError,
DoingCStandard,
DoingCxxStandard,
DoingCStandardRequired,
DoingCxxStandardRequired,
DoingCExtensions,
DoingCxxExtensions,
DoingSources
};
Doing doing = useSources ? DoingSources : DoingNone;
......@@ -126,6 +163,24 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "COPY_FILE_ERROR") {
doing = DoingCopyFileError;
didCopyFileError = true;
} else if (argv[i] == "C_STANDARD") {
doing = DoingCStandard;
didCStandard = true;
} else if (argv[i] == "CXX_STANDARD") {
doing = DoingCxxStandard;
didCxxStandard = true;
} else if (argv[i] == "C_STANDARD_REQUIRED") {
doing = DoingCStandardRequired;
didCStandardRequired = true;
} else if (argv[i] == "CXX_STANDARD_REQUIRED") {
doing = DoingCxxStandardRequired;
didCxxStandardRequired = true;
} else if (argv[i] == "C_EXTENSIONS") {
doing = DoingCExtensions;
didCExtensions = true;
} else if (argv[i] == "CXX_EXTENSIONS") {
doing = DoingCxxExtensions;
didCxxExtensions = true;
} else if (doing == DoingCMakeFlags) {
cmakeFlags.push_back(argv[i]);
} else if (doing == DoingCompileDefinitions) {
......@@ -166,6 +221,24 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCopyFileError) {
copyFileError = argv[i];
doing = DoingNone;
} else if (doing == DoingCStandard) {
cStandard = argv[i];
doing = DoingNone;
} else if (doing == DoingCxxStandard) {
cxxStandard = argv[i];
doing = DoingNone;
} else if (doing == DoingCStandardRequired) {
cStandardRequired = argv[i];
doing = DoingNone;
} else if (doing == DoingCxxStandardRequired) {
cxxStandardRequired = argv[i];
doing = DoingNone;
} else if (doing == DoingCExtensions) {
cExtensions = argv[i];
doing = DoingNone;
} else if (doing == DoingCxxExtensions) {
cxxExtensions = argv[i];
doing = DoingNone;
} else if (doing == DoingSources) {
sources.push_back(argv[i]);
} else if (i == 3) {
......@@ -213,6 +286,42 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
return -1;
}
if (didCStandard && !this->SrcFileSignature) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR, "C_STANDARD allowed only in source file signature.");
return -1;
}
if (didCxxStandard && !this->SrcFileSignature) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
"CXX_STANDARD allowed only in source file signature.");
return -1;
}
if (didCStandardRequired && !this->SrcFileSignature) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
"C_STANDARD_REQUIRED allowed only in source file signature.");
return -1;
}
if (didCxxStandardRequired && !this->SrcFileSignature) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
"CXX_STANDARD_REQUIRED allowed only in source file signature.");
return -1;
}
if (didCExtensions && !this->SrcFileSignature) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
"C_EXTENSIONS allowed only in source file signature.");
return -1;
}
if (didCxxExtensions && !this->SrcFileSignature) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
"CXX_EXTENSIONS allowed only in source file signature.");
return -1;
}
// compute the binary dir when TRY_COMPILE is called with a src file
// signature
if (this->SrcFileSignature) {
......@@ -518,6 +627,104 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
fprintf(fout, ")\n");
bool const testC = testLangs.find("C") != testLangs.end();
bool const testCxx = testLangs.find("CXX") != testLangs.end();
bool warnCMP0067 = false;
bool honorStandard = true;
if (!didCStandard && !didCxxStandard && !didCStandardRequired &&
!didCxxStandardRequired && !didCExtensions && !didCxxExtensions) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
case cmPolicies::WARN:
warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
"CMAKE_POLICY_WARNING_CMP0067");
case cmPolicies::OLD:
// OLD behavior is to not honor the language standard variables.
honorStandard = false;
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0067));
case cmPolicies::NEW:
// NEW behavior is to honor the language standard variables.
// We already initialized honorStandard to true.
break;
}
}
if (honorStandard || warnCMP0067) {
if (testC) {
if (!didCStandard) {
cStandard = this->LookupStdVar("CMAKE_C_STANDARD", warnCMP0067);
}
if (!didCStandardRequired) {
cStandardRequired =
this->LookupStdVar("CMAKE_C_STANDARD_REQUIRED", warnCMP0067);
}
if (!didCExtensions) {
cExtensions = this->LookupStdVar("CMAKE_C_EXTENSIONS", warnCMP0067);
}
}
if (testCxx) {
if (!didCxxStandard) {
cxxStandard = this->LookupStdVar("CMAKE_CXX_STANDARD", warnCMP0067);
}
if (!didCxxStandardRequired) {
cxxStandardRequired =
this->LookupStdVar("CMAKE_CXX_STANDARD_REQUIRED", warnCMP0067);
}
if (!didCxxExtensions) {
cxxExtensions =
this->LookupStdVar("CMAKE_CXX_EXTENSIONS", warnCMP0067);
}
}
}
if (!this->WarnCMP0067.empty()) {
std::ostringstream w;
/* clang-format off */
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
"For compatibility with older versions of CMake, try_compile "
"is not honoring language standard variables in the test project:\n"
;
/* clang-format on */
for (std::vector<std::string>::iterator vi = this->WarnCMP0067.begin();
vi != this->WarnCMP0067.end(); ++vi) {
w << " " << *vi << "\n";
}
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
if (testC) {
if (!cStandard.empty()) {
writeProperty(fout, targetName, "C_STANDARD", cStandard);
}
if (!cStandardRequired.empty()) {
writeProperty(fout, targetName, "C_STANDARD_REQUIRED",
cStandardRequired);
}
if (!cExtensions.empty()) {
writeProperty(fout, targetName, "C_EXTENSIONS", cExtensions);
}
}
if (testCxx) {
if (!cxxStandard.empty()) {
writeProperty(fout, targetName, "CXX_STANDARD", cxxStandard);
}
if (!cxxStandardRequired.empty()) {
writeProperty(fout, targetName, "CXX_STANDARD_REQUIRED",
cxxStandardRequired);
}
if (!cxxExtensions.empty()) {
writeProperty(fout, targetName, "CXX_EXTENSIONS", cxxExtensions);
}
}
if (useOldLinkLibs) {
fprintf(fout, "target_link_libraries(%s ${LINK_LIBRARIES})\n",
targetName.c_str());
......
......@@ -47,6 +47,10 @@ protected:
std::string OutputFile;
std::string FindErrorMessage;
bool SrcFileSignature;
private:
std::vector<std::string> WarnCMP0067;
std::string LookupStdVar(std::string const& var, bool warnCMP0067);
};
#endif
......@@ -3158,8 +3158,10 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cmGlobalGenerator* gg =
cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
if (!gg) {
cmSystemTools::Error(
"Internal CMake error, TryCompile bad GlobalGenerator");
this->IssueMessage(cmake::INTERNAL_ERROR, "Global generator '" +
this->GetGlobalGenerator()->GetName() +
"' could not be created.");
cmSystemTools::SetFatalErrorOccured();
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
......@@ -3222,8 +3224,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cmStateEnums::INTERNAL);
}
if (cm.Configure() != 0) {
cmSystemTools::Error(
"Internal CMake error, TryCompile configure of cmake failed");
this->IssueMessage(cmake::FATAL_ERROR,
"Failed to configure test project build system.");
cmSystemTools::SetFatalErrorOccured();
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
......@@ -3231,8 +3234,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
}
if (cm.Generate() != 0) {
cmSystemTools::Error(
"Internal CMake error, TryCompile generation of cmake failed");
this->IssueMessage(cmake::FATAL_ERROR,
"Failed to generate test project build system.");
cmSystemTools::SetFatalErrorOccured();
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
this->IsSourceFileTryCompile = false;
......
......@@ -197,7 +197,10 @@ class cmMakefile;
3, 4, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0066, \
"Honor per-config flags in try_compile() source-file signature.", 3, \
7, 0, cmPolicies::WARN)
7, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0067, \
"Honor language standard in try_compile() source-file signature.", \
3, 8, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
......
......@@ -215,6 +215,18 @@ add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES})
add_RunCMake_test(return)
add_RunCMake_test(set_property)
add_RunCMake_test(string)
foreach(var
CMAKE_C_COMPILER_ID
CMAKE_C_COMPILER_VERSION
CMAKE_C_STANDARD_DEFAULT
CMAKE_CXX_COMPILER_ID
CMAKE_CXX_COMPILER_VERSION
CMAKE_CXX_STANDARD_DEFAULT
)
if(DEFINED ${var})
list(APPEND try_compile_ARGS -D${var}=${${var}})
endif()
endforeach()
add_RunCMake_test(try_compile)
add_RunCMake_test(try_run)
add_RunCMake_test(set)
......
before try_compile with CMP0067 WARN-enabled but no variables
after try_compile with CMP0067 WARN-enabled but no variables
before try_compile with CMP0067 WARN-default
after try_compile with CMP0067 WARN-default
before try_compile with CMP0067 WARN-enabled
CMake Warning \(dev\) at CMP0067.cmake:[0-9]+ \(try_compile\):
Policy CMP0067 is not set: Honor language standard in try_compile\(\)
source-file signature. Run "cmake --help-policy CMP0067" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
For compatibility with older versions of CMake, try_compile is not honoring
language standard variables in the test project:
CMAKE_C_STANDARD
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
after try_compile with CMP0067 WARN-enabled
before try_compile with CMP0067 OLD
after try_compile with CMP0067 OLD
before try_compile with CMP0067 NEW
after try_compile with CMP0067 NEW
enable_language(C)
set(CMAKE_POLICY_WARNING_CMP0067 ON)
message("before try_compile with CMP0067 WARN-enabled but no variables")
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src.c
)
message("after try_compile with CMP0067 WARN-enabled but no variables")
set(CMAKE_POLICY_WARNING_CMP0067 OFF)
#-----------------------------------------------------------------------------
set(CMAKE_C_STANDARD 90)
message("before try_compile with CMP0067 WARN-default")
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src.c
)
message("after try_compile with CMP0067 WARN-default")
set(CMAKE_POLICY_WARNING_CMP0067 ON)
message("before try_compile with CMP0067 WARN-enabled")
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src.c
)
message("after try_compile with CMP0067 WARN-enabled")
cmake_policy(SET CMP0067 OLD)
message("before try_compile with CMP0067 OLD")
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src.c
)
message("after try_compile with CMP0067 OLD")
cmake_policy(SET CMP0066 NEW)
message("before try_compile with CMP0067 NEW")
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src.c
)
message("after try_compile with CMP0067 NEW")
^CMake Error at .*/Tests/RunCMake/try_compile/CStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
C_STANDARD is set to invalid value '3'
+
CMake Error at CStandard.cmake:[0-9]+ \(try_compile\):
Failed to generate test project build system.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
enable_language(C)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
C_STANDARD 3
OUTPUT_VARIABLE out
)
message("try_compile output:\n${out}")
#if __STDC_VERSION__ != 199901L
#error "Not GNU C 99 mode!"
#endif
#ifndef __STRICT_ANSI__
#error "Not GNU C strict ANSI!"
#endif
int main(void)
{
return 0;
}
enable_language(C)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
C_STANDARD 99
C_STANDARD_REQUIRED 1
C_EXTENSIONS 0
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
cmake_policy(SET CMP0067 NEW)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED 1)
set(CMAKE_C_EXTENSIONS 0)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
enable_language(C)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
C_STANDARD 3 # bogus, but not used
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
^CMake Error at .*/Tests/RunCMake/try_compile/CxxStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
CXX_STANDARD is set to invalid value '3'
+
CMake Error at CxxStandard.cmake:[0-9]+ \(try_compile\):
Failed to generate test project build system.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
enable_language(CXX)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
CXX_STANDARD 3
OUTPUT_VARIABLE out
)
message("try_compile output:\n${out}")
enable_language(CXX)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
CXX_STANDARD 11
CXX_STANDARD_REQUIRED 1
CXX_EXTENSIONS 0
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
cmake_policy(SET CMP0067 NEW)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED 1)
set(CMAKE_CXX_EXTENSIONS 0)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
#if __cplusplus != 201103L && \
!(__cplusplus < 201103L && defined(__GXX_EXPERIMENTAL_CXX0X__))
#error "Not GNU C++ 11 mode!"
#endif
#ifndef __STRICT_ANSI__
#error "Not GNU C++ strict ANSI!"
#endif
int main()
{
return 0;
}
enable_language(CXX)
try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
CXX_STANDARD 3 # bogus, but not used
OUTPUT_VARIABLE out
)
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
......@@ -25,8 +25,26 @@ run_cmake(TargetTypeExe)
run_cmake(TargetTypeInvalid)
run_cmake(TargetTypeStatic)
if(CMAKE_C_STANDARD_DEFAULT)
run_cmake(CStandard)
elseif(DEFINED CMAKE_C_STANDARD_DEFAULT)
run_cmake(CStandardNoDefault)
endif()
if(CMAKE_CXX_STANDARD_DEFAULT)
run_cmake(CxxStandard)
elseif(DEFINED CMAKE_CXX_STANDARD_DEFAULT)
run_cmake(CxxStandardNoDefault)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
run_cmake(CStandardGNU)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
run_cmake(CxxStandardGNU)
endif()
run_cmake(CMP0056)
run_cmake(CMP0066)
run_cmake(CMP0067)
if(RunCMake_GENERATOR MATCHES "Make|Ninja")
# Use a single build tree for a few tests without cleaning.
......
int main()
{
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment