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
This commit is contained in:
Brad King 2023-11-22 10:03:58 -05:00
parent 5c77facd78
commit 43d218d970
18 changed files with 105 additions and 2 deletions

View File

@ -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

View File

@ -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`.

View File

@ -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=<compiler>``
.. 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=<arch>``
Specify the host tools architecture as ``x64`` or ``x86``.
Supported by VS 2013 and above.

View File

@ -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.

View File

@ -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)

View File

@ -13,7 +13,7 @@
Name="Debug|@id_platform@"
OutputDirectory="."
IntermediateDirectory="$(ConfigurationName)"
>
@id_UseCompiler@>
<Tool
Name="VFFortranCompilerTool"
DebugInformationFormat="debugEnabled"

View File

@ -191,6 +191,23 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
}
}
if (this->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<std::string> 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;

View File

@ -93,6 +93,12 @@ public:
* directory */
std::string const& GetPlatformToolsetCudaVSIntegrationSubdirString() const;
/** The fortran toolset name. */
cm::optional<std::string> 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<std::string> GeneratorToolsetFortran;
std::string DefaultPlatformToolset;
std::string DefaultPlatformToolsetHostArchitecture;
std::string DefaultAndroidToolset;

View File

@ -10,6 +10,8 @@
#include <utility>
#include <vector>
#include <cm/optional>
#include <cm3p/json/value.h>
#include "cmGlobalVisualStudioGenerator.h"
@ -102,6 +104,10 @@ public:
}
const std::string& GetIntelProjectVersion();
virtual cm::optional<std::string> GetPlatformToolsetFortran() const
{
return cm::nullopt;
}
bool FindMakeProgram(cmMakefile* mf) override;

View File

@ -795,6 +795,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
target->GetType() == cmStateEnums::OBJECT_LIBRARY
? ".lib"
: cmSystemTools::GetFilenameLastExtension(targetNameFull);
if (cm::optional<std::string> fortran = gg->GetPlatformToolsetFortran()) {
fout << "\t\t\tUseCompiler=\"" << *fortran << "Compiler\"\n";
}
/* clang-format off */
fout <<
"\t\t\tTargetName=\"" << this->EscapeForXML(targetName) << "\"\n"

View File

@ -0,0 +1 @@
1

View File

@ -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"\.

View File

@ -0,0 +1 @@
message(FATAL_ERROR "This should not be reached!")

View File

@ -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)

View File

@ -0,0 +1 @@
-- CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='ifort'

View File

@ -0,0 +1 @@
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='${CMAKE_VS_PLATFORM_TOOLSET_FORTRAN}'")

View File

@ -0,0 +1 @@
-- CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='ifx'

View File

@ -0,0 +1 @@
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_FORTRAN='${CMAKE_VS_PLATFORM_TOOLSET_FORTRAN}'")