From 43d218d970665245692b8f8a1163a42ee9ee186d Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 22 Nov 2023 10:03:58 -0500 Subject: VS: Add support for using Intel oneAPI Fortran compiler in .vfproj files Add a `fortran={ifort,ifx}` field to `CMAKE_GENERATOR_TOOLSET` to specify which Intel Fortran compiler to use. Fixes: #25427 --- Help/manual/cmake-variables.7.rst | 1 + Help/release/dev/vs-ifx.rst | 7 +++++++ Help/variable/CMAKE_GENERATOR_TOOLSET.rst | 14 +++++++++++++ .../variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst | 12 +++++++++++ Modules/CMakeDetermineCompilerId.cmake | 8 +++++++- Modules/CompilerId/VS-Intel.vfproj.in | 2 +- Source/cmGlobalVisualStudio10Generator.cxx | 24 ++++++++++++++++++++++ Source/cmGlobalVisualStudio10Generator.h | 7 +++++++ Source/cmGlobalVisualStudio7Generator.h | 6 ++++++ Source/cmLocalVisualStudio7Generator.cxx | 3 +++ .../GeneratorToolset/BadToolsetFortran-result.txt | 1 + .../GeneratorToolset/BadToolsetFortran-stderr.txt | 11 ++++++++++ .../GeneratorToolset/BadToolsetFortran.cmake | 1 + Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake | 6 ++++++ .../TestToolsetFortranIFORT-stdout.txt | 1 + .../GeneratorToolset/TestToolsetFortranIFORT.cmake | 1 + .../TestToolsetFortranIFX-stdout.txt | 1 + .../GeneratorToolset/TestToolsetFortranIFX.cmake | 1 + 18 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 Help/release/dev/vs-ifx.rst create mode 100644 Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst create mode 100644 Tests/RunCMake/GeneratorToolset/BadToolsetFortran-result.txt create mode 100644 Tests/RunCMake/GeneratorToolset/BadToolsetFortran-stderr.txt create mode 100644 Tests/RunCMake/GeneratorToolset/BadToolsetFortran.cmake create mode 100644 Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT-stdout.txt create mode 100644 Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT.cmake create mode 100644 Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX-stdout.txt create mode 100644 Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX.cmake diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 35b57a5..c2e826c 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -131,6 +131,7 @@ Variables that Provide Information /variable/CMAKE_VS_PLATFORM_TOOLSET /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR + /variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN /variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE /variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION /variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER diff --git a/Help/release/dev/vs-ifx.rst b/Help/release/dev/vs-ifx.rst new file mode 100644 index 0000000..9e72cc7 --- /dev/null +++ b/Help/release/dev/vs-ifx.rst @@ -0,0 +1,7 @@ +vs-ifx +------ + +* :ref:`Visual Studio Generators` now support selecting between the + Intel oneAPI Fortran compiler (``ifx``) and the Intel classic Fortran + compiler (``ifort``) using a ``fortran=`` field in + :variable:`CMAKE_GENERATOR_TOOLSET`. diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst index 4855477..b83fa01 100644 --- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst +++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst @@ -48,6 +48,20 @@ Supported pairs are: See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA` and :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR` variables. +``fortran=`` + .. versionadded:: 3.29 + + Specify the Fortran compiler to use, among those that integrate with VS. + The value may be one of: + + ``ifort`` + Intel classic Fortran compiler. + + ``ifx`` + Intel oneAPI Fortran compiler. + + See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_FORTRAN` variable. + ``host=`` Specify the host tools architecture as ``x64`` or ``x86``. Supported by VS 2013 and above. diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst new file mode 100644 index 0000000..e0ecb12 --- /dev/null +++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst @@ -0,0 +1,12 @@ +CMAKE_VS_PLATFORM_TOOLSET_FORTRAN +--------------------------------- + +.. versionadded:: 3.29 + +Fortran compiler to be used by Visual Studio projects. + +:ref:`Visual Studio Generators` support selecting among Fortran compilers +whose Visual Studio Integration is installed. The compiler may be specified +by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of the form ``fortran=...``. +CMake provides the selected Fortran compiler in this variable. +The value may be empty if the field was not specified. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 4f1eaba..ffba1cb 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -402,7 +402,13 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} elseif(lang STREQUAL Fortran) set(v Intel) set(ext vfproj) - set(id_cl ifort.exe) + if(CMAKE_VS_PLATFORM_TOOLSET_FORTRAN) + set(id_cl "${CMAKE_VS_PLATFORM_TOOLSET_FORTRAN}.exe") + set(id_UseCompiler "UseCompiler=\"${CMAKE_VS_PLATFORM_TOOLSET_FORTRAN}Compiler\"") + else() + set(id_cl ifort.exe) + set(id_UseCompiler "") + endif() elseif(lang STREQUAL CSharp) set(v 10) set(ext csproj) diff --git a/Modules/CompilerId/VS-Intel.vfproj.in b/Modules/CompilerId/VS-Intel.vfproj.in index 044dd20..fdd9d9d 100644 --- a/Modules/CompilerId/VS-Intel.vfproj.in +++ b/Modules/CompilerId/VS-Intel.vfproj.in @@ -13,7 +13,7 @@ Name="Debug|@id_platform@" OutputDirectory="." IntermediateDirectory="$(ConfigurationName)" - > + @id_UseCompiler@> GeneratorToolsetFortran) { + if (*this->GeneratorToolsetFortran != "ifx" && + *this->GeneratorToolsetFortran != "ifort") { + mf->IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("Generator\n" + " ", + this->GetName(), + "\n" + "given toolset\n" + " fortran=", + *this->GeneratorToolsetFortran, + "\n" + "but the value is not \"ifx\" or \"ifort\".")); + this->GeneratorToolsetFortran = cm::nullopt; + } + } + if (!this->GeneratorToolsetVersion.empty() && this->GeneratorToolsetVersion != "Test Toolset Version"_s) { // If a specific minor version of the MSVC toolset is requested, verify @@ -300,6 +317,9 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) { mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir); } + if (cm::optional fortran = this->GetPlatformToolsetFortran()) { + mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_FORTRAN", *fortran); + } if (const char* vcTargetsDir = this->GetCustomVCTargetsPath()) { mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR", vcTargetsDir); @@ -410,6 +430,10 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField( cmSystemTools::ConvertToUnixSlashes(this->CustomFlagTableDir); return true; } + if (key == "fortran"_s) { + this->GeneratorToolsetFortran = value; + return true; + } if (key == "version"_s) { this->GeneratorToolsetVersion = value; return true; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 40bdd71..a2b351c 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -93,6 +93,12 @@ public: * directory */ std::string const& GetPlatformToolsetCudaVSIntegrationSubdirString() const; + /** The fortran toolset name. */ + cm::optional GetPlatformToolsetFortran() const override + { + return this->GeneratorToolsetFortran; + } + /** Return whether we need to use No/Debug instead of false/true for GenerateDebugInformation. */ bool GetPlatformToolsetNeedsDebugEnum() const @@ -221,6 +227,7 @@ protected: std::string GeneratorToolsetCudaCustomDir; std::string GeneratorToolsetCudaNvccSubdir; std::string GeneratorToolsetCudaVSIntegrationSubdir; + cm::optional GeneratorToolsetFortran; std::string DefaultPlatformToolset; std::string DefaultPlatformToolsetHostArchitecture; std::string DefaultAndroidToolset; diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 6f6109e..2056b2f 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -10,6 +10,8 @@ #include #include +#include + #include #include "cmGlobalVisualStudioGenerator.h" @@ -102,6 +104,10 @@ public: } const std::string& GetIntelProjectVersion(); + virtual cm::optional GetPlatformToolsetFortran() const + { + return cm::nullopt; + } bool FindMakeProgram(cmMakefile* mf) override; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 3f3779a..d315f0f 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -795,6 +795,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( target->GetType() == cmStateEnums::OBJECT_LIBRARY ? ".lib" : cmSystemTools::GetFilenameLastExtension(targetNameFull); + if (cm::optional fortran = gg->GetPlatformToolsetFortran()) { + fout << "\t\t\tUseCompiler=\"" << *fortran << "Compiler\"\n"; + } /* clang-format off */ fout << "\t\t\tTargetName=\"" << this->EscapeForXML(targetName) << "\"\n" diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetFortran-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetFortran-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetFortran-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetFortran-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetFortran-stderr.txt new file mode 100644 index 0000000..acb13da --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetFortran-stderr.txt @@ -0,0 +1,11 @@ +CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + [^ +]* + + given toolset + + fortran=bad + + but the value is not "ifx" or "ifort"\. diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetFortran.cmake b/Tests/RunCMake/GeneratorToolset/BadToolsetFortran.cmake new file mode 100644 index 0000000..2fc38e5 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetFortran.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake index 71cc2d4..b86c481 100644 --- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake @@ -43,6 +43,12 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[0124567]") set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=does_not_exist") run_cmake(BadToolsetCustomFlagTableDir) endif() + set(RunCMake_GENERATOR_TOOLSET "fortran=ifort") + run_cmake(TestToolsetFortranIFORT) + set(RunCMake_GENERATOR_TOOLSET "fortran=ifx") + run_cmake(TestToolsetFortranIFX) + set(RunCMake_GENERATOR_TOOLSET "fortran=bad") + run_cmake(BadToolsetFortran) if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[24567]") set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64") run_cmake(TestToolsetHostArchBoth) diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT-stdout.txt new file mode 100644 index 0000000..9fa8c21 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT-stdout.txt @@ -0,0 +1 @@ +-- CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='ifort' diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT.cmake new file mode 100644 index 0000000..7f18fbc --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFORT.cmake @@ -0,0 +1 @@ +message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='${CMAKE_VS_PLATFORM_TOOLSET_FORTRAN}'") diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX-stdout.txt new file mode 100644 index 0000000..56a0c30 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX-stdout.txt @@ -0,0 +1 @@ +-- CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='ifx' diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX.cmake new file mode 100644 index 0000000..7f18fbc --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetFortranIFX.cmake @@ -0,0 +1 @@ +message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='${CMAKE_VS_PLATFORM_TOOLSET_FORTRAN}'") -- cgit v0.12