diff options
86 files changed, 2128 insertions, 189 deletions
diff --git a/Help/generator/CodeBlocks.rst b/Help/generator/CodeBlocks.rst index 01798c7..d03cb0c 100644 --- a/Help/generator/CodeBlocks.rst +++ b/Help/generator/CodeBlocks.rst @@ -18,6 +18,9 @@ This "extra" generator may be specified as: ``CodeBlocks - NMake Makefiles`` Generate with :generator:`NMake Makefiles`. +``CodeBlocks - NMake Makefiles JOM`` + Generate with :generator:`NMake Makefiles JOM`. + ``CodeBlocks - Ninja`` Generate with :generator:`Ninja`. diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 015e36e..d4712ba 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -59,6 +59,7 @@ All Modules /module/CPackDeb /module/CPackDMG /module/CPackIFW + /module/CPackIFWConfigureFile /module/CPackNSIS /module/CPackPackageMaker /module/CPackProductBuild diff --git a/Help/module/CPackIFWConfigureFile.rst b/Help/module/CPackIFWConfigureFile.rst new file mode 100644 index 0000000..e88517c --- /dev/null +++ b/Help/module/CPackIFWConfigureFile.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CPackIFWConfigureFile.cmake diff --git a/Help/release/dev/codeblocks-nmake-makefiles-jom.rst b/Help/release/dev/codeblocks-nmake-makefiles-jom.rst new file mode 100644 index 0000000..f5612f0 --- /dev/null +++ b/Help/release/dev/codeblocks-nmake-makefiles-jom.rst @@ -0,0 +1,5 @@ +codeblocks-nmake-makefiles-jom +------------------------------ + +* The :generator:`CodeBlocks` now can generate with + :generator:`NMake Makefiles JOM`. diff --git a/Help/release/dev/cpack-ifw-configure-file.rst b/Help/release/dev/cpack-ifw-configure-file.rst new file mode 100644 index 0000000..c9a1220 --- /dev/null +++ b/Help/release/dev/cpack-ifw-configure-file.rst @@ -0,0 +1,9 @@ +cpack-ifw-configure-file +------------------------ + +* The :command:`cpack_ifw_configure_file` command was added + (in :module:`CPackIFWConfigureFile`) to configure file templates prepared + in QtIFW/SDK/Creator style. + +* The :module:`CPackIFWConfigureFile` module was added to define + :command:`cpack_ifw_configure_file` command. diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 3b39bce..4649f35 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -45,7 +45,6 @@ set(_MS_MINGW_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) include(CheckLanguage) include(ExternalProject) -include(CMakeParseArguments) function(_setup_mingw_config_and_build source_dir build_dir) # Look for a MinGW gfortran. diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index 8a6c0bc..1ba42d9 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -4,6 +4,9 @@ set(CMAKE_CUDA_HOST_LINK_LAUNCHER "@CMAKE_CUDA_HOST_LINK_LAUNCHER@") set(CMAKE_CUDA_COMPILER_ID "@CMAKE_CUDA_COMPILER_ID@") set(CMAKE_CUDA_COMPILER_VERSION "@CMAKE_CUDA_COMPILER_VERSION@") set(CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT "@CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT@") +set(CMAKE_CUDA_SIMULATE_ID "@CMAKE_CUDA_SIMULATE_ID@") +set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@") +@SET_MSVC_CUDA_ARCHITECTURE_ID@ set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX") set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX") diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in index a20f1b1..018bab7 100644 --- a/Modules/CMakeCUDACompilerId.cu.in +++ b/Modules/CMakeCUDACompilerId.cu.in @@ -9,6 +9,9 @@ because some compilers will just produce instructions to fill the array rather than assigning a pointer to a static array. */ char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif @CMAKE_CUDA_COMPILER_ID_PLATFORM_CONTENT@ @CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@ @@ -35,6 +38,12 @@ int main(int argc, char* argv[]) #ifdef COMPILER_VERSION_MAJOR require += info_version[argc]; #endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif require += info_language_dialect_default[argc]; (void)argv; return require; diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index 202a7a6..abc4b66 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -1,7 +1,11 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -set(CMAKE_CUDA_OUTPUT_EXTENSION .o) +if(UNIX) + set(CMAKE_CUDA_OUTPUT_EXTENSION .o) +else() + set(CMAKE_CUDA_OUTPUT_EXTENSION .obj) +endif() set(CMAKE_INCLUDE_FLAG_CUDA "-I") # Load compiler-specific information. @@ -177,11 +181,14 @@ if(NOT CMAKE_CUDA_LINK_EXECUTABLE) endif() #These are used when linking relocatable (dc) cuda code -set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") -set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") - +if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY) + set(CMAKE_CUDA_DEVICE_LINK_LIBRARY + "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") +endif() +if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE) + set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE + "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") +endif() mark_as_advanced( CMAKE_CUDA_FLAGS diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index 484e1f0..7ca79bd 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -11,8 +11,6 @@ function(_readFile file) set(_compiler_id_pp_test_${CompilerId} ${_compiler_id_pp_test} PARENT_SCOPE) endfunction() -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) - function(compiler_id_detection outvar lang) if (NOT lang STREQUAL Fortran AND NOT lang STREQUAL CSharp) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index e03de7e..bef6d0e 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -60,7 +60,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCUDA/(\\./)?(CompilerIdCUDA.xctest/)?CompilerIdCUDA[ \t\n\\\"]") set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2) - set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v") + set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS -v --keep --keep-dir tmp) if(CMAKE_CUDA_HOST_COMPILER) list(APPEND CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-ccbin=${CMAKE_CUDA_HOST_COMPILER}") endif() @@ -70,6 +70,10 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() include(CMakeFindBinUtils) +if(MSVC_CUDA_ARCHITECTURE_ID) + set(SET_MSVC_CUDA_ARCHITECTURE_ID + "set(MSVC_CUDA_ARCHITECTURE_ID ${MSVC_CUDA_ARCHITECTURE_ID})") +endif() #if this compiler vendor is matches NVIDIA we can determine #what the host compiler is. This only needs to be done if the CMAKE_CUDA_HOST_COMPILER @@ -102,6 +106,14 @@ if(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA) if("${_nvcc_output_line}" MATCHES "^ *nvlink") string(APPEND _nvcc_log " ignoring nvlink line\n") elseif(_nvcc_libraries) + if("${_nvcc_output_line}" MATCHES "(@\"?tmp/a\\.exe\\.res\"?)") + set(_nvcc_link_res_arg "${CMAKE_MATCH_1}") + set(_nvcc_link_res "${CMAKE_PLATFORM_INFO_DIR}/CompilerIdCUDA/tmp/a.exe.res") + if(EXISTS "${_nvcc_link_res}") + file(READ "${_nvcc_link_res}" _nvcc_link_res_content) + string(REPLACE "${_nvcc_link_res_arg}" "${_nvcc_link_res_content}" _nvcc_output_line "${_nvcc_output_line}") + endif() + endif() string(FIND "${_nvcc_output_line}" "${_nvcc_libraries}" _nvcc_libraries_pos) if(NOT _nvcc_libraries_pos EQUAL -1) set(_nvcc_link_line "${_nvcc_output_line}") @@ -112,9 +124,13 @@ if(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA) endif() if(_nvcc_link_line) - #extract the compiler that is being used for linking - separate_arguments(_nvcc_link_line_args UNIX_COMMAND "${_nvcc_link_line}") - list(GET _nvcc_link_line_args 0 CMAKE_CUDA_HOST_LINK_LAUNCHER) + if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_LINKER}") + else() + #extract the compiler that is being used for linking + separate_arguments(_nvcc_link_line_args UNIX_COMMAND "${_nvcc_link_line}") + list(GET _nvcc_link_line_args 0 CMAKE_CUDA_HOST_LINK_LAUNCHER) + endif() #prefix the line with cuda-fake-ld so that implicit link info believes it is #a link line diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index eae139d..bb34de5 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -131,6 +131,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src) # Create a clean working directory. file(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR}) file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}) + file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}/tmp) CMAKE_DETERMINE_COMPILER_ID_WRITE("${lang}" "${src}") # Construct a description of this test case. diff --git a/Modules/CMakeExpandImportedTargets.cmake b/Modules/CMakeExpandImportedTargets.cmake index add0c6d..ad065f0 100644 --- a/Modules/CMakeExpandImportedTargets.cmake +++ b/Modules/CMakeExpandImportedTargets.cmake @@ -37,9 +37,6 @@ # LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} # CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}" ) - -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) - function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT ) set(options ) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 75a031e..4c0486e 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -25,6 +25,7 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" OR "x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC" OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC" OR (CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake index 8415641..3210222 100644 --- a/Modules/CMakePackageConfigHelpers.cmake +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -201,9 +201,6 @@ # # check_required_components(Foo) - -include(CMakeParseArguments) - include(WriteBasicConfigVersionFile) macro(WRITE_BASIC_PACKAGE_VERSION_FILE) diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index 2031ba5..3469d34 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -45,6 +45,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj endif() list(GET args 0 cmd) endif() + set(is_msvc 0) if("${cmd}" MATCHES "${linker_regex}") string(APPEND log " link line: [${line}]\n") string(REGEX REPLACE ";-([LYz]);" ";-\\1" args "${args}") @@ -54,6 +55,17 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj string(REGEX REPLACE "^-L" "" dir "${arg}") list(APPEND implicit_dirs_tmp ${dir}) string(APPEND log " arg [${arg}] ==> dir [${dir}]\n") + elseif("${arg}" MATCHES "^[-/]LIBPATH:(.+)") + # MSVC search path. + set(dir "${CMAKE_MATCH_1}") + list(APPEND implicit_dirs_tmp ${dir}) + string(APPEND log " arg [${arg}] ==> dir [${dir}]\n") + elseif(is_msvc AND "${arg}" STREQUAL "-link") + string(APPEND log " arg [${arg}] ==> ignore MSVC cl option\n") + elseif(is_msvc AND "${arg}" MATCHES "^(.*\\.[Ll][Ii][Bb])$") + set(lib "${CMAKE_MATCH_1}") + list(APPEND implicit_libs_tmp ${lib}) + string(APPEND log " arg [${arg}] ==> lib [${lib}]\n") elseif("${arg}" MATCHES "^-l([^:].*)$") # Unix library. set(lib "${CMAKE_MATCH_1}") @@ -82,6 +94,9 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj # Link editor option. list(APPEND implicit_libs_tmp ${arg}) string(APPEND log " arg [${arg}] ==> opt [${arg}]\n") + elseif("${arg}" STREQUAL "cl.exe") + string(APPEND log " arg [${arg}] ==> recognize MSVC cl\n") + set(is_msvc 1) else() string(APPEND log " arg [${arg}] ==> ignore\n") endif() diff --git a/Modules/CMakePrintHelpers.cmake b/Modules/CMakePrintHelpers.cmake index bf98a42..21c333e 100644 --- a/Modules/CMakePrintHelpers.cmake +++ b/Modules/CMakePrintHelpers.cmake @@ -39,8 +39,6 @@ # # -- CMAKE_C_COMPILER="/usr/bin/gcc" ; CMAKE_MAJOR_VERSION="2" ; DOES_NOT_EXIST="" -include(CMakeParseArguments) - function(CMAKE_PRINT_VARIABLES) set(msg "") foreach(var ${ARGN}) diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 670b31d..80113cb 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -58,6 +58,11 @@ else() include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake) CMAKE_DETERMINE_COMPILER_ABI(CUDA ${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu) + if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}") + set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}") + endif() + # Re-configure to save learned information. configure_file( ${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index d0d24ba..b3ab055 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -630,10 +630,6 @@ if(NOT CPackComponent_CMake_INCLUDED) include(CPackComponent) endif() -if(NOT __CMAKE_PARSE_ARGUMENTS_INCLUDED) - include(CMakeParseArguments) -endif() - # Resolve full filename for script file macro(_cpack_ifw_resolve_script _variable) set(_ifw_script_macro ${_variable}) diff --git a/Modules/CPackIFWConfigureFile.cmake b/Modules/CPackIFWConfigureFile.cmake new file mode 100644 index 0000000..790574a --- /dev/null +++ b/Modules/CPackIFWConfigureFile.cmake @@ -0,0 +1,65 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# CPackIFWConfigureFile +# --------------------- +# +# The module defines :command:`configure_file` similar command to +# configure file templates prepared in QtIFW/SDK/Creator style. +# +# +# Commands +# ^^^^^^^^ +# +# The module defines the following commands: +# +# .. command:: cpack_ifw_configure_file +# +# Copy a file to another location and modify its contents. +# +# :: +# +# cpack_ifw_configure_file(<input> <output>) +# +# Copies an ``<input>`` file to an ``<output>`` file and substitutes variable +# values referenced as ``%{VAR}`` or ``%VAR%`` in the input file content. +# Each variable reference will be replaced with the current value of the +# variable, or the empty string if the variable is not defined. +# + +# NOTE: This file used to himself packaging via CPack IFW generator and +# should be compatible with minimal CMake version defined in +# ../CMakeLists.txt file. + +if(NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED) +set(CPackIFWConfigureFile_CMake_INCLUDED 1) + +macro(cpack_ifw_configure_file INPUT OUTPUT) + file(READ "${INPUT}" _tmp) + foreach(_tmp_regex "%{([^%}]+)}" "%([^%]+)%") + string(REGEX MATCHALL "${_tmp_regex}" _tmp_vars "${_tmp}") + while(_tmp_vars) + foreach(_tmp_var ${_tmp_vars}) + string(REGEX REPLACE "${_tmp_regex}" "\\1" + _tmp_var_name "${_tmp_var}") + if(DEFINED ${_tmp_var_name}) + set(_tmp_var_value "${${_tmp_var_name}}") + elseif(NOT "$ENV{${_tmp_var_name}}" STREQUAL "") + set(_tmp_var_value "$ENV{${_tmp_var_name}}") + else() + set(_tmp_var_value "") + endif() + string(REPLACE "${_tmp_var}" "${_tmp_var_value}" _tmp "${_tmp}") + endforeach() + string(REGEX MATCHALL "${_tmp_regex}" _tmp_vars "${_tmp}") + endwhile() + endforeach() + if(IS_ABSOLUTE "${OUTPUT}") + file(WRITE "${OUTPUT}" "${_tmp}") + else() + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT}" "${_tmp}") + endif() +endmacro() + +endif() # NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake index 8451a6a..1203be4 100644 --- a/Modules/CTestCoverageCollectGCOV.cmake +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -65,7 +65,6 @@ # Suppress non-error messages that otherwise would have been # printed out by this function. -include(CMakeParseArguments) function(ctest_coverage_collect_gcov) set(options QUIET GLOB DELETE) set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND) diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake index 5f049e7..ef08062 100644 --- a/Modules/CheckFunctionExists.cmake +++ b/Modules/CheckFunctionExists.cmake @@ -5,18 +5,16 @@ # CheckFunctionExists # ------------------- # -# Check if a C function can be linked +# Check if a C function can be linked:: # -# CHECK_FUNCTION_EXISTS(<function> <variable>) +# check_function_exists(<function> <variable>) # -# Check that the <function> is provided by libraries on the system and -# store the result in a <variable>. This does not verify that any -# system header file declares the function, only that it can be found at -# link time (consider using CheckSymbolExists). -# <variable> will be created as an internal cache variable. +# Check that the ``<function>`` is provided by libraries on the system and store +# the result in a ``<variable>``. ``<variable>`` will be created as an internal +# cache variable. # -# The following variables may be set before calling this macro to modify -# the way the check is run: +# The following variables may be set before calling this macro to modify the +# way the check is run: # # :: # @@ -25,6 +23,20 @@ # CMAKE_REQUIRED_INCLUDES = list of include directories # CMAKE_REQUIRED_LIBRARIES = list of libraries to link # CMAKE_REQUIRED_QUIET = execute quietly without messages +# +# .. note:: +# +# Prefer using :Module:`CheckSymbolExists` instead of this module, +# for the following reasons: +# +# * ``check_function_exists()`` can't detect functions that are inlined +# in headers or specified as a macro. +# +# * ``check_function_exists()`` can't detect anything in the 32-bit +# versions of the Win32 API, because of a mismatch in calling conventions. +# +# * ``check_function_exists()`` only verifies linking, it does not verify +# that the function is declared in system headers. macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE) if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}") diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 605d555..ae35132 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -1,14 +1,15 @@ set(CMAKE_CUDA_VERBOSE_FLAG "-v") - -set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) -set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) -#CMAKE_SHARED_LIBRARY_CUDA_FLAGS is sent to the host linker so we don' need -#to forward it through nvcc -set(CMAKE_SHARED_LIBRARY_CUDA_FLAGS -fPIC) +if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) + set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) + set(CMAKE_CUDA_COMPILE_OPTIONS_VISIBILITY -Xcompiler=-fvisibility=) + # CMAKE_SHARED_LIBRARY_CUDA_FLAGS is sent to the host linker so we + # don't need to forward it through nvcc. + set(CMAKE_SHARED_LIBRARY_CUDA_FLAGS -fPIC) +endif() set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared) set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=) -set(CMAKE_CUDA_COMPILE_OPTIONS_VISIBILITY -Xcompiler=-fvisibility=) string(APPEND CMAKE_CUDA_FLAGS_INIT " ") string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -g") @@ -16,9 +17,12 @@ string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -Os -DNDEBUG") string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -O3 -DNDEBUG") string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG") -set(CMAKE_CUDA98_STANDARD_COMPILE_OPTION "") -set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "") -set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11") -set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11") - -set(CMAKE_CUDA_STANDARD_DEFAULT 98) +if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_CUDA_STANDARD_DEFAULT "") +else() + set(CMAKE_CUDA_STANDARD_DEFAULT 98) + set(CMAKE_CUDA98_STANDARD_COMPILE_OPTION "") + set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11") +endif() diff --git a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake index 32ccf8a..cb0beaf 100644 --- a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake +++ b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake @@ -4,4 +4,14 @@ set(_compiler_id_pp_test "defined(__NVCC__)") set(_compiler_id_version_compute " # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__CUDACC_VER_MAJOR__) # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__CUDACC_VER_MINOR__) -# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CUDACC_VER_BUILD__)") +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CUDACC_VER_BUILD__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100) +# define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(_MSC_VER % 100) +# endif") + +set(_compiler_id_simulate " +# if defined(_MSC_VER) +# define @PREFIX@SIMULATE_ID \"MSVC\" +# endif") diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index 88bc1c8..78d9df3 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake @@ -26,9 +26,6 @@ Functions #]=======================================================================] -include("${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake") - - function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet) set(_type "ANY") diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake index 0ebd465..d684ccd 100644 --- a/Modules/FindBISON.cmake +++ b/Modules/FindBISON.cmake @@ -84,8 +84,6 @@ find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable") mark_as_advanced(BISON_EXECUTABLE) -include(CMakeParseArguments) - if(BISON_EXECUTABLE) # the bison commands should be executed with the C locale, otherwise # the message (which are parsed) may be translated diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake index 214873c..fef7fb4 100644 --- a/Modules/FindFLEX.cmake +++ b/Modules/FindFLEX.cmake @@ -107,8 +107,6 @@ find_path(FLEX_INCLUDE_DIR FlexLexer.h mark_as_advanced(FL_LIBRARY FLEX_INCLUDE_DIR) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) - set(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR}) set(FLEX_LIBRARIES ${FL_LIBRARY}) diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake index 1f447f1..e1b22b6 100644 --- a/Modules/FindGTK2.cmake +++ b/Modules/FindGTK2.cmake @@ -165,7 +165,6 @@ #============================================================= include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr) file(STRINGS ${_gtkversion_hdr} _contents REGEX "#define GTK_M[A-Z]+_VERSION[ \t]+") diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake index 7718468..8035507 100644 --- a/Modules/FindGettext.cmake +++ b/Modules/FindGettext.cmake @@ -77,8 +77,6 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gettext REQUIRED_VARS GETTEXT_MSGMERGE_EXECUTABLE GETTEXT_MSGFMT_EXECUTABLE VERSION_VAR GETTEXT_VERSION_STRING) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) - function(_GETTEXT_GET_UNIQUE_TARGET_NAME _name _unique_name) set(propertyName "_GETTEXT_UNIQUE_COUNTER_${_name}") get_property(currentCounter GLOBAL PROPERTY "${propertyName}") diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index 5c0abb0..4265a97 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -86,6 +86,14 @@ list(APPEND _JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\2.0;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.9;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.8;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.7;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\2.6;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.5;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.4;JavaHome]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.3;JavaHome]/bin" ) # Hard-coded guesses should still go in PATHS. This ensures that the user # environment can always override hard guesses. diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 7b46877..b77925d 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -130,7 +130,6 @@ message. #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) # internal helper macro macro(_FPHSA_FAILURE_MESSAGE _msg) diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake index 6c8813c..09bdf1f 100644 --- a/Modules/FindSquish.cmake +++ b/Modules/FindSquish.cmake @@ -119,9 +119,6 @@ # # This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead. - -include(CMakeParseArguments) - set(SQUISH_INSTALL_DIR_STRING "Directory containing the bin, doc, and lib directories for Squish; this should be the root of the installation directory.") set(SQUISH_SERVER_EXECUTABLE_STRING "The squishserver executable program.") set(SQUISH_CLIENT_EXECUTABLE_STRING "The squishclient executable program.") diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index c201714..6d1b4ed 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -184,7 +184,6 @@ # :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` and # :prop_tgt:`VISIBILITY_INLINES_HIDDEN` instead. -include(CMakeParseArguments) include(CheckCXXCompilerFlag) # TODO: Install this macro separately? diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 72775ce..1b23800 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -654,6 +654,8 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa if(NOT EXISTS "${target}") message("warning: target '${target}' does not exist...") + set(${prerequisites_var} "" PARENT_SCOPE) + return() endif() set(gp_cmd_paths ${gp_cmd_paths} @@ -810,6 +812,20 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa OUTPUT_VARIABLE gp_cmd_ov ERROR_VARIABLE gp_ev ) + + if(gp_tool STREQUAL "dumpbin") + # Exclude delay load dependencies under windows (they are listed in dumpbin output after the message below) + string(FIND "${gp_cmd_ov}" "Image has the following delay load dependencies" gp_delayload_pos) + if (${gp_delayload_pos} GREATER -1) + string(SUBSTRING "${gp_cmd_ov}" 0 ${gp_delayload_pos} gp_cmd_ov_no_delayload_deps) + string(SUBSTRING "${gp_cmd_ov}" ${gp_delayload_pos} -1 gp_cmd_ov_delayload_deps) + if (verbose) + message(STATUS "GetPrequisites(${target}) : ignoring the following delay load dependencies :\n ${gp_cmd_ov_delayload_deps}") + endif() + set(gp_cmd_ov ${gp_cmd_ov_no_delayload_deps}) + endif() + endif() + if(NOT gp_rv STREQUAL "0") if(gp_tool STREQUAL "dumpbin") # dumpbin error messages seem to go to stdout diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index f4ae091..7975bd4 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -210,21 +210,27 @@ if(MSVC) endif() if(CMAKE_INSTALL_UCRT_LIBRARIES AND NOT v VERSION_LESS 14) - # Find the Windows Universal CRT redistribution directory. + # Find the Windows Kits directory. get_filename_component(windows_kits_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" ABSOLUTE) set(programfilesx86 "ProgramFiles(x86)") - find_path(WINDOWS_KITS_REDIST_DIR NAMES ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll + find_path(WINDOWS_KITS_DIR NAMES Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll PATHS - "${windows_kits_dir}/Redist" - "$ENV{ProgramFiles}/Windows Kits/10/Redist" - "$ENV{${programfilesx86}}/Windows Kits/10/Redist" + "${windows_kits_dir}" + "$ENV{ProgramFiles}/Windows Kits/10" + "$ENV{${programfilesx86}}/Windows Kits/10" ) - mark_as_advanced(WINDOWS_KITS_REDIST_DIR) + mark_as_advanced(WINDOWS_KITS_DIR) # Glob the list of UCRT DLLs. - file(GLOB __ucrt_dlls "${WINDOWS_KITS_REDIST_DIR}/ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll") - list(APPEND __install__libs ${__ucrt_dlls}) + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll") + list(APPEND __install__libs ${__ucrt_dlls}) + endif() + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${CMAKE_MSVC_ARCH}/ucrt/*.dll") + list(APPEND __install__libs ${__ucrt_dlls}) + endif() endif() endmacro() diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index f506500..0e90d35 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -54,6 +54,8 @@ if(NOT MSVC_VERSION) set(_compiler_version ${CMAKE_CXX_SIMULATE_VERSION}) elseif(CMAKE_Fortran_SIMULATE_VERSION) set(_compiler_version ${CMAKE_Fortran_SIMULATE_VERSION}) + elseif(CMAKE_CUDA_SIMULATE_VERSION) + set(_compiler_version ${CMAKE_CUDA_SIMULATE_VERSION}) elseif(CMAKE_C_COMPILER_VERSION) set(_compiler_version ${CMAKE_C_COMPILER_VERSION}) else() diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake new file mode 100644 index 0000000..80ecfbc --- /dev/null +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -0,0 +1,42 @@ +include(Platform/Windows-MSVC) + +set(CMAKE_CUDA_COMPILE_PTX_COMPILATION + "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") +set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION + "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") +set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION + "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + +set(__IMPLICT_LINKS ) +foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) + string(APPEND __IMPLICT_LINKS " -LIBPATH:\"${dir}\"") +endforeach() +foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}) + string(APPEND __IMPLICT_LINKS " \"${lib}\"") +endforeach() +set(CMAKE_CUDA_LINK_EXECUTABLE + "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_CUDA_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_LIBRARIES>${__IMPLICT_LINKS}") + +set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ") +set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ") +set(CMAKE_CUDA_CREATE_SHARED_LIBRARY + "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}") + +set(CMAKE_CUDA_CREATE_SHARED_MODULE ${CMAKE_CUDA_CREATE_SHARED_LIBRARY}) +set(CMAKE_CUDA_CREATE_STATIC_LIBRARY "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ") +set(CMAKE_CUDA_LINKER_SUPPORTS_PDB ON) +set(CMAKE_CUDA_LINK_EXECUTABLE + "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_CUDA_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}") +unset(_CMAKE_VS_LINK_EXE) +unset(_CMAKE_VS_LINK_EXE) + +set(CMAKE_CUDA_DEVICE_LINK_LIBRARY + "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") +set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE + "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + +string(APPEND CMAKE_CUDA_FLAGS_INIT " -Xcompiler=-GR,-EHsc") +string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=-MDd,-Zi,-RTC1") +string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=-MD") +string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -Xcompiler=-MD") +string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -Xcompiler=-MD") diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 6b34c8f..93255ae 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -403,8 +403,6 @@ # Sets the directory where the header files will be generated. Same behavior as option # '-d' of javah tool. If not specified, ${CMAKE_CURRENT_BINARY_DIR} is used as output directory. -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) - function (__java_copy_file src dest comment) add_custom_command( OUTPUT ${dest} diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index ffb72a0..277f4ca 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -232,8 +232,6 @@ endmacro() macro(SWIG_ADD_LIBRARY name) - - include(CMakeParseArguments) set(options "") set(oneValueArgs LANGUAGE TYPE) @@ -341,4 +339,3 @@ macro(SWIG_LINK_LIBRARIES name) message(SEND_ERROR "Cannot find Swig library \"${name}\".") endif() endmacro() - diff --git a/Modules/WriteBasicConfigVersionFile.cmake b/Modules/WriteBasicConfigVersionFile.cmake index 20c769e..7c9467a 100644 --- a/Modules/WriteBasicConfigVersionFile.cmake +++ b/Modules/WriteBasicConfigVersionFile.cmake @@ -18,8 +18,6 @@ # # Deprecated, see WRITE_BASIC_PACKAGE_VERSION_FILE(), it is identical. -include(CMakeParseArguments) - function(WRITE_BASIC_CONFIG_VERSION_FILE _filename) set(options ) diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index a390f4b..ba249e1 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -216,7 +216,6 @@ # CompatSupport_DEPRECATED= # ) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) include(${CMAKE_CURRENT_LIST_DIR}/CMakeCompilerIdDetection.cmake) function(_load_compiler_variables CompilerId lang) diff --git a/Source/CMakeInstallDestinations.cmake b/Source/CMakeInstallDestinations.cmake index 023f6c0..28f4e87 100644 --- a/Source/CMakeInstallDestinations.cmake +++ b/Source/CMakeInstallDestinations.cmake @@ -25,6 +25,12 @@ set(CMAKE_DOC_DIR_DESC "docs") set(CMAKE_MAN_DIR_DESC "man pages") set(CMAKE_XDGDATA_DIR_DESC "XDG specific files") +set(CMake_INSTALL_INFIX "" CACHE STRING "") +set_property(CACHE CMake_INSTALL_INFIX PROPERTY HELPSTRING + "Intermediate installation path (empty by default)" + ) +mark_as_advanced(CMake_INSTALL_INFIX) + foreach(v CMAKE_BIN_DIR CMAKE_DATA_DIR @@ -41,7 +47,7 @@ foreach(v # Use the default when the user did not set this variable. if(NOT ${v}) - set(${v} "${${v}_DEFAULT}") + set(${v} "${CMake_INSTALL_INFIX}${${v}_DEFAULT}") endif() # Remove leading slash to treat as relative to install prefix. string(REGEX REPLACE "^/" "" ${v} "${${v}}") diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index d15fdbe..2835ee6 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -710,6 +710,8 @@ if (WIN32) cmGhsMultiTargetGenerator.h cmGhsMultiGpj.cxx cmGhsMultiGpj.h + cmVSSetupHelper.cxx + cmVSSetupHelper.h ) # Add a manifest file to executables on Windows to allow for @@ -785,6 +787,15 @@ target_link_libraries(CMakeLib cmsys ${CMake_KWIML_LIBRARIES} ) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "sparc") + # the atomic instructions are implemented using libatomic on some platforms, + # so linking to that may be required + check_library_exists(atomic __atomic_fetch_add_4 "" LIBATOMIC_NEEDED) + if(LIBATOMIC_NEEDED) + target_link_libraries(CMakeLib atomic) + endif() +endif() + # On Apple we need CoreFoundation if(APPLE) target_link_libraries(CMakeLib "-framework CoreFoundation") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index fde01c1..0c64d70 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 7) -set(CMake_VERSION_PATCH 20170112) +set(CMake_VERSION_PATCH 20170116) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 4d23e45..a062e64 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -634,7 +634,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() std::string outputFile = envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\""; this->MemoryTesterEnvironmentVariable = - outputFile + extraOptions + suppressionsOption; + outputFile + suppressionsOption + extraOptions; break; } default: diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index f544e8a..2dffcaa 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -48,6 +48,7 @@ cmExtraCodeBlocksGenerator::GetFactory() #if defined(_WIN32) factory.AddSupportedGlobalGenerator("MinGW Makefiles"); factory.AddSupportedGlobalGenerator("NMake Makefiles"); + factory.AddSupportedGlobalGenerator("NMake Makefiles JOM"); // disable until somebody actually tests it: // this->AddSupportedGlobalGenerator("MSYS Makefiles"); #endif @@ -741,7 +742,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand( } std::string generator = this->GlobalGenerator->GetName(); - if (generator == "NMake Makefiles") { + if (generator == "NMake Makefiles" || generator == "NMake Makefiles JOM") { // For Windows ConvertToOutputPath already adds quotes when required. // These need to be escaped, see // https://gitlab.kitware.com/cmake/cmake/issues/13952 diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx index 03bbf42..909be78 100644 --- a/Source/cmFileMonitor.cxx +++ b/Source/cmFileMonitor.cxx @@ -334,6 +334,9 @@ void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths, rootSegment)); // Can not be both filename and root part of the path! const std::string& currentSegment = pathSegments[i]; + if (currentSegment.empty()) { + continue; + } cmIBaseWatcher* nextWatcher = currentWatcher->Find(currentSegment); if (!nextWatcher) { diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index dde6e82..e27615a 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -425,20 +425,6 @@ std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand() } } - // Search where VS15Preview places it. - mskey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;"; - mskey += this->GetIDEVersion(); - if (cmSystemTools::ReadRegistryValue(mskey.c_str(), msbuild, - cmSystemTools::KeyWOW64_32)) { - cmSystemTools::ConvertToUnixSlashes(msbuild); - msbuild += "/MSBuild/"; - msbuild += this->GetIDEVersion(); - msbuild += "/Bin/MSBuild.exe"; - if (cmSystemTools::FileExists(msbuild, true)) { - return msbuild; - } - } - msbuild = "MSBuild.exe"; return msbuild; } diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx index 20d30bc..d11ee7c 100644 --- a/Source/cmGlobalVisualStudio15Generator.cxx +++ b/Source/cmGlobalVisualStudio15Generator.cxx @@ -8,6 +8,7 @@ #include "cmMakefile.h" #include "cmVS141CLFlagTable.h" #include "cmVS141CSharpFlagTable.h" +#include "cmVSSetupHelper.h" static const char vs15generatorName[] = "Visual Studio 15 2017"; @@ -80,11 +81,7 @@ cmGlobalVisualStudio15Generator::cmGlobalVisualStudio15Generator( cmake* cm, const std::string& name, const std::string& platformName) : cmGlobalVisualStudio14Generator(cm, name, platformName) { - std::string vc15Express; - this->ExpressEdition = cmSystemTools::ReadRegistryValue( - "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\15.0\\Setup\\VC;" - "ProductDir", - vc15Express, cmSystemTools::KeyWOW64_32); + this->ExpressEdition = false; this->DefaultPlatformToolset = "v141"; this->DefaultClFlagTable = cmVS141CLFlagTable; this->DefaultCSharpFlagTable = cmVS141CSharpFlagTable; @@ -118,7 +115,7 @@ bool cmGlobalVisualStudio15Generator::SelectWindowsStoreToolset( if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) { if (this->IsWindowsStoreToolsetInstalled() && this->IsWindowsDesktopToolsetInstalled()) { - toolset = "v140"; // VS 15 uses v140 toolset + toolset = "v141"; // VS 15 uses v141 toolset return true; } else { return false; @@ -130,21 +127,44 @@ bool cmGlobalVisualStudio15Generator::SelectWindowsStoreToolset( bool cmGlobalVisualStudio15Generator::IsWindowsDesktopToolsetInstalled() const { - const char desktop10Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" - "VisualStudio\\15.0\\VC\\Runtimes"; - - std::vector<std::string> vc15; - return cmSystemTools::GetRegistrySubKeys(desktop10Key, vc15, - cmSystemTools::KeyWOW64_32); + return vsSetupAPIHelper.IsVS2017Installed(); } bool cmGlobalVisualStudio15Generator::IsWindowsStoreToolsetInstalled() const { - const char universal10Key[] = - "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" - "VisualStudio\\15.0\\Setup\\Build Tools for Windows 10;SrcPath"; + return vsSetupAPIHelper.IsWin10SDKInstalled(); +} + +std::string cmGlobalVisualStudio15Generator::FindMSBuildCommand() +{ + std::string msbuild; + + // Ask Visual Studio Installer tool. + std::string vs; + if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) { + msbuild = vs + "/MSBuild/15.0/Bin/MSBuild.exe"; + if (cmSystemTools::FileExists(msbuild)) { + return msbuild; + } + } + + msbuild = "MSBuild.exe"; + return msbuild; +} + +std::string cmGlobalVisualStudio15Generator::FindDevEnvCommand() +{ + std::string devenv; + + // Ask Visual Studio Installer tool. + std::string vs; + if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) { + devenv = vs + "/Common7/IDE/devenv.com"; + if (cmSystemTools::FileExists(devenv)) { + return devenv; + } + } - std::string win10SDK; - return cmSystemTools::ReadRegistryValue(universal10Key, win10SDK, - cmSystemTools::KeyWOW64_32); + devenv = "devenv.com"; + return devenv; } diff --git a/Source/cmGlobalVisualStudio15Generator.h b/Source/cmGlobalVisualStudio15Generator.h index 59eb11a..781b41e 100644 --- a/Source/cmGlobalVisualStudio15Generator.h +++ b/Source/cmGlobalVisualStudio15Generator.h @@ -9,6 +9,7 @@ #include <string> #include "cmGlobalVisualStudio14Generator.h" +#include "cmVSSetupHelper.h" class cmGlobalGeneratorFactory; class cmake; @@ -39,7 +40,11 @@ protected: // of the toolset is installed bool IsWindowsStoreToolsetInstalled() const; + std::string FindMSBuildCommand() CM_OVERRIDE; + std::string FindDevEnvCommand() CM_OVERRIDE; + private: class Factory; + mutable cmVSSetupAPIHelper vsSetupAPIHelper; }; #endif diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c index 31faca1..56559f6 100644 --- a/Source/cmListFileLexer.c +++ b/Source/cmListFileLexer.c @@ -2518,7 +2518,7 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer) } /*--------------------------------------------------------------------------*/ -cmListFileLexer* cmListFileLexer_New() +cmListFileLexer* cmListFileLexer_New(void) { cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer)); if (!lexer) { diff --git a/Source/cmListFileLexer.h b/Source/cmListFileLexer.h index dfbad5e..c9fb6da 100644 --- a/Source/cmListFileLexer.h +++ b/Source/cmListFileLexer.h @@ -46,7 +46,7 @@ typedef struct cmListFileLexer_s cmListFileLexer; extern "C" { #endif -cmListFileLexer* cmListFileLexer_New(); +cmListFileLexer* cmListFileLexer_New(void); int cmListFileLexer_SetFileName(cmListFileLexer*, const char*, cmListFileLexer_BOM* bom); int cmListFileLexer_SetString(cmListFileLexer*, const char*); diff --git a/Source/cmListFileLexer.in.l b/Source/cmListFileLexer.in.l index 4b389b9..dd64923 100644 --- a/Source/cmListFileLexer.in.l +++ b/Source/cmListFileLexer.in.l @@ -398,7 +398,7 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer) } /*--------------------------------------------------------------------------*/ -cmListFileLexer* cmListFileLexer_New() +cmListFileLexer* cmListFileLexer_New(void) { cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer)); if (!lexer) { diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 069011d..4bc706c 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -104,10 +104,12 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // Get the language to use for linking this library. std::string linkLanguage = "CUDA"; + std::string const objExt = + this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); // Get the name of the device object to generate. std::string const targetOutputReal = - this->GeneratorTarget->ObjectDirectory + "cmake_device_link.o"; + this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt; this->DeviceLinkObject = targetOutputReal; this->NumberOfProgressActions++; @@ -228,6 +230,11 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal), output); + std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB(); + std::string targetOutPathCompilePDB = + this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB, + cmOutputConverter::SHELL); + vars.Language = linkLanguage.c_str(); vars.Objects = buildObjs.c_str(); vars.ObjectDir = objectDir.c_str(); @@ -235,6 +242,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( vars.LinkLibraries = linkLibs.c_str(); vars.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); + vars.TargetCompilePDB = targetOutPathCompilePDB.c_str(); std::string launcher; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 2b0e1b1..27b7c21 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -281,6 +281,8 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // Get the language to use for linking this library. std::string linkLanguage = "CUDA"; + std::string const objExt = + this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); // Create set of linking flags. std::string linkFlags; @@ -288,7 +290,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // Get the name of the device object to generate. std::string const targetOutputReal = - this->GeneratorTarget->ObjectDirectory + "cmake_device_link.o"; + this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt; this->DeviceLinkObject = targetOutputReal; this->NumberOfProgressActions++; @@ -364,12 +366,18 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal), output); + std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB(); + std::string targetOutPathCompilePDB = + this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB, + cmOutputConverter::SHELL); + vars.Objects = buildObjs.c_str(); vars.ObjectDir = objectDir.c_str(); vars.Target = target.c_str(); vars.LinkLibraries = linkLibs.c_str(); vars.ObjectsQuoted = buildObjs.c_str(); vars.LinkFlags = linkFlags.c_str(); + vars.TargetCompilePDB = targetOutPathCompilePDB.c_str(); // Add language feature flags. std::string langFlags; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 0db5687..bc8d8ff 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -229,6 +229,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) vars.SONameFlag = "$SONAME_FLAG"; vars.TargetSOName = "$SONAME"; vars.TargetPDB = "$TARGET_PDB"; + vars.TargetCompilePDB = "$TARGET_COMPILE_PDB"; vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; @@ -602,10 +603,12 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() // First and very important step is to make sure while inside this // step our link language is set to CUDA std::string cudaLinkLanguage = "CUDA"; + std::string const objExt = + this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); std::string const cfgName = this->GetConfigName(); - std::string const targetOutputReal = - ConvertToNinjaPath(genTarget.ObjectDirectory + "cmake_device_link.o"); + std::string const targetOutputReal = ConvertToNinjaPath( + genTarget.ObjectDirectory + "cmake_device_link" + objExt); std::string const targetOutputImplib = ConvertToNinjaPath(genTarget.GetFullPath(cfgName, @@ -714,6 +717,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL); EnsureDirectoryExists(objPath); + this->SetMsvcTargetPdbVariable(vars); + if (this->GetGlobalGenerator()->IsGCCOnWindows()) { // ar.exe can't handle backslashes in rsp files (implicitly used by gcc) std::string& linkLibraries = vars["LINK_LIBRARIES"]; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 23caead..8ad2efe 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -344,7 +344,8 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const { cmMakefile* mf = this->GetMakefile(); if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") || - mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID")) { + mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") || + mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID")) { std::string pdbPath; std::string compilePdbPath = this->ComputeTargetCompilePDB(); if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE || diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx new file mode 100644 index 0000000..d675a2c --- /dev/null +++ b/Source/cmVSSetupHelper.cxx @@ -0,0 +1,395 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmVSSetupHelper.h" + +#ifndef VSSetupConstants +#define VSSetupConstants +/* clang-format off */ +const IID IID_ISetupConfiguration = { + 0x42843719, 0xDB4C, 0x46C2, + { 0x8E, 0x7C, 0x64, 0xF1, 0x81, 0x6E, 0xFD, 0x5B } +}; +const IID IID_ISetupConfiguration2 = { + 0x26AAB78C, 0x4A60, 0x49D6, + { 0xAF, 0x3B, 0x3C, 0x35, 0xBC, 0x93, 0x36, 0x5D } +}; +const IID IID_ISetupPackageReference = { + 0xda8d8a16, 0xb2b6, 0x4487, + { 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5 } +}; +const IID IID_ISetupHelper = { + 0x42b21b78, 0x6192, 0x463e, + { 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c } +}; +const IID IID_IEnumSetupInstances = { + 0x6380BCFF, 0x41D3, 0x4B2E, + { 0x8B, 0x2E, 0xBF, 0x8A, 0x68, 0x10, 0xC8, 0x48 } +}; +const IID IID_ISetupInstance2 = { + 0x89143C9A, 0x05AF, 0x49B0, + { 0xB7, 0x17, 0x72, 0xE2, 0x18, 0xA2, 0x18, 0x5C } +}; +const IID IID_ISetupInstance = { + 0xB41463C3, 0x8866, 0x43B5, + { 0xBC, 0x33, 0x2B, 0x06, 0x76, 0xF7, 0xF4, 0x2E } +}; +const CLSID CLSID_SetupConfiguration = { + 0x177F0C4A, 0x1CD3, 0x4DE7, + { 0xA3, 0x2C, 0x71, 0xDB, 0xBB, 0x9F, 0xA3, 0x6D } +}; +/* clang-format on */ +#endif + +const WCHAR* VCToolsetComponent = + L"Microsoft.VisualStudio.Component.VC.Tools.x86.x64"; +const WCHAR* Win10SDKComponent = + L"Microsoft.VisualStudio.Component.Windows10SDK"; +const WCHAR* Win81SDKComponent = + L"Microsoft.VisualStudio.Component.Windows81SDK"; +const WCHAR* ComponentType = L"Component"; + +cmVSSetupAPIHelper::cmVSSetupAPIHelper() + : setupConfig(NULL) + , setupConfig2(NULL) + , setupHelper(NULL) + , initializationFailure(false) +{ + comInitialized = CoInitializeEx(NULL, 0); + if (SUCCEEDED(comInitialized)) { + Initialize(); + } else { + initializationFailure = true; + } +} + +cmVSSetupAPIHelper::~cmVSSetupAPIHelper() +{ + setupHelper = NULL; + setupConfig2 = NULL; + setupConfig = NULL; + if (SUCCEEDED(comInitialized)) + CoUninitialize(); +} + +bool cmVSSetupAPIHelper::IsVS2017Installed() +{ + bool ret = false; + if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) { + ret = EnumerateAndChooseVSInstance(); + } + + return ret; +} + +bool cmVSSetupAPIHelper::IsWin10SDKInstalled() +{ + bool isWin10SDKInstalled = false; + if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) { + if (EnumerateAndChooseVSInstance() && + chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) { + isWin10SDKInstalled = chosenInstanceInfo.IsWin10SDKInstalled; + } + } else { + isWin10SDKInstalled = chosenInstanceInfo.IsWin10SDKInstalled; + } + + return isWin10SDKInstalled; +} + +bool cmVSSetupAPIHelper::IsWin81SDKInstalled() +{ + bool isWin81SDKInstalled = false; + if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) { + if (EnumerateAndChooseVSInstance() && + chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) { + isWin81SDKInstalled = chosenInstanceInfo.IsWin81SDKInstalled; + } + } else { + isWin81SDKInstalled = chosenInstanceInfo.IsWin81SDKInstalled; + } + + return isWin81SDKInstalled; +} + +bool cmVSSetupAPIHelper::CheckInstalledComponent( + SmartCOMPtr<ISetupPackageReference> package, bool& bVCToolset, + bool& bWin10SDK, bool& bWin81SDK) +{ + bool ret = false; + bVCToolset = bWin10SDK = bWin81SDK = false; + SmartBSTR bstrId; + if (FAILED(package->GetId(&bstrId))) { + return ret; + } + + SmartBSTR bstrType; + if (FAILED(package->GetType(&bstrType))) { + return ret; + } + + std::wstring id = std::wstring(bstrId); + std::wstring type = std::wstring(bstrType); + if (id.compare(VCToolsetComponent) == 0 && + type.compare(ComponentType) == 0) { + bVCToolset = true; + ret = true; + } + + // Checks for any version of Win10 SDK. The version is appended at the end of + // the + // component name ex: Microsoft.VisualStudio.Component.Windows10SDK.10240 + if (id.find(Win10SDKComponent) != std::wstring::npos && + type.compare(ComponentType) == 0) { + bWin10SDK = true; + ret = true; + } + + if (id.compare(Win81SDKComponent) == 0 && type.compare(ComponentType) == 0) { + bWin81SDK = true; + ret = true; + } + + return ret; +} + +// Gather additional info such as if VCToolset, WinSDKs are installed, location +// of VS and version information. +bool cmVSSetupAPIHelper::GetVSInstanceInfo( + SmartCOMPtr<ISetupInstance2> pInstance, VSInstanceInfo& vsInstanceInfo) +{ + bool isVCToolSetInstalled = false; + if (pInstance == NULL) + return false; + + SmartBSTR bstrId; + if (SUCCEEDED(pInstance->GetInstanceId(&bstrId))) { + vsInstanceInfo.InstanceId = std::wstring(bstrId); + } else { + return false; + } + + InstanceState state; + if (FAILED(pInstance->GetState(&state))) { + return false; + } + + ULONGLONG ullVersion = 0; + SmartBSTR bstrVersion; + if (FAILED(pInstance->GetInstallationVersion(&bstrVersion))) { + return false; + } else { + vsInstanceInfo.Version = std::wstring(bstrVersion); + if (FAILED(setupHelper->ParseVersion(bstrVersion, &ullVersion))) { + vsInstanceInfo.ullVersion = 0; + } else { + vsInstanceInfo.ullVersion = ullVersion; + } + } + + // Reboot may have been required before the installation path was created. + SmartBSTR bstrInstallationPath; + if ((eLocal & state) == eLocal) { + if (FAILED(pInstance->GetInstallationPath(&bstrInstallationPath))) { + return false; + } else { + vsInstanceInfo.VSInstallLocation = std::wstring(bstrInstallationPath); + } + } + + // Reboot may have been required before the product package was registered + // (last). + if ((eRegistered & state) == eRegistered) { + SmartCOMPtr<ISetupPackageReference> product; + if (FAILED(pInstance->GetProduct(&product)) || !product) { + return false; + } + + LPSAFEARRAY lpsaPackages; + if (FAILED(pInstance->GetPackages(&lpsaPackages)) || + lpsaPackages == NULL) { + return false; + } + + int lower = lpsaPackages->rgsabound[0].lLbound; + int upper = lpsaPackages->rgsabound[0].cElements + lower; + + IUnknown** ppData = (IUnknown**)lpsaPackages->pvData; + for (int i = lower; i < upper; i++) { + SmartCOMPtr<ISetupPackageReference> package = NULL; + if (FAILED(ppData[i]->QueryInterface(IID_ISetupPackageReference, + (void**)&package)) || + package == NULL) + continue; + + bool vcToolsetInstalled = false, win10SDKInstalled = false, + win81SDkInstalled = false; + bool ret = CheckInstalledComponent(package, vcToolsetInstalled, + win10SDKInstalled, win81SDkInstalled); + if (ret) { + isVCToolSetInstalled |= vcToolsetInstalled; + vsInstanceInfo.IsWin10SDKInstalled |= win10SDKInstalled; + vsInstanceInfo.IsWin81SDKInstalled |= win81SDkInstalled; + } + } + + SafeArrayDestroy(lpsaPackages); + } + + return isVCToolSetInstalled; +} + +bool cmVSSetupAPIHelper::GetVSInstanceInfo(std::string& vsInstallLocation) +{ + vsInstallLocation = ""; + bool isInstalled = false; + + if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) { + isInstalled = EnumerateAndChooseVSInstance(); + } + + // Enumerate and choose best VS instance + if (chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) { + std::string str(chosenInstanceInfo.VSInstallLocation.begin(), + chosenInstanceInfo.VSInstallLocation.end()); + vsInstallLocation = str; + isInstalled = true; + } + + return isInstalled; +} + +bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() +{ + bool isVSInstanceExists = false; + if (chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) { + return true; + } + + if (initializationFailure || setupConfig == NULL || setupConfig2 == NULL || + setupHelper == NULL) + return false; + + std::vector<VSInstanceInfo> vecVSInstances; + SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL; + if (FAILED( + setupConfig2->EnumInstances((IEnumSetupInstances**)&enumInstances)) || + !enumInstances) { + return false; + } + + SmartCOMPtr<ISetupInstance> instance; + while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) { + SmartCOMPtr<ISetupInstance2> instance2 = NULL; + if (FAILED( + instance->QueryInterface(IID_ISetupInstance2, (void**)&instance2)) || + !instance2) { + instance = NULL; + continue; + } + + VSInstanceInfo instanceInfo; + bool isInstalled = GetVSInstanceInfo(instance2, instanceInfo); + instance = instance2 = NULL; + + if (isInstalled) { + vecVSInstances.push_back(instanceInfo); + } + } + + if (vecVSInstances.size() > 0) { + isVSInstanceExists = true; + int index = ChooseVSInstance(vecVSInstances); + chosenInstanceInfo = vecVSInstances[index]; + } + + return isVSInstanceExists; +} + +int cmVSSetupAPIHelper::ChooseVSInstance( + const std::vector<VSInstanceInfo>& vecVSInstances) +{ + if (vecVSInstances.size() == 0) + return -1; + + if (vecVSInstances.size() == 1) + return 0; + + unsigned int chosenIndex = 0; + for (unsigned int i = 1; i < vecVSInstances.size(); i++) { + // If the current has Win10 SDK but not the chosen one, then choose the + // current VS instance + if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled && + vecVSInstances[i].IsWin10SDKInstalled) { + chosenIndex = i; + continue; + } + + // If the chosen one has Win10 SDK but the current one is not, then look at + // the next VS instance even the current + // instance version may be higher + if (vecVSInstances[chosenIndex].IsWin10SDKInstalled && + !vecVSInstances[i].IsWin10SDKInstalled) { + continue; + } + + // If both chosen one and current one doesn't have Win10 SDK but the + // current one has Win8.1 SDK installed, + // then choose the current one + if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled && + !vecVSInstances[i].IsWin10SDKInstalled && + !vecVSInstances[chosenIndex].IsWin81SDKInstalled && + vecVSInstances[i].IsWin81SDKInstalled) { + chosenIndex = i; + continue; + } + + // If there is no difference in WinSDKs then look for the highest version + // of installed VS + if ((vecVSInstances[chosenIndex].IsWin10SDKInstalled == + vecVSInstances[i].IsWin10SDKInstalled) && + (vecVSInstances[chosenIndex].IsWin81SDKInstalled == + vecVSInstances[i].IsWin81SDKInstalled) && + vecVSInstances[chosenIndex].Version < vecVSInstances[i].Version) { + chosenIndex = i; + continue; + } + } + + return chosenIndex; +} + +bool cmVSSetupAPIHelper::Initialize() +{ + if (initializationFailure) + return false; + + if (FAILED(comInitialized)) { + initializationFailure = true; + return false; + } + + if (FAILED(setupConfig.CoCreateInstance(CLSID_SetupConfiguration, NULL, + IID_ISetupConfiguration, + CLSCTX_INPROC_SERVER)) || + setupConfig == NULL) { + initializationFailure = true; + return false; + } + + if (FAILED(setupConfig.QueryInterface(IID_ISetupConfiguration2, + (void**)&setupConfig2)) || + setupConfig2 == NULL) { + initializationFailure = true; + return false; + } + + if (FAILED( + setupConfig.QueryInterface(IID_ISetupHelper, (void**)&setupHelper)) || + setupHelper == NULL) { + initializationFailure = true; + return false; + } + + initializationFailure = false; + return true; +} diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h new file mode 100644 index 0000000..d2f514c --- /dev/null +++ b/Source/cmVSSetupHelper.h @@ -0,0 +1,154 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmVSSetupHelper_h +#define cmVSSetupHelper_h + +#ifndef NOMINMAX +#define NOMINMAX // Undefine min and max defined by windows.h +#endif + +// Published by Visual Studio Setup team +#include "cmvssetup/Setup.Configuration.h" + +#include <string> +#include <vector> + +#include <windows.h> + +template <class T> +class SmartCOMPtr +{ +public: + SmartCOMPtr() { ptr = NULL; } + SmartCOMPtr(T* p) + { + ptr = p; + if (ptr != NULL) + ptr->AddRef(); + } + SmartCOMPtr(const SmartCOMPtr<T>& sptr) + { + ptr = sptr.ptr; + if (ptr != NULL) + ptr->AddRef(); + } + T** operator&() { return &ptr; } + T* operator->() { return ptr; } + T* operator=(T* p) + { + if (*this != p) { + ptr = p; + if (ptr != NULL) + ptr->AddRef(); + } + return *this; + } + operator T*() const { return ptr; } + template <class I> + HRESULT QueryInterface(REFCLSID rclsid, I** pp) + { + if (pp != NULL) { + return ptr->QueryInterface(rclsid, (void**)pp); + } else { + return E_FAIL; + } + } + HRESULT CoCreateInstance(REFCLSID clsid, IUnknown* pUnknown, + REFIID interfaceId, DWORD dwClsContext = CLSCTX_ALL) + { + HRESULT hr = ::CoCreateInstance(clsid, pUnknown, dwClsContext, interfaceId, + (void**)&ptr); + return hr; + } + ~SmartCOMPtr() + { + if (ptr != NULL) + ptr->Release(); + } + +private: + T* ptr; +}; + +class SmartBSTR +{ +public: + SmartBSTR() { str = NULL; } + SmartBSTR(const SmartBSTR& src) + { + if (src.str != NULL) { + str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str)); + } else { + str = ::SysAllocStringByteLen(NULL, 0); + } + } + SmartBSTR& operator=(const SmartBSTR& src) + { + if (str != src.str) { + ::SysFreeString(str); + if (src.str != NULL) { + str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str)); + } else { + str = ::SysAllocStringByteLen(NULL, 0); + } + } + return *this; + } + operator BSTR() const { return str; } + BSTR* operator&() throw() { return &str; } + ~SmartBSTR() throw() { ::SysFreeString(str); } +private: + BSTR str; +}; + +struct VSInstanceInfo +{ + std::wstring InstanceId; + std::wstring VSInstallLocation; + std::wstring Version; + ULONGLONG ullVersion; + bool IsWin10SDKInstalled; + bool IsWin81SDKInstalled; + + VSInstanceInfo() + { + InstanceId = VSInstallLocation = Version = L""; + ullVersion = 0; + IsWin10SDKInstalled = IsWin81SDKInstalled = false; + } +}; + +class cmVSSetupAPIHelper +{ +public: + cmVSSetupAPIHelper(); + ~cmVSSetupAPIHelper(); + + bool IsVS2017Installed(); + bool GetVSInstanceInfo(std::string& vsInstallLocation); + bool IsWin10SDKInstalled(); + bool IsWin81SDKInstalled(); + +private: + bool Initialize(); + bool GetVSInstanceInfo(SmartCOMPtr<ISetupInstance2> instance2, + VSInstanceInfo& vsInstanceInfo); + bool CheckInstalledComponent(SmartCOMPtr<ISetupPackageReference> package, + bool& bVCToolset, bool& bWin10SDK, + bool& bWin81SDK); + int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances); + bool EnumerateAndChooseVSInstance(); + + // COM ptrs to query about VS instances + SmartCOMPtr<ISetupConfiguration> setupConfig; + SmartCOMPtr<ISetupConfiguration2> setupConfig2; + SmartCOMPtr<ISetupHelper> setupHelper; + // used to indicate failure in Initialize(), so we don't have to call again + bool initializationFailure; + // indicated if COM initialization is successful + HRESULT comInitialized; + // current best instance of VS selected + VSInstanceInfo chosenInstanceInfo; +}; + +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 733e0e4..6141f50 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -64,6 +64,7 @@ #include "cmGlobalVisualStudio71Generator.h" #include "cmGlobalVisualStudio8Generator.h" #include "cmGlobalVisualStudio9Generator.h" +#include "cmVSSetupHelper.h" #define CMAKE_HAVE_VS_GENERATORS #endif @@ -1470,18 +1471,23 @@ void cmake::CreateDefaultGlobalGenerator() "\\Setup\\VC;ProductDir", // ";InstallDir" // }; - for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators); - found.empty() && g != cmArrayEnd(vsGenerators); ++g) { - for (const char* const* v = cmArrayBegin(vsVariants); - found.empty() && v != cmArrayEnd(vsVariants); ++v) { - for (const char* const* e = cmArrayBegin(vsEntries); - found.empty() && e != cmArrayEnd(vsEntries); ++e) { - std::string const reg = vsregBase + *v + g->MSVersion + *e; - std::string dir; - if (cmSystemTools::ReadRegistryValue(reg, dir, - cmSystemTools::KeyWOW64_32) && - cmSystemTools::PathExists(dir)) { - found = g->GeneratorName; + cmVSSetupAPIHelper vsSetupAPIHelper; + if (vsSetupAPIHelper.IsVS2017Installed()) { + found = "Visual Studio 15 2017"; + } else { + for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators); + found.empty() && g != cmArrayEnd(vsGenerators); ++g) { + for (const char* const* v = cmArrayBegin(vsVariants); + found.empty() && v != cmArrayEnd(vsVariants); ++v) { + for (const char* const* e = cmArrayBegin(vsEntries); + found.empty() && e != cmArrayEnd(vsEntries); ++e) { + std::string const reg = vsregBase + *v + g->MSVersion + *e; + std::string dir; + if (cmSystemTools::ReadRegistryValue(reg, dir, + cmSystemTools::KeyWOW64_32) && + cmSystemTools::PathExists(dir)) { + found = g->GeneratorName; + } } } } diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in index 1313dbf..d6d2357 100644 --- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in +++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in @@ -518,6 +518,13 @@ set(msys_g77_libs "frtbegin;g2c;mingw32;moldname;mingwex;msvcrt;user32;kernel32; set(msys_g77_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib") list(APPEND platforms msys_g77) +#----------------------------------------------------------------------------- +# MSVC from NVIDIA CUDA + +set(nvcc_msvc_text [[cuda-fake-ld cl.exe -nologo "tmp/a_dlink.obj" "tmp/CMakeCUDACompilerId.obj" -link -INCREMENTAL:NO "/LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/../lib/x64" cudadevrt.lib cudart_static.lib -Fe"a.exe"]]) +set(nvcc_msvc_libs "cudadevrt.lib;cudart_static.lib") +set(nvcc_msvc_dirs "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/x64") +list(APPEND platforms nvcc_msvc) #----------------------------------------------------------------------------- # Test parsing for all above examples. diff --git a/Tests/CTestTestLaunchers/launcher_compiler_test_project/CMakeLists.txt b/Tests/CTestTestLaunchers/launcher_compiler_test_project/CMakeLists.txt new file mode 100644 index 0000000..7376a40 --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_compiler_test_project/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(launcher_compiler_test_project) + +include(CTest) + +add_executable(build_error build_error.cxx) diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_compiler_test_project/CTestConfig.cmake index 669b0fb..669b0fb 100644 --- a/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake +++ b/Tests/CTestTestLaunchers/launcher_compiler_test_project/CTestConfig.cmake diff --git a/Tests/CTestTestLaunchers/launcher_compiler_test_project/build_error.cxx b/Tests/CTestTestLaunchers/launcher_compiler_test_project/build_error.cxx new file mode 100644 index 0000000..2d51693 --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_compiler_test_project/build_error.cxx @@ -0,0 +1,5 @@ +int main() +{ + int = 3; + return; +} diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CMakeLists.txt index 06c5725..b31f587 100644 --- a/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt +++ b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.8.12) -project(launcher_test_project) +project(launcher_custom_command_test_project) include(CTest) diff --git a/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake new file mode 100644 index 0000000..669b0fb --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/CTestConfig.cmake @@ -0,0 +1,8 @@ +set(CTEST_USE_LAUNCHERS 1) +set(CTEST_PROJECT_NAME "CTestTestLaunchers") +set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") +set(CTEST_DART_SERVER_VERSION "2") +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "open.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Tests/CTestTestLaunchers/launcher_test_project/command.cmake b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/command.cmake index 7f31af9..7f31af9 100644 --- a/Tests/CTestTestLaunchers/launcher_test_project/command.cmake +++ b/Tests/CTestTestLaunchers/launcher_custom_command_test_project/command.cmake diff --git a/Tests/CTestTestLaunchers/launcher_linker_test_project/CMakeLists.txt b/Tests/CTestTestLaunchers/launcher_linker_test_project/CMakeLists.txt new file mode 100644 index 0000000..38980aa --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_linker_test_project/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(launcher_linker_test_project) + +include(CTest) + +add_executable(link_error link_error.cxx) diff --git a/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake new file mode 100644 index 0000000..669b0fb --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_linker_test_project/CTestConfig.cmake @@ -0,0 +1,8 @@ +set(CTEST_USE_LAUNCHERS 1) +set(CTEST_PROJECT_NAME "CTestTestLaunchers") +set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") +set(CTEST_DART_SERVER_VERSION "2") +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "open.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Tests/CTestTestLaunchers/launcher_linker_test_project/link_error.cxx b/Tests/CTestTestLaunchers/launcher_linker_test_project/link_error.cxx new file mode 100644 index 0000000..c879be1 --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_linker_test_project/link_error.cxx @@ -0,0 +1,6 @@ +extern int foo(); + +int main() +{ + return foo(); +} diff --git a/Tests/CTestTestLaunchers/test.cmake.in b/Tests/CTestTestLaunchers/test.cmake.in index 03a118a..2db1ddd 100644 --- a/Tests/CTestTestLaunchers/test.cmake.in +++ b/Tests/CTestTestLaunchers/test.cmake.in @@ -1,39 +1,51 @@ cmake_minimum_required(VERSION 2.8.12) -# Settings: -set(CTEST_DASHBOARD_SOURCE "@CMake_SOURCE_DIR@/Tests/CTestTestLaunchers") -set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTestLaunchers") -set(CTEST_SITE "@SITE@") -set(CTEST_BUILD_NAME "Launchers-@BUILDNAME@-CTestTestLaunchers") - -set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_SOURCE}/launcher_test_project") -set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/launcher_test_project-bin") -set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") -set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@") -set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@") -set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") -set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") - -ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) - -file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" " -CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@ -CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@ -CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@ -CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@ -CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@ -CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@ -") - -set(TEST_SUCCESS FALSE) - -ctest_start(Experimental) -ctest_configure(OPTIONS "-DCTEST_USE_LAUNCHERS=1") -ctest_build(NUMBER_ERRORS error_count) - -if("${error_count}" STREQUAL "1") - set(TEST_SUCCESS TRUE) -endif() +set(TEST_SUCCESS TRUE) + +function(run_test_case NAME WHAT) + set(_message "Testing that launchers are used when running ${WHAT}") + message(STATUS "${_message}...") + + # Settings: + set(CTEST_DASHBOARD_SOURCE "@CMake_SOURCE_DIR@/Tests/CTestTestLaunchers") + set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTestLaunchers") + set(CTEST_SITE "@SITE@") + set(CTEST_BUILD_NAME "Launchers-@BUILDNAME@-CTestTestLaunchers") + + set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_SOURCE}/${NAME}") + set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${NAME}-bin") + set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") + set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@") + set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@") + set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") + set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") + + ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) + + file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" " + CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@ + CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@ + CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@ + CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@ + CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@ + CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@ + ") + + ctest_start(Experimental) + ctest_configure(OPTIONS "-DCTEST_USE_LAUNCHERS=1") + ctest_build(NUMBER_ERRORS error_count) + + if("${error_count}" STREQUAL "0") + set(TEST_SUCCESS FALSE PARENT_SCOPE) + message(STATUS "${_message}... FAIL") + else() + message(STATUS "${_message}... PASS") + endif() +endfunction() + +run_test_case(launcher_compiler_test_project "the compiler") +run_test_case(launcher_linker_test_project "the linker") +run_test_case(launcher_custom_command_test_project "a custom command") if(TEST_SUCCESS) message("CTEST_TEST_LAUNCHER_SUCCESS") diff --git a/Tests/Cuda/Complex/dynamic.cpp b/Tests/Cuda/Complex/dynamic.cpp index d579f1e..3848ce7 100644 --- a/Tests/Cuda/Complex/dynamic.cpp +++ b/Tests/Cuda/Complex/dynamic.cpp @@ -1,5 +1,11 @@ -int dynamic_base_func(int x) +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + +EXPORT int dynamic_base_func(int x) { return x * x; } diff --git a/Tests/Cuda/Complex/dynamic.cu b/Tests/Cuda/Complex/dynamic.cu index ea52acb..a23dc25 100644 --- a/Tests/Cuda/Complex/dynamic.cu +++ b/Tests/Cuda/Complex/dynamic.cu @@ -3,9 +3,15 @@ #include <cuda.h> #include <iostream> +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + int dynamic_base_func(int); -int __host__ cuda_dynamic_host_func(int x) +EXPORT int __host__ cuda_dynamic_host_func(int x) { return dynamic_base_func(x); } @@ -16,7 +22,7 @@ void DetermineIfValidCudaDevice() { } -void cuda_dynamic_lib_func() +EXPORT void cuda_dynamic_lib_func() { DetermineIfValidCudaDevice <<<1,1>>> (); cudaError_t err = cudaGetLastError(); diff --git a/Tests/Cuda/Complex/main.cpp b/Tests/Cuda/Complex/main.cpp index 32312d0..5a3f820 100644 --- a/Tests/Cuda/Complex/main.cpp +++ b/Tests/Cuda/Complex/main.cpp @@ -3,8 +3,14 @@ #include "file1.h" #include "file2.h" -int call_cuda_seperable_code(int x); -int mixed_launch_kernel(int x); +#ifdef _WIN32 +#define IMPORT __declspec(dllimport) +#else +#define IMPORT +#endif + +IMPORT int call_cuda_seperable_code(int x); +IMPORT int mixed_launch_kernel(int x); int main(int argc, char** argv) { diff --git a/Tests/Cuda/Complex/mixed.cpp b/Tests/Cuda/Complex/mixed.cpp index 205f091..bd32e51 100644 --- a/Tests/Cuda/Complex/mixed.cpp +++ b/Tests/Cuda/Complex/mixed.cpp @@ -1,6 +1,14 @@ +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#define IMPORT __declspec(dllimport) +#else +#define EXPORT +#define IMPORT +#endif + int dynamic_base_func(int); -int cuda_dynamic_host_func(int); +IMPORT int cuda_dynamic_host_func(int); int file3_launch_kernel(int); int dynamic_final_func(int x) @@ -8,7 +16,7 @@ int dynamic_final_func(int x) return cuda_dynamic_host_func(dynamic_base_func(x)); } -int call_cuda_seperable_code(int x) +EXPORT int call_cuda_seperable_code(int x) { return file3_launch_kernel(x); } diff --git a/Tests/Cuda/Complex/mixed.cu b/Tests/Cuda/Complex/mixed.cu index 45b412f..7051de0 100644 --- a/Tests/Cuda/Complex/mixed.cu +++ b/Tests/Cuda/Complex/mixed.cu @@ -4,10 +4,18 @@ #include "file1.h" #include "file2.h" +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#define IMPORT __declspec(dllimport) +#else +#define EXPORT +#define IMPORT +#endif + result_type __device__ file1_func(int x); result_type_dynamic __device__ file2_func(int x); -void __host__ cuda_dynamic_lib_func(); +IMPORT void __host__ cuda_dynamic_lib_func(); static __global__ @@ -17,7 +25,7 @@ void mixed_kernel(result_type& r, int x) result_type_dynamic rd = file2_func(x); } -int mixed_launch_kernel(int x) +EXPORT int mixed_launch_kernel(int x) { cuda_dynamic_lib_func(); diff --git a/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt b/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt index 8361b9e..9fda2d0 100644 --- a/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt +++ b/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt @@ -11,7 +11,7 @@ project (CudaConsumeCompileFeatures CXX CUDA) add_library(CudaConsumeLib STATIC static.cpp static.cu) -target_compile_features(CudaConsumeLib PUBLIC cxx_constexpr) +target_compile_features(CudaConsumeLib PUBLIC cxx_nullptr) add_executable(CudaConsumeCompileFeatures main.cu) target_link_libraries(CudaConsumeCompileFeatures PRIVATE CudaConsumeLib) diff --git a/Tests/CudaOnly/EnableStandard/main.cu b/Tests/CudaOnly/EnableStandard/main.cu index 83e9dfd..f7144e6 100644 --- a/Tests/CudaOnly/EnableStandard/main.cu +++ b/Tests/CudaOnly/EnableStandard/main.cu @@ -1,8 +1,14 @@ #include <iostream> +#ifdef _WIN32 +#define IMPORT __declspec(dllimport) +#else +#define IMPORT +#endif + int static_cuda11_func(int); -int shared_cuda11_func(int); +IMPORT int shared_cuda11_func(int); void test_functions() { diff --git a/Tests/CudaOnly/EnableStandard/shared.cu b/Tests/CudaOnly/EnableStandard/shared.cu index 28555b3..ccdd0b2 100644 --- a/Tests/CudaOnly/EnableStandard/shared.cu +++ b/Tests/CudaOnly/EnableStandard/shared.cu @@ -1,9 +1,15 @@ #include <type_traits> +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + using tt = std::true_type; using ft = std::false_type; -int __host__ shared_cuda11_func(int x) +EXPORT int __host__ shared_cuda11_func(int x) { return x * x + std::integral_constant<int, 17>::value; } diff --git a/Tests/CudaOnly/SeparateCompilation/main.cu b/Tests/CudaOnly/SeparateCompilation/main.cu index d4520ae..5c8e150 100644 --- a/Tests/CudaOnly/SeparateCompilation/main.cu +++ b/Tests/CudaOnly/SeparateCompilation/main.cu @@ -4,12 +4,12 @@ #include "file1.h" #include "file2.h" -// result_type file4_launch_kernel(int x); -// result_type file5_launch_kernel(int x); +int file4_launch_kernel(int x); +int file5_launch_kernel(int x); int main(int argc, char **argv) { - // file4_launch_kernel(42); - // file5_launch_kernel(42); + file4_launch_kernel(42); + file5_launch_kernel(42); return 0; } diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt index c4ca8b9..6c4011c 100644 --- a/Tests/CudaOnly/WithDefs/CMakeLists.txt +++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt @@ -4,7 +4,12 @@ project (CudaOnlyWithDefs CUDA) #verify that we can pass explicit cuda arch flags set(CMAKE_CUDA_FLAGS "-gencode arch=compute_30,code=compute_30") -set(debug_compile_flags --generate-code arch=compute_20,code=sm_20 -Xcompiler=-Werror) +set(debug_compile_flags --generate-code arch=compute_20,code=sm_20) +if(CMAKE_CUDA_SIMULATE_ID STREQUAL "MSVC") + list(APPEND debug_compile_flags -Xcompiler=-WX) +else() + list(APPEND debug_compile_flags -Xcompiler=-Werror) +endif() set(release_compile_defs DEFREL) #Goal for this example: diff --git a/Tests/CudaOnly/WithDefs/main.notcu b/Tests/CudaOnly/WithDefs/main.notcu index 33a49d2..67bf10c 100644 --- a/Tests/CudaOnly/WithDefs/main.notcu +++ b/Tests/CudaOnly/WithDefs/main.notcu @@ -2,12 +2,21 @@ #include <cuda_runtime.h> #include <iostream> +#ifndef PACKED_DEFINE +#error "PACKED_DEFINE not defined!" +#endif + static __global__ void DetermineIfValidCudaDevice() { } +#ifdef _MSC_VER +#pragma pack(push,1) +#undef PACKED_DEFINE +#define PACKED_DEFINE +#endif struct PACKED_DEFINE result_type { bool valid; @@ -16,6 +25,9 @@ struct PACKED_DEFINE result_type #error missing DEFREL flag #endif }; +#ifdef _MSC_VER +#pragma pack(pop) +#endif result_type can_launch_kernel() { diff --git a/Tests/RunCMake/try_compile/CudaStandardNoDefault.cmake b/Tests/RunCMake/try_compile/CudaStandardNoDefault.cmake new file mode 100644 index 0000000..ea22152 --- /dev/null +++ b/Tests/RunCMake/try_compile/CudaStandardNoDefault.cmake @@ -0,0 +1,9 @@ +enable_language(CUDA) +try_compile(result ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cu + CUDA_STANDARD 3 # bogus, but not used + OUTPUT_VARIABLE out + ) +if(NOT result) + message(FATAL_ERROR "try_compile failed:\n${out}") +endif() diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake index 5452e6d..6a1bc64 100644 --- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -36,7 +36,11 @@ elseif(DEFINED CMAKE_CXX_STANDARD_DEFAULT) run_cmake(CxxStandardNoDefault) endif() if(CMake_TEST_CUDA) - run_cmake(CudaStandard) + if(CMAKE_HOST_WIN32) + run_cmake(CudaStandardNoDefault) + else() + run_cmake(CudaStandard) + endif() endif() if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) run_cmake(CStandardGNU) diff --git a/Utilities/cmvssetup/.gitattributes b/Utilities/cmvssetup/.gitattributes new file mode 100644 index 0000000..562b12e --- /dev/null +++ b/Utilities/cmvssetup/.gitattributes @@ -0,0 +1 @@ +* -whitespace diff --git a/Utilities/cmvssetup/Setup.Configuration.h b/Utilities/cmvssetup/Setup.Configuration.h new file mode 100644 index 0000000..6c9d8f9 --- /dev/null +++ b/Utilities/cmvssetup/Setup.Configuration.h @@ -0,0 +1,991 @@ +// <copyright file="Setup.Configuration.h" company="Microsoft Corporation"> +// Copyright (C) Microsoft Corporation. All rights reserved. +// </copyright> + +// This file is licensed under "The MIT License(MIT)". +// This file is released by Visual Studio setup team for consumption by external applications. +// For more information please look at this git repo https://github.com/microsoft/vs-setup-samples + +#ifndef SetupConfiguration_h +#define SetupConfiguration_h + +#include <objbase.h> + +// Constants +// +#ifndef E_NOTFOUND +#define E_NOTFOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND) +#endif + +#ifndef E_FILENOTFOUND +#define E_FILENOTFOUND HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) + +#ifndef _Outptr_result_maybenull_ +#define _Outptr_result_maybenull_ +#endif +#ifndef _Out_writes_to_ +#define _Out_writes_to_(x,y) +#endif +#ifndef _Reserved_ +#define _Reserved_ +#endif +#ifndef MAXUINT +#define MAXUINT ((UINT)~((UINT)0)) +#endif + +// Enumerations +// +/// <summary> +/// The state of an instance. +/// </summary> +enum InstanceState +{ + /// <summary> + /// The instance state has not been determined. + /// </summary> + eNone = 0, + + /// <summary> + /// The instance installation path exists. + /// </summary> + eLocal = 1, + + /// <summary> + /// A product is registered to the instance. + /// </summary> + eRegistered = 2, + + /// <summary> + /// No reboot is required for the instance. + /// </summary> + eNoRebootRequired = 4, + + /// <summary> + /// The instance represents a complete install. + /// </summary> + eComplete = MAXUINT, +}; + +// Forward interface declarations +// +#ifndef __ISetupInstance_FWD_DEFINED__ +#define __ISetupInstance_FWD_DEFINED__ +typedef struct ISetupInstance ISetupInstance; +#endif + +#ifndef __ISetupInstance2_FWD_DEFINED__ +#define __ISetupInstance2_FWD_DEFINED__ +typedef struct ISetupInstance2 ISetupInstance2; +#endif + +#ifndef __IEnumSetupInstances_FWD_DEFINED__ +#define __IEnumSetupInstances_FWD_DEFINED__ +typedef struct IEnumSetupInstances IEnumSetupInstances; +#endif + +#ifndef __ISetupConfiguration_FWD_DEFINED__ +#define __ISetupConfiguration_FWD_DEFINED__ +typedef struct ISetupConfiguration ISetupConfiguration; +#endif + +#ifndef __ISetupConfiguration2_FWD_DEFINED__ +#define __ISetupConfiguration2_FWD_DEFINED__ +typedef struct ISetupConfiguration2 ISetupConfiguration2; +#endif + +#ifndef __ISetupPackageReference_FWD_DEFINED__ +#define __ISetupPackageReference_FWD_DEFINED__ +typedef struct ISetupPackageReference ISetupPackageReference; +#endif + +#ifndef __ISetupHelper_FWD_DEFINED__ +#define __ISetupHelper_FWD_DEFINED__ +typedef struct ISetupHelper ISetupHelper; +#endif + +// Forward class declarations +// +#ifndef __SetupConfiguration_FWD_DEFINED__ +#define __SetupConfiguration_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class SetupConfiguration SetupConfiguration; +#endif + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// Interface definitions +// +EXTERN_C const IID IID_ISetupInstance; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// Information about an instance of a product. +/// </summary> +struct DECLSPEC_UUID("B41463C3-8866-43B5-BC33-2B0676F7F42E") DECLSPEC_NOVTABLE ISetupInstance : public IUnknown +{ + /// <summary> + /// Gets the instance identifier (should match the name of the parent instance directory). + /// </summary> + /// <param name="pbstrInstanceId">The instance identifier.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist.</returns> + STDMETHOD(GetInstanceId)( + _Out_ BSTR* pbstrInstanceId + ) = 0; + + /// <summary> + /// Gets the local date and time when the installation was originally installed. + /// </summary> + /// <param name="pInstallDate">The local date and time when the installation was originally installed.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallDate)( + _Out_ LPFILETIME pInstallDate + ) = 0; + + /// <summary> + /// Gets the unique name of the installation, often indicating the branch and other information used for telemetry. + /// </summary> + /// <param name="pbstrInstallationName">The unique name of the installation, often indicating the branch and other information used for telemetry.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallationName)( + _Out_ BSTR* pbstrInstallationName + ) = 0; + + /// <summary> + /// Gets the path to the installation root of the product. + /// </summary> + /// <param name="pbstrInstallationPath">The path to the installation root of the product.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallationPath)( + _Out_ BSTR* pbstrInstallationPath + ) = 0; + + /// <summary> + /// Gets the version of the product installed in this instance. + /// </summary> + /// <param name="pbstrInstallationVersion">The version of the product installed in this instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallationVersion)( + _Out_ BSTR* pbstrInstallationVersion + ) = 0; + + /// <summary> + /// Gets the display name (title) of the product installed in this instance. + /// </summary> + /// <param name="lcid">The LCID for the display name.</param> + /// <param name="pbstrDisplayName">The display name (title) of the product installed in this instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetDisplayName)( + _In_ LCID lcid, + _Out_ BSTR* pbstrDisplayName + ) = 0; + + /// <summary> + /// Gets the description of the product installed in this instance. + /// </summary> + /// <param name="lcid">The LCID for the description.</param> + /// <param name="pbstrDescription">The description of the product installed in this instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetDescription)( + _In_ LCID lcid, + _Out_ BSTR* pbstrDescription + ) = 0; + + /// <summary> + /// Resolves the optional relative path to the root path of the instance. + /// </summary> + /// <param name="pwszRelativePath">A relative path within the instance to resolve, or NULL to get the root path.</param> + /// <param name="pbstrAbsolutePath">The full path to the optional relative path within the instance. If the relative path is NULL, the root path will always terminate in a backslash.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(ResolvePath)( + _In_opt_z_ LPCOLESTR pwszRelativePath, + _Out_ BSTR* pbstrAbsolutePath + ) = 0; +}; +#endif + +EXTERN_C const IID IID_ISetupInstance2; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// Information about an instance of a product. +/// </summary> +struct DECLSPEC_UUID("89143C9A-05AF-49B0-B717-72E218A2185C") DECLSPEC_NOVTABLE ISetupInstance2 : public ISetupInstance +{ + /// <summary> + /// Gets the state of the instance. + /// </summary> + /// <param name="pState">The state of the instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist.</returns> + STDMETHOD(GetState)( + _Out_ InstanceState* pState + ) = 0; + + /// <summary> + /// Gets an array of package references registered to the instance. + /// </summary> + /// <param name="ppsaPackages">Pointer to an array of <see cref="ISetupPackageReference"/>.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the packages property is not defined.</returns> + STDMETHOD(GetPackages)( + _Out_ LPSAFEARRAY* ppsaPackages + ) = 0; + + /// <summary> + /// Gets a pointer to the <see cref="ISetupPackageReference"/> that represents the registered product. + /// </summary> + /// <param name="ppPackage">Pointer to an instance of <see cref="ISetupPackageReference"/>. This may be NULL if <see cref="GetState"/> does not return <see cref="eComplete"/>.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the packages property is not defined.</returns> + STDMETHOD(GetProduct)( + _Outptr_result_maybenull_ ISetupPackageReference** ppPackage + ) = 0; + + /// <summary> + /// Gets the relative path to the product application, if available. + /// </summary> + /// <param name="pbstrProductPath">The relative path to the product application, if available.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist.</returns> + STDMETHOD(GetProductPath)( + _Outptr_result_maybenull_ BSTR* pbstrProductPath + ) = 0; +}; +#endif + +EXTERN_C const IID IID_IEnumSetupInstances; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// A enumerator of installed <see cref="ISetupInstance"/> objects. +/// </summary> +struct DECLSPEC_UUID("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848") DECLSPEC_NOVTABLE IEnumSetupInstances : public IUnknown +{ + /// <summary> + /// Retrieves the next set of product instances in the enumeration sequence. + /// </summary> + /// <param name="celt">The number of product instances to retrieve.</param> + /// <param name="rgelt">A pointer to an array of <see cref="ISetupInstance"/>.</param> + /// <param name="pceltFetched">A pointer to the number of product instances retrieved. If celt is 1 this parameter may be NULL.</param> + /// <returns>S_OK if the number of elements were fetched, S_FALSE if nothing was fetched (at end of enumeration), E_INVALIDARG if celt is greater than 1 and pceltFetched is NULL, or E_OUTOFMEMORY if an <see cref="ISetupInstance"/> could not be allocated.</returns> + STDMETHOD(Next)( + _In_ ULONG celt, + _Out_writes_to_(celt, *pceltFetched) ISetupInstance** rgelt, + _Out_opt_ _Deref_out_range_(0, celt) ULONG* pceltFetched + ) = 0; + + /// <summary> + /// Skips the next set of product instances in the enumeration sequence. + /// </summary> + /// <param name="celt">The number of product instances to skip.</param> + /// <returns>S_OK if the number of elements could be skipped; otherwise, S_FALSE;</returns> + STDMETHOD(Skip)( + _In_ ULONG celt + ) = 0; + + /// <summary> + /// Resets the enumeration sequence to the beginning. + /// </summary> + /// <returns>Always returns S_OK;</returns> + STDMETHOD(Reset)(void) = 0; + + /// <summary> + /// Creates a new enumeration object in the same state as the current enumeration object: the new object points to the same place in the enumeration sequence. + /// </summary> + /// <param name="ppenum">A pointer to a pointer to a new <see cref="IEnumSetupInstances"/> interface. If the method fails, this parameter is undefined.</param> + /// <returns>S_OK if a clone was returned; otherwise, E_OUTOFMEMORY.</returns> + STDMETHOD(Clone)( + _Deref_out_opt_ IEnumSetupInstances** ppenum + ) = 0; +}; +#endif + +EXTERN_C const IID IID_ISetupConfiguration; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// Gets information about product instances set up on the machine. +/// </summary> +struct DECLSPEC_UUID("42843719-DB4C-46C2-8E7C-64F1816EFD5B") DECLSPEC_NOVTABLE ISetupConfiguration : public IUnknown +{ + /// <summary> + /// Enumerates all completed product instances installed. + /// </summary> + /// <param name="ppEnumInstances">An enumeration of completed, installed product instances.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(EnumInstances)( + _Out_ IEnumSetupInstances** ppEnumInstances + ) = 0; + + /// <summary> + /// Gets the instance for the current process path. + /// </summary> + /// <param name="ppInstance">The instance for the current process path.</param> + /// <returns>The instance for the current process path, or E_NOTFOUND if not found.</returns> + STDMETHOD(GetInstanceForCurrentProcess)( + _Out_ ISetupInstance** ppInstance + ) = 0; + + /// <summary> + /// Gets the instance for the given path. + /// </summary> + /// <param name="ppInstance">The instance for the given path.</param> + /// <returns>The instance for the given path, or E_NOTFOUND if not found.</returns> + STDMETHOD(GetInstanceForPath)( + _In_z_ LPCWSTR wzPath, + _Out_ ISetupInstance** ppInstance + ) = 0; +}; +#endif + +EXTERN_C const IID IID_ISetupConfiguration2; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// Gets information about product instances. +/// </summary> +struct DECLSPEC_UUID("26AAB78C-4A60-49D6-AF3B-3C35BC93365D") DECLSPEC_NOVTABLE ISetupConfiguration2 : public ISetupConfiguration +{ + /// <summary> + /// Enumerates all product instances. + /// </summary> + /// <param name="ppEnumInstances">An enumeration of all product instances.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(EnumAllInstances)( + _Out_ IEnumSetupInstances** ppEnumInstances + ) = 0; +}; +#endif + +EXTERN_C const IID IID_ISetupPackageReference; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// A reference to a package. +/// </summary> +struct DECLSPEC_UUID("da8d8a16-b2b6-4487-a2f1-594ccccd6bf5") DECLSPEC_NOVTABLE ISetupPackageReference : public IUnknown +{ + /// <summary> + /// Gets the general package identifier. + /// </summary> + /// <param name="pbstrId">The general package identifier.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetId)( + _Out_ BSTR* pbstrId + ) = 0; + + /// <summary> + /// Gets the version of the package. + /// </summary> + /// <param name="pbstrVersion">The version of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetVersion)( + _Out_ BSTR* pbstrVersion + ) = 0; + + /// <summary> + /// Gets the target process architecture of the package. + /// </summary> + /// <param name="pbstrChip">The target process architecture of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetChip)( + _Out_ BSTR* pbstrChip + ) = 0; + + /// <summary> + /// Gets the language and optional region identifier. + /// </summary> + /// <param name="pbstrLanguage">The language and optional region identifier.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetLanguage)( + _Out_ BSTR* pbstrLanguage + ) = 0; + + /// <summary> + /// Gets the build branch of the package. + /// </summary> + /// <param name="pbstrBranch">The build branch of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetBranch)( + _Out_ BSTR* pbstrBranch + ) = 0; + + /// <summary> + /// Gets the type of the package. + /// </summary> + /// <param name="pbstrType">The type of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetType)( + _Out_ BSTR* pbstrType + ) = 0; + + /// <summary> + /// Gets the unique identifier consisting of all defined tokens. + /// </summary> + /// <param name="pbstrUniqueId">The unique identifier consisting of all defined tokens.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_UNEXPECTED if no Id was defined (required).</returns> + STDMETHOD(GetUniqueId)( + _Out_ BSTR* pbstrUniqueId + ) = 0; +}; +#endif + +EXTERN_C const IID IID_ISetupHelper; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/// <summary> +/// Helper functions. +/// </summary> +/// <remarks> +/// You can query for this interface from the <see cref="SetupConfiguration"/> class. +/// </remarks> +struct DECLSPEC_UUID("42b21b78-6192-463e-87bf-d577838f1d5c") DECLSPEC_NOVTABLE ISetupHelper : public IUnknown +{ + /// <summary> + /// Parses a dotted quad version string into a 64-bit unsigned integer. + /// </summary> + /// <param name="pwszVersion">The dotted quad version string to parse, e.g. 1.2.3.4.</param> + /// <param name="pullVersion">A 64-bit unsigned integer representing the version. You can compare this to other versions.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(ParseVersion)( + _In_ LPCOLESTR pwszVersion, + _Out_ PULONGLONG pullVersion + ) = 0; + + /// <summary> + /// Parses a dotted quad version string into a 64-bit unsigned integer. + /// </summary> + /// <param name="pwszVersionRange">The string containing 1 or 2 dotted quad version strings to parse, e.g. [1.0,) that means 1.0.0.0 or newer.</param> + /// <param name="pullMinVersion">A 64-bit unsigned integer representing the minimum version, which may be 0. You can compare this to other versions.</param> + /// <param name="pullMaxVersion">A 64-bit unsigned integer representing the maximum version, which may be MAXULONGLONG. You can compare this to other versions.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(ParseVersionRange)( + _In_ LPCOLESTR pwszVersionRange, + _Out_ PULONGLONG pullMinVersion, + _Out_ PULONGLONG pullMaxVersion + ) = 0; +}; +#endif + +// Class declarations +// +EXTERN_C const CLSID CLSID_SetupConfiguration; + +#ifdef __cplusplus +/// <summary> +/// This class implements <see cref="ISetupConfiguration"/>, <see cref="ISetupConfiguration2"/>, and <see cref="ISetupHelper"/>. +/// </summary> +class DECLSPEC_UUID("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D") SetupConfiguration; +#endif + +// Function declarations +// +/// <summary> +/// Gets an <see cref="ISetupConfiguration"/> that provides information about product instances installed on the machine. +/// </summary> +/// <param name="ppConfiguration">The <see cref="ISetupConfiguration"/> that provides information about product instances installed on the machine.</param> +/// <param name="pReserved">Reserved for future use.</param> +/// <returns>Standard HRESULT indicating success or failure.</returns> +STDMETHODIMP GetSetupConfiguration( + _Out_ ISetupConfiguration** ppConfiguration, + _Reserved_ LPVOID pReserved +); + +#ifdef __cplusplus +} +#endif + +#else + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#define VS_SETUP_GCC_DIAGNOSTIC_PUSHED +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif + +#ifndef MAXUINT +#define MAXUINT ((UINT)~((UINT)0)) +#endif + +#ifndef DECLSPEC_NOVTABLE +#if (_MSC_VER >= 1100) && defined(__cplusplus) +#define DECLSPEC_NOVTABLE __declspec(novtable) +#else +#define DECLSPEC_NOVTABLE +#endif +#endif + +// Enumerations +// +/// <summary> +/// The state of an instance. +/// </summary> +enum InstanceState +{ + /// <summary> + /// The instance state has not been determined. + /// </summary> + eNone = 0, + + /// <summary> + /// The instance installation path exists. + /// </summary> + eLocal = 1, + + /// <summary> + /// A product is registered to the instance. + /// </summary> + eRegistered = 2, + + /// <summary> + /// No reboot is required for the instance. + /// </summary> + eNoRebootRequired = 4, + + /// <summary> + /// The instance represents a complete install. + /// </summary> + eComplete = MAXUINT, +}; + +// Forward interface declarations +// +#ifndef __ISetupInstance_FWD_DEFINED__ +#define __ISetupInstance_FWD_DEFINED__ +typedef struct ISetupInstance ISetupInstance; +#endif + +#ifndef __ISetupInstance2_FWD_DEFINED__ +#define __ISetupInstance2_FWD_DEFINED__ +typedef struct ISetupInstance2 ISetupInstance2; +#endif + +#ifndef __IEnumSetupInstances_FWD_DEFINED__ +#define __IEnumSetupInstances_FWD_DEFINED__ +typedef struct IEnumSetupInstances IEnumSetupInstances; +#endif + +#ifndef __ISetupConfiguration_FWD_DEFINED__ +#define __ISetupConfiguration_FWD_DEFINED__ +typedef struct ISetupConfiguration ISetupConfiguration; +#endif + +#ifndef __ISetupConfiguration2_FWD_DEFINED__ +#define __ISetupConfiguration2_FWD_DEFINED__ +typedef struct ISetupConfiguration2 ISetupConfiguration2; +#endif + +#ifndef __ISetupPackageReference_FWD_DEFINED__ +#define __ISetupPackageReference_FWD_DEFINED__ +typedef struct ISetupPackageReference ISetupPackageReference; +#endif + +#ifndef __ISetupHelper_FWD_DEFINED__ +#define __ISetupHelper_FWD_DEFINED__ +typedef struct ISetupHelper ISetupHelper; +#endif + +// Forward class declarations +// +#ifndef __SetupConfiguration_FWD_DEFINED__ +#define __SetupConfiguration_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class SetupConfiguration SetupConfiguration; +#endif + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + // Interface definitions + // + EXTERN_C const IID IID_ISetupInstance; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// Information about an instance of a product. + /// </summary> + struct DECLSPEC_UUID("B41463C3-8866-43B5-BC33-2B0676F7F42E") DECLSPEC_NOVTABLE ISetupInstance : public IUnknown + { + /// <summary> + /// Gets the instance identifier (should match the name of the parent instance directory). + /// </summary> + /// <param name="pbstrInstanceId">The instance identifier.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist.</returns> + STDMETHOD(GetInstanceId)( + BSTR* pbstrInstanceId + ) = 0; + + /// <summary> + /// Gets the local date and time when the installation was originally installed. + /// </summary> + /// <param name="pInstallDate">The local date and time when the installation was originally installed.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallDate)( + LPFILETIME pInstallDate + ) = 0; + + /// <summary> + /// Gets the unique name of the installation, often indicating the branch and other information used for telemetry. + /// </summary> + /// <param name="pbstrInstallationName">The unique name of the installation, often indicating the branch and other information used for telemetry.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallationName)( + BSTR* pbstrInstallationName + ) = 0; + + /// <summary> + /// Gets the path to the installation root of the product. + /// </summary> + /// <param name="pbstrInstallationPath">The path to the installation root of the product.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallationPath)( + BSTR* pbstrInstallationPath + ) = 0; + + /// <summary> + /// Gets the version of the product installed in this instance. + /// </summary> + /// <param name="pbstrInstallationVersion">The version of the product installed in this instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetInstallationVersion)( + BSTR* pbstrInstallationVersion + ) = 0; + + /// <summary> + /// Gets the display name (title) of the product installed in this instance. + /// </summary> + /// <param name="lcid">The LCID for the display name.</param> + /// <param name="pbstrDisplayName">The display name (title) of the product installed in this instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetDisplayName)( + LCID lcid, + BSTR* pbstrDisplayName + ) = 0; + + /// <summary> + /// Gets the description of the product installed in this instance. + /// </summary> + /// <param name="lcid">The LCID for the description.</param> + /// <param name="pbstrDescription">The description of the product installed in this instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(GetDescription)( + LCID lcid, + BSTR* pbstrDescription + ) = 0; + + /// <summary> + /// Resolves the optional relative path to the root path of the instance. + /// </summary> + /// <param name="pwszRelativePath">A relative path within the instance to resolve, or NULL to get the root path.</param> + /// <param name="pbstrAbsolutePath">The full path to the optional relative path within the instance. If the relative path is NULL, the root path will always terminate in a backslash.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the property is not defined.</returns> + STDMETHOD(ResolvePath)( + LPCOLESTR pwszRelativePath, + BSTR* pbstrAbsolutePath + ) = 0; + }; +#endif + + EXTERN_C const IID IID_ISetupInstance2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// Information about an instance of a product. + /// </summary> + struct DECLSPEC_UUID("89143C9A-05AF-49B0-B717-72E218A2185C") DECLSPEC_NOVTABLE ISetupInstance2 : public ISetupInstance + { + /// <summary> + /// Gets the state of the instance. + /// </summary> + /// <param name="pState">The state of the instance.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist.</returns> + STDMETHOD(GetState)( + InstanceState* pState + ) = 0; + + /// <summary> + /// Gets an array of package references registered to the instance. + /// </summary> + /// <param name="ppsaPackages">Pointer to an array of <see cref="ISetupPackageReference"/>.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the packages property is not defined.</returns> + STDMETHOD(GetPackages)( + LPSAFEARRAY* ppsaPackages + ) = 0; + + /// <summary> + /// Gets a pointer to the <see cref="ISetupPackageReference"/> that represents the registered product. + /// </summary> + /// <param name="ppPackage">Pointer to an instance of <see cref="ISetupPackageReference"/>. This may be NULL if <see cref="GetState"/> does not return <see cref="eComplete"/>.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the packages property is not defined.</returns> + STDMETHOD(GetProduct)( + ISetupPackageReference** ppPackage + ) = 0; + + /// <summary> + /// Gets the relative path to the product application, if available. + /// </summary> + /// <param name="pbstrProductPath">The relative path to the product application, if available.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_FILENOTFOUND if the instance state does not exist.</returns> + STDMETHOD(GetProductPath)( + BSTR* pbstrProductPath + ) = 0; + }; +#endif + + EXTERN_C const IID IID_IEnumSetupInstances; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// A enumerator of installed <see cref="ISetupInstance"/> objects. + /// </summary> + struct DECLSPEC_UUID("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848") DECLSPEC_NOVTABLE IEnumSetupInstances : public IUnknown + { + /// <summary> + /// Retrieves the next set of product instances in the enumeration sequence. + /// </summary> + /// <param name="celt">The number of product instances to retrieve.</param> + /// <param name="rgelt">A pointer to an array of <see cref="ISetupInstance"/>.</param> + /// <param name="pceltFetched">A pointer to the number of product instances retrieved. If celt is 1 this parameter may be NULL.</param> + /// <returns>S_OK if the number of elements were fetched, S_FALSE if nothing was fetched (at end of enumeration), E_INVALIDARG if celt is greater than 1 and pceltFetched is NULL, or E_OUTOFMEMORY if an <see cref="ISetupInstance"/> could not be allocated.</returns> + STDMETHOD(Next)( + ULONG celt, + ISetupInstance** rgelt, + ULONG* pceltFetched + ) = 0; + + /// <summary> + /// Skips the next set of product instances in the enumeration sequence. + /// </summary> + /// <param name="celt">The number of product instances to skip.</param> + /// <returns>S_OK if the number of elements could be skipped; otherwise, S_FALSE;</returns> + STDMETHOD(Skip)( + ULONG celt + ) = 0; + + /// <summary> + /// Resets the enumeration sequence to the beginning. + /// </summary> + /// <returns>Always returns S_OK;</returns> + STDMETHOD(Reset)(void) = 0; + + /// <summary> + /// Creates a new enumeration object in the same state as the current enumeration object: the new object points to the same place in the enumeration sequence. + /// </summary> + /// <param name="ppenum">A pointer to a pointer to a new <see cref="IEnumSetupInstances"/> interface. If the method fails, this parameter is undefined.</param> + /// <returns>S_OK if a clone was returned; otherwise, E_OUTOFMEMORY.</returns> + STDMETHOD(Clone)( + IEnumSetupInstances** ppenum + ) = 0; + }; +#endif + + EXTERN_C const IID IID_ISetupConfiguration; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// Gets information about product instances set up on the machine. + /// </summary> + struct DECLSPEC_UUID("42843719-DB4C-46C2-8E7C-64F1816EFD5B") DECLSPEC_NOVTABLE ISetupConfiguration : public IUnknown + { + /// <summary> + /// Enumerates all completed product instances installed. + /// </summary> + /// <param name="ppEnumInstances">An enumeration of completed, installed product instances.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(EnumInstances)( + IEnumSetupInstances** ppEnumInstances + ) = 0; + + /// <summary> + /// Gets the instance for the current process path. + /// </summary> + /// <param name="ppInstance">The instance for the current process path.</param> + /// <returns>The instance for the current process path, or E_NOTFOUND if not found.</returns> + STDMETHOD(GetInstanceForCurrentProcess)( + ISetupInstance** ppInstance + ) = 0; + + /// <summary> + /// Gets the instance for the given path. + /// </summary> + /// <param name="ppInstance">The instance for the given path.</param> + /// <returns>The instance for the given path, or E_NOTFOUND if not found.</returns> + STDMETHOD(GetInstanceForPath)( + LPCWSTR wzPath, + ISetupInstance** ppInstance + ) = 0; + }; +#endif + + EXTERN_C const IID IID_ISetupConfiguration2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// Gets information about product instances. + /// </summary> + struct DECLSPEC_UUID("26AAB78C-4A60-49D6-AF3B-3C35BC93365D") DECLSPEC_NOVTABLE ISetupConfiguration2 : public ISetupConfiguration + { + /// <summary> + /// Enumerates all product instances. + /// </summary> + /// <param name="ppEnumInstances">An enumeration of all product instances.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(EnumAllInstances)( + IEnumSetupInstances** ppEnumInstances + ) = 0; + }; +#endif + + EXTERN_C const IID IID_ISetupPackageReference; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// A reference to a package. + /// </summary> + struct DECLSPEC_UUID("da8d8a16-b2b6-4487-a2f1-594ccccd6bf5") DECLSPEC_NOVTABLE ISetupPackageReference : public IUnknown + { + /// <summary> + /// Gets the general package identifier. + /// </summary> + /// <param name="pbstrId">The general package identifier.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetId)( + BSTR* pbstrId + ) = 0; + + /// <summary> + /// Gets the version of the package. + /// </summary> + /// <param name="pbstrVersion">The version of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetVersion)( + BSTR* pbstrVersion + ) = 0; + + /// <summary> + /// Gets the target process architecture of the package. + /// </summary> + /// <param name="pbstrChip">The target process architecture of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetChip)( + BSTR* pbstrChip + ) = 0; + + /// <summary> + /// Gets the language and optional region identifier. + /// </summary> + /// <param name="pbstrLanguage">The language and optional region identifier.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetLanguage)( + BSTR* pbstrLanguage + ) = 0; + + /// <summary> + /// Gets the build branch of the package. + /// </summary> + /// <param name="pbstrBranch">The build branch of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetBranch)( + BSTR* pbstrBranch + ) = 0; + + /// <summary> + /// Gets the type of the package. + /// </summary> + /// <param name="pbstrType">The type of the package.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(GetType)( + BSTR* pbstrType + ) = 0; + + /// <summary> + /// Gets the unique identifier consisting of all defined tokens. + /// </summary> + /// <param name="pbstrUniqueId">The unique identifier consisting of all defined tokens.</param> + /// <returns>Standard HRESULT indicating success or failure, including E_UNEXPECTED if no Id was defined (required).</returns> + STDMETHOD(GetUniqueId)( + BSTR* pbstrUniqueId + ) = 0; + }; +#endif + + EXTERN_C const IID IID_ISetupHelper; + +#if defined(__cplusplus) && !defined(CINTERFACE) + /// <summary> + /// Helper functions. + /// </summary> + /// <remarks> + /// You can query for this interface from the <see cref="SetupConfiguration"/> class. + /// </remarks> + struct DECLSPEC_UUID("42b21b78-6192-463e-87bf-d577838f1d5c") DECLSPEC_NOVTABLE ISetupHelper : public IUnknown + { + /// <summary> + /// Parses a dotted quad version string into a 64-bit unsigned integer. + /// </summary> + /// <param name="pwszVersion">The dotted quad version string to parse, e.g. 1.2.3.4.</param> + /// <param name="pullVersion">A 64-bit unsigned integer representing the version. You can compare this to other versions.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(ParseVersion)( + LPCOLESTR pwszVersion, + PULONGLONG pullVersion + ) = 0; + + /// <summary> + /// Parses a dotted quad version string into a 64-bit unsigned integer. + /// </summary> + /// <param name="pwszVersionRange">The string containing 1 or 2 dotted quad version strings to parse, e.g. [1.0,) that means 1.0.0.0 or newer.</param> + /// <param name="pullMinVersion">A 64-bit unsigned integer representing the minimum version, which may be 0. You can compare this to other versions.</param> + /// <param name="pullMaxVersion">A 64-bit unsigned integer representing the maximum version, which may be MAXULONGLONG. You can compare this to other versions.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHOD(ParseVersionRange)( + LPCOLESTR pwszVersionRange, + PULONGLONG pullMinVersion, + PULONGLONG pullMaxVersion + ) = 0; + }; +#endif + + // Class declarations + // + EXTERN_C const CLSID CLSID_SetupConfiguration; + +#ifdef __cplusplus + /// <summary> + /// This class implements <see cref="ISetupConfiguration"/>, <see cref="ISetupConfiguration2"/>, and <see cref="ISetupHelper"/>. + /// </summary> + class DECLSPEC_UUID("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D") SetupConfiguration; +#endif + + // Function declarations + // + /// <summary> + /// Gets an <see cref="ISetupConfiguration"/> that provides information about product instances installed on the machine. + /// </summary> + /// <param name="ppConfiguration">The <see cref="ISetupConfiguration"/> that provides information about product instances installed on the machine.</param> + /// <param name="pReserved">Reserved for future use.</param> + /// <returns>Standard HRESULT indicating success or failure.</returns> + STDMETHODIMP GetSetupConfiguration( + ISetupConfiguration** ppConfiguration, + LPVOID pReserved + ); + +#ifdef __cplusplus +} +#endif + +#ifdef VS_SETUP_GCC_DIAGNOSTIC_PUSHED +#pragma GCC diagnostic pop +#undef VS_SETUP_GCC_DIAGNOSTIC_PUSHED +#endif + +#endif +#endif |