Merge topic 'cuda-mixed-cxx-standard'

4b7618d1 CUDA: Fix CUDA_STANDARD selection via cxx_std_11 with CXX_STANDARD
1d2d9c18 cmMakefile: Refactor determining a targets C++ standard level

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1590
This commit is contained in:
Brad King
2017-12-20 12:59:13 +00:00
committed by Kitware Robot
4 changed files with 84 additions and 70 deletions
+59 -70
View File
@@ -4401,8 +4401,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
existingCxxStandard = defaultCxxStandard;
}
if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard)) == cm::cend(CXX_STANDARDS)) {
const char* const* existingCxxLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
std::ostringstream e;
e << "The CXX_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCxxStandard << "\".";
@@ -4410,32 +4412,16 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
return false;
}
const char* const* existingCxxIt = existingCxxStandard
? std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard))
: cm::cend(CXX_STANDARDS);
/* clang-format off */
const char* const* needCxxLevel =
needCxx17 ? &CXX_STANDARDS[3]
: needCxx14 ? &CXX_STANDARDS[2]
: needCxx11 ? &CXX_STANDARDS[1]
: needCxx98 ? &CXX_STANDARDS[0]
: nullptr;
/* clang-format on */
if (needCxx17 &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS), cmStrCmp("17"))) {
return false;
}
if (needCxx14 &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS), cmStrCmp("14"))) {
return false;
}
if (needCxx11 &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS), cmStrCmp("11"))) {
return false;
}
if (needCxx98 &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS), cmStrCmp("98"))) {
return false;
}
return true;
return !needCxxLevel || needCxxLevel <= existingCxxLevel;
}
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
@@ -4481,10 +4467,12 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
needCxx17);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
const char* const* existingCxxLevel = nullptr;
if (existingCxxStandard) {
if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard)) ==
cm::cend(CXX_STANDARDS)) {
existingCxxLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
std::ostringstream e;
e << "The CXX_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCxxStandard << "\".";
@@ -4497,50 +4485,51 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
return false;
}
}
const char* const* existingCxxIt = existingCxxStandard
? std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard))
: cm::cend(CXX_STANDARDS);
bool setCxx98 = needCxx98 && !existingCxxStandard;
bool setCxx11 = needCxx11 && !existingCxxStandard;
bool setCxx14 = needCxx14 && !existingCxxStandard;
bool setCxx17 = needCxx17 && !existingCxxStandard;
if (needCxx17 && existingCxxStandard &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS), cmStrCmp("17"))) {
setCxx17 = true;
} else if (needCxx14 && existingCxxStandard &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS),
cmStrCmp("14"))) {
setCxx14 = true;
} else if (needCxx11 && existingCxxStandard &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS),
cmStrCmp("11"))) {
setCxx11 = true;
} else if (needCxx98 && existingCxxStandard &&
existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
cm::cend(CXX_STANDARDS),
cmStrCmp("98"))) {
setCxx98 = true;
const char* existingCudaStandard = target->GetProperty("CUDA_STANDARD");
const char* const* existingCudaLevel = nullptr;
if (existingCudaStandard) {
existingCudaLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCudaStandard));
if (existingCudaLevel == cm::cend(CXX_STANDARDS)) {
std::ostringstream e;
e << "The CUDA_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCudaStandard
<< "\".";
if (error) {
*error = e.str();
} else {
this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, e.str(),
this->Backtrace);
}
return false;
}
}
if (setCxx17) {
target->SetProperty("CXX_STANDARD", "17");
target->SetProperty("CUDA_STANDARD", "17");
} else if (setCxx14) {
target->SetProperty("CXX_STANDARD", "14");
target->SetProperty("CUDA_STANDARD", "14");
} else if (setCxx11) {
target->SetProperty("CXX_STANDARD", "11");
target->SetProperty("CUDA_STANDARD", "11");
} else if (setCxx98) {
target->SetProperty("CXX_STANDARD", "98");
target->SetProperty("CUDA_STANDARD", "98");
/* clang-format off */
const char* const* needCxxLevel =
needCxx17 ? &CXX_STANDARDS[3]
: needCxx14 ? &CXX_STANDARDS[2]
: needCxx11 ? &CXX_STANDARDS[1]
: needCxx98 ? &CXX_STANDARDS[0]
: nullptr;
/* clang-format on */
if (needCxxLevel) {
// Ensure the C++ language level is high enough to support
// the needed C++ features.
if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
target->SetProperty("CXX_STANDARD", *needCxxLevel);
}
// Ensure the CUDA language level is high enough to support
// the needed C++ features.
if (!existingCudaLevel || existingCudaLevel < needCxxLevel) {
target->SetProperty("CUDA_STANDARD", *needCxxLevel);
}
}
return true;
}
+1
View File
@@ -2,6 +2,7 @@
ADD_TEST_MACRO(Cuda.Complex CudaComplex)
ADD_TEST_MACRO(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures)
ADD_TEST_MACRO(Cuda.ObjectLibrary CudaObjectLibrary)
ADD_TEST_MACRO(Cuda.MixedStandardLevels MixedStandardLevels)
ADD_TEST_MACRO(Cuda.ToolkitInclude CudaToolkitInclude)
ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags)
ADD_TEST_MACRO(Cuda.WithC CudaWithC)
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.7)
project(CudaComplex CXX CUDA)
string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
set(CMAKE_CXX_STANDARD 11)
add_executable(MixedStandardLevels main.cu)
target_compile_features(MixedStandardLevels PUBLIC cxx_std_11)
if(APPLE)
# Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
set_property(TARGET MixedStandardLevels PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
endif()
+10
View File
@@ -0,0 +1,10 @@
#include <type_traits>
int main(int argc, char** argv)
{
// Verify that issue #17519 Setting CXX_STANDARD breaks CUDA_STANDARD
// selection via cxx_std_11 has been corrected
using returnv = std::integral_constant<int, 0>;
return returnv::value;
}