diff options
author | Michael Stürmer <michael.stuermer@schaeffler.com> | 2016-12-12 13:52:29 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-12-15 14:16:30 (GMT) |
commit | 5c6c0344d32f9282059d46b6fe6f9925ac1f1202 (patch) | |
tree | fc9ce79ea985322807b73cbcd30bcc5cff5ce24d /Modules | |
parent | 3874843f0f5be9d53001517b3697e0d092f0e845 (diff) | |
download | CMake-5c6c0344d32f9282059d46b6fe6f9925ac1f1202.zip CMake-5c6c0344d32f9282059d46b6fe6f9925ac1f1202.tar.gz CMake-5c6c0344d32f9282059d46b6fe6f9925ac1f1202.tar.bz2 |
C# support: add compiler detection for MSVC
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/CMakeCSharpCompiler.cmake.in | 9 | ||||
-rw-r--r-- | Modules/CMakeCSharpCompilerId.cs.in | 63 | ||||
-rw-r--r-- | Modules/CMakeCSharpInformation.cmake | 119 | ||||
-rw-r--r-- | Modules/CMakeCompilerIdDetection.cmake | 2 | ||||
-rw-r--r-- | Modules/CMakeDetermineCSharpCompiler.cmake | 43 | ||||
-rw-r--r-- | Modules/CMakeDetermineCompilerId.cmake | 10 | ||||
-rw-r--r-- | Modules/CMakeTestCSharpCompiler.cmake | 68 | ||||
-rw-r--r-- | Modules/CompilerId/VS-10.csproj.in | 55 |
8 files changed, 367 insertions, 2 deletions
diff --git a/Modules/CMakeCSharpCompiler.cmake.in b/Modules/CMakeCSharpCompiler.cmake.in new file mode 100644 index 0000000..5ecc480 --- /dev/null +++ b/Modules/CMakeCSharpCompiler.cmake.in @@ -0,0 +1,9 @@ +set(CMAKE_CSharp_COMPILER "@CMAKE_CSharp_COMPILER@") +set(CMAKE_CSharp_COMPILER_ID "@CMAKE_CSharp_COMPILER_ID@") +set(CMAKE_CSharp_COMPILER_VERSION "@CMAKE_CSharp_COMPILER_VERSION@") + +set(CMAKE_CSharp_COMPILER_WORKS "@CMAKE_CSharp_COMPILER_WORKS@") + +set(CMAKE_CSharp_COMPILER_ID_RUN "@CMAKE_CSharp_COMPILER_ID_RUN@") +set(CMAKE_CSharp_IGNORE_EXTENSIONS "inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC") +set(CMAKE_CSharp_SOURCE_FILE_EXTENSIONS "cs") diff --git a/Modules/CMakeCSharpCompilerId.cs.in b/Modules/CMakeCSharpCompilerId.cs.in new file mode 100644 index 0000000..987f63a --- /dev/null +++ b/Modules/CMakeCSharpCompilerId.cs.in @@ -0,0 +1,63 @@ +using System; + +namespace CSharp +{ + public class CSharpApp + { + const string InfoCompiler = "INFO:compiler[Microsoft " +#if PlatformToolsetv100 + + "Visual Studio" +#elif PlatformToolsetv110 + + "Visual Studio" +#elif PlatformToolsetv120 + + "Visual Studio" +#elif PlatformToolsetv140 + + "Visual Studio" +#elif PlatformToolsetv141 + + "Visual Studio" +#else + + "unknown" +#endif + + "]"; + + const string InfoPlatform = "INFO:platform[Windows]"; + + const string InfoArchitecture = "INFO:arch[" +#if Platformx64 + + "x64" +#elif Platformx86 + + "x86" +#elif PlatformxWin32 + + "Win32]" +#else + + "unknown" +#endif + + "]"; + + const string InfoCompilerVersion = "INFO:compiler_version[" +#if PlatformToolsetv100 + + "2010" +#elif PlatformToolsetv110 + + "2012" +#elif PlatformToolsetv120 + + "2013" +#elif PlatformToolsetv140 + + "2015" +#elif PlatformToolsetv141 + + "2017" +#else + + "9999" +#endif + + "]"; + + static void Main(string[] args) + { + // we have to print the lines to make sure + // the compiler does not optimize them away ... + System.Console.WriteLine(InfoCompiler); + System.Console.WriteLine(InfoPlatform); + System.Console.WriteLine(InfoArchitecture); + System.Console.WriteLine(InfoCompilerVersion); + } + } +} diff --git a/Modules/CMakeCSharpInformation.cmake b/Modules/CMakeCSharpInformation.cmake new file mode 100644 index 0000000..dc775bd --- /dev/null +++ b/Modules/CMakeCSharpInformation.cmake @@ -0,0 +1,119 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# This file sets the basic flags for the C# language in CMake. +# It also loads the available platform file for the system-compiler +# if it exists. + +set(CMAKE_BASE_NAME) +get_filename_component(CMAKE_BASE_NAME "${CMAKE_CSharp_COMPILER}" NAME_WE) + +set(CMAKE_BUILD_TYPE_INIT Debug) + +set(CMAKE_CSharp_FLAGS_INIT "/define:TRACE /langversion:3 /nowin32manifest") +set(CMAKE_CSharp_FLAGS_DEBUG_INIT "/debug:full /optimize- /warn:3 /errorreport:prompt /define:DEBUG") +set(CMAKE_CSharp_FLAGS_RELEASE_INIT "/debug:none /optimize /warn:1 /errorreport:queue") +set(CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT "/debug:full /optimize-") +set(CMAKE_CSharp_FLAGS_MINSIZEREL_INIT "/debug:none /optimize") +set(CMAKE_CSharp_LINKER_SUPPORTS_PDB ON) + +set(CMAKE_CSharp_STANDARD_LIBRARIES_INIT "System") + +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CMAKE_CSharp_FLAGS_INIT "/platform:x86 ${CMAKE_CSharp_FLAGS_INIT}") +else() + set(CMAKE_CSharp_FLAGS_INIT "/platform:x64 ${CMAKE_CSharp_FLAGS_INIT}") +endif() + +# This should be included before the _INIT variables are +# used to initialize the cache. Since the rule variables +# have if blocks on them, users can still define them here. +# But, it should still be after the platform file so changes can +# be made to those values. + +# for most systems a module is the same as a shared library +# so unless the variable CMAKE_MODULE_EXISTS is set just +# copy the values from the LIBRARY variables +if(NOT CMAKE_MODULE_EXISTS) + set(CMAKE_SHARED_MODULE_CSharp_FLAGS ${CMAKE_SHARED_LIBRARY_CSharp_FLAGS}) + set(CMAKE_SHARED_MODULE_CREATE_CSharp_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CSharp_FLAGS}) +endif() + +# add the flags to the cache based +# on the initial values computed in the platform/*.cmake files +# use _INIT variables so that this only happens the first time +# and you can set these flags in the cmake cache +set(CMAKE_CSharp_FLAGS_INIT "$ENV{CSharpFLAGS} ${CMAKE_CSharp_FLAGS_INIT}") +# avoid just having a space as the initial value for the cache +if(CMAKE_CSharp_FLAGS_INIT STREQUAL " ") + set(CMAKE_CSharp_FLAGS_INIT) +endif() +set (CMAKE_CSharp_FLAGS "${CMAKE_CSharp_FLAGS_INIT}" CACHE STRING + "Flags used by the C# compiler during all build types.") + +if(NOT CMAKE_NOT_USING_CONFIG_FLAGS) + set (CMAKE_CSharp_FLAGS_DEBUG "${CMAKE_CSharp_FLAGS_DEBUG_INIT}" CACHE STRING + "Flags used by the C# compiler during debug builds.") + set (CMAKE_CSharp_FLAGS_MINSIZEREL "${CMAKE_CSharp_FLAGS_MINSIZEREL_INIT}" CACHE STRING + "Flags used by the C# compiler during release builds for minimum size.") + set (CMAKE_CSharp_FLAGS_RELEASE "${CMAKE_CSharp_FLAGS_RELEASE_INIT}" CACHE STRING + "Flags used by the C# compiler during release builds.") + set (CMAKE_CSharp_FLAGS_RELWITHDEBINFO "${CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING + "Flags used by the C# compiler during release builds with debug info.") +endif() + +if(CMAKE_CSharp_STANDARD_LIBRARIES_INIT) + set(CMAKE_CSharp_STANDARD_LIBRARIES "${CMAKE_CSharp_STANDARD_LIBRARIES_INIT}" + CACHE STRING "Libraries linked by default with all C# applications.") + mark_as_advanced(CMAKE_CSharp_STANDARD_LIBRARIES) +endif() + +# set missing flags (if they do not exist). This is needed in the +# unlikely case that you have only C# and no C/C++ targets in your +# project. +if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS) + set(CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_DEBUG) + set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_RELEASE) + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL) + set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO) + set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "" CACHE STRING "" FORCE) +endif() + +if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS) + set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_DEBUG) + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_RELEASE) + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_MINSIZEREL) + set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "" CACHE STRING "" FORCE) +endif() +if(NOT EXISTS CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO) + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE STRING "" FORCE) +endif() + +set(CMAKE_CSharp_CREATE_SHARED_LIBRARY "CSharp_NO_CREATE_SHARED_LIBRARY") +set(CMAKE_CSharp_CREATE_SHARED_MODULE "CSharp_NO_CREATE_SHARED_MODULE") +set(CMAKE_CSharp_LINK_EXECUTABLE "CSharp_NO_LINK_EXECUTABLE") + +mark_as_advanced( + CMAKE_CSharp_FLAGS + CMAKE_CSharp_FLAGS_RELEASE + CMAKE_CSharp_FLAGS_RELWITHDEBINFO + CMAKE_CSharp_FLAGS_MINSIZEREL + CMAKE_CSharp_FLAGS_DEBUG + ) + +set(CMAKE_CSharp_USE_RESPONSE_FILE_FOR_OBJECTS 1) +set(CMAKE_CSharp_INFORMATION_LOADED 1) diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index 2881cb1..484e1f0 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -15,7 +15,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) function(compiler_id_detection outvar lang) - if (NOT lang STREQUAL Fortran) + if (NOT lang STREQUAL Fortran AND NOT lang STREQUAL CSharp) file(GLOB lang_files "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake") set(nonlang CXX) diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake new file mode 100644 index 0000000..1b8dd02 --- /dev/null +++ b/Modules/CMakeDetermineCSharpCompiler.cmake @@ -0,0 +1,43 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio ([^789]|[789][0-9])") + message(FATAL_ERROR + "C# is currently only supported for Microsoft Visual Studio 2010 and later.") +endif() + +include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) +#include(Platform/${CMAKE_SYSTEM_NAME}-Determine-CSharp OPTIONAL) +#include(Platform/${CMAKE_SYSTEM_NAME}-CSharp OPTIONAL) +if(NOT CMAKE_CSharp_COMPILER_NAMES) + set(CMAKE_CSharp_COMPILER_NAMES csc) +endif() + +# Build a small source file to identify the compiler. +if(NOT CMAKE_CSharp_COMPILER_ID_RUN) + set(CMAKE_CSharp_COMPILER_ID_RUN 1) + + # Try to identify the compiler. + set(CMAKE_CSharp_COMPILER_ID_STRINGS_PARAMETERS ENCODING UTF-16LE) + set(CMAKE_CSharp_COMPILER_ID) + include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) + CMAKE_DETERMINE_COMPILER_ID(CSharp CSFLAGS CMakeCSharpCompilerId.cs) + + execute_process(COMMAND "${CMAKE_CSharp_COMPILER}" "/help" OUTPUT_VARIABLE output) + string(REPLACE "\n" ";" output "${output}") + foreach(line ${output}) + string(TOUPPER ${line} line) + string(REGEX REPLACE "^.*COMPILER.*VERSION[^\\.0-9]*([\\.0-9]+).*$" "\\1" version "${line}") + if(version AND NOT "x${line}" STREQUAL "x${version}") + set(CMAKE_CSharp_COMPILER_VERSION ${version}) + break() + endif() + endforeach() + message(STATUS "The CSharp compiler version is ${CMAKE_CSharp_COMPILER_VERSION}") +endif() + +# configure variables set in this file for fast reload later on +configure_file(${CMAKE_ROOT}/Modules/CMakeCSharpCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeCSharpCompiler.cmake + @ONLY + ) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index c5a2bcb..eae139d 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -164,6 +164,10 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} set(v Intel) set(ext vfproj) set(id_cl ifort.exe) + elseif(lang STREQUAL CSharp) + set(v 10) + set(ext csproj) + set(id_cl csc.exe) elseif(NOT "${vs_version}" VERSION_LESS 10) set(v 10) set(ext vcxproj) @@ -447,8 +451,12 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(SIMULATE_ID) set(SIMULATE_VERSION) file(STRINGS ${file} - CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") + CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38 + ${CMAKE_${lang}_COMPILER_ID_STRINGS_PARAMETERS} + REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") set(COMPILER_ID_TWICE) + # In C# binaries, some strings are found more than once. + list(REMOVE_DUPLICATES CMAKE_${lang}_COMPILER_ID_STRINGS) foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS}) if("${info}" MATCHES "INFO:compiler\\[([^]\"]*)\\]") if(COMPILER_ID) diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake new file mode 100644 index 0000000..21b7236 --- /dev/null +++ b/Modules/CMakeTestCSharpCompiler.cmake @@ -0,0 +1,68 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +if(CMAKE_CSharp_COMPILER_FORCED) + # The compiler configuration was forced by the user. + # Assume the user has configured all compiler information. + set(CMAKE_CSharp_COMPILER_WORKS TRUE) + return() +endif() + +include(CMakeTestCompilerCommon) + +unset(CMAKE_CSharp_COMPILER_WORKS CACHE) + +set(test_compile_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCSharpCompiler.cs") + +# This file is used by EnableLanguage in cmGlobalGenerator to +# determine that that selected C# compiler can actually compile +# and link the most basic of programs. If not, a fatal error +# is set and cmake stops processing commands and will not generate +# any makefiles or projects. +if(NOT CMAKE_CSharp_COMPILER_WORKS) + PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER}") + file(WRITE "${test_compile_file}" + "namespace Test {" + " public class CSharp {" + " static void Main(string[] args) {}" + " }" + "}" + ) + try_compile(CMAKE_CSharp_COMPILER_WORKS ${CMAKE_BINARY_DIR} "${test_compile_file}" + OUTPUT_VARIABLE __CMAKE_CSharp_COMPILER_OUTPUT + ) + # Move result from cache to normal variable. + set(CMAKE_CSharp_COMPILER_WORKS ${CMAKE_CSharp_COMPILER_WORKS}) + unset(CMAKE_CSharp_COMPILER_WORKS CACHE) + if(NOT CMAKE_CSharp_COMPILER_WORKS) + message("forcing compiler works to true (will be removed once C# support is integrated)") + set(CMAKE_CSharp_COMPILER_WORKS 1) + endif() + set(CSharp_TEST_WAS_RUN 1) +endif() + +if(NOT CMAKE_CSharp_COMPILER_WORKS) + PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER} -- broken") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the C# compiler works failed with " + "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n") + message(FATAL_ERROR "The C# compiler \"${CMAKE_CSharp_COMPILER}\" " + "is not able to compile a simple test program.\nIt fails " + "with the following output:\n ${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n" + "CMake will not be able to correctly generate this project.") +else() + if(CSharp_TEST_WAS_RUN) + PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER} -- works") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the C# compiler works passed with " + "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n") + endif() + + # Re-configure to save learned information. + configure_file( + ${CMAKE_ROOT}/Modules/CMakeCSharpCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeCSharpCompiler.cmake + @ONLY + ) + include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCSharpCompiler.cmake) +endif() diff --git a/Modules/CompilerId/VS-10.csproj.in b/Modules/CompilerId/VS-10.csproj.in new file mode 100644 index 0000000..833dca7 --- /dev/null +++ b/Modules/CompilerId/VS-10.csproj.in @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid> + <RootNamespace>CompilerId@id_lang@</RootNamespace> + <Keyword>Win32Proj</Keyword> + @id_system@ + @id_system_version@ + @id_WindowsTargetPlatformVersion@ + @id_WindowsSDKDesktopARMSupport@ + </PropertyGroup> + <PropertyGroup> + @id_PreferredToolArchitecture@ + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + @id_toolset@ + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <!-- ============================================================ --> + <!-- == set preprocessor definitions == --> + <!-- ============================================================ --> + <PropertyGroup> + <DefineConstants></DefineConstants> + <UnknownValue>Unknown</UnknownValue> + </PropertyGroup> + <!-- Platform --> + <PropertyGroup Condition="'$(Platform)'!=''"> + <DefineConstants>$(DefineConstants);Platform$(Platform)</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(Platform)'==''"> + <DefineConstants>$(DefineConstants);Platform$(UnknownValue)</DefineConstants> + </PropertyGroup> + <!-- PlatformToolset --> + <PropertyGroup Condition="'$(PlatformToolset)'!=''"> + <DefineConstants>$(DefineConstants);PlatformToolset$(PlatformToolset)</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(PlatformToolset)'==''"> + <DefineConstants>$(DefineConstants);PlatformToolset$(UnknownValue)</DefineConstants> + </PropertyGroup> + <!-- ============================================================ --> + <PropertyGroup> + <OutputPath Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'">.\</OutputPath> + </PropertyGroup> + <ItemGroup> + <Compile Include="@id_src@" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <PropertyGroup> + <PostBuildEvent>cd /D "$(MSBuildToolsPath)" +if not %errorlevel%==0 exit -1 +if not exist @id_cl@ exit -2 +%40echo CMAKE_@id_lang@_COMPILER=$(MSBuildToolsPath)\@id_cl@</PostBuildEvent> + </PropertyGroup> +</Project> |