diff options
71 files changed, 674 insertions, 105 deletions
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 5e96d79..1e8342c 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -27,6 +27,7 @@ All Modules /module/CheckFortranFunctionExists /module/CheckFortranSourceCompiles /module/CheckFunctionExists + /module/CheckIPOSupported /module/CheckIncludeFileCXX /module/CheckIncludeFile /module/CheckIncludeFiles diff --git a/Help/module/CheckIPOSupported.rst b/Help/module/CheckIPOSupported.rst new file mode 100644 index 0000000..9c8a77b --- /dev/null +++ b/Help/module/CheckIPOSupported.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CheckIPOSupported.cmake diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst index 06c3e6d..86711bf 100644 --- a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst +++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst @@ -14,6 +14,13 @@ be automatically exported and imported by callers. This simplifies porting projects to Windows by reducing the need for explicit ``dllexport`` markup, even in ``C++`` classes. +When this property is enabled, zero or more ``.def`` files may also be +specified as source files of the target. The exports named by these files +will be merged with those detected from the object files to generate a +single module definition file to be passed to the linker. This can be +used to export symbols from a ``.dll`` that are not in any of its object +files but are added by the linker from dependencies (e.g. ``msvcrt.lib``). + This property is initialized by the value of the :variable:`CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` variable if it is set when a target is created. diff --git a/Help/release/dev/CheckIPOSupported.rst b/Help/release/dev/CheckIPOSupported.rst new file mode 100644 index 0000000..dbc84e6 --- /dev/null +++ b/Help/release/dev/CheckIPOSupported.rst @@ -0,0 +1,6 @@ +CheckIPOSupported +----------------- + +* A :module:`CheckIPOSupported` module was added to help projects + check whether interprocedural optimization (IPO) is supported by + the current toolchain and CMake version. diff --git a/Help/release/dev/module-def-and-WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/release/dev/module-def-and-WINDOWS_EXPORT_ALL_SYMBOLS.rst new file mode 100644 index 0000000..dfa9ef1 --- /dev/null +++ b/Help/release/dev/module-def-and-WINDOWS_EXPORT_ALL_SYMBOLS.rst @@ -0,0 +1,8 @@ +module-def-and-WINDOWS_EXPORT_ALL_SYMBOLS +----------------------------------------- + +* The :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property may now + be used in combination with explicit ``.def`` files in order to + export all symbols from the object files within a target plus + an explicit list of symbols that the linker finds in dependencies + (e.g. ``msvcrt.lib``). diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index 7a7c170..2e69195 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -2156,7 +2156,9 @@ function(cpack_rpm_generate_package) if(CPACK_RPM_DEBUGINFO_PACKAGE) # only add current package files to debuginfo list if debuginfo # generation is enabled for current package - set(install_files_ "${CPACK_RPM_INSTALL_FILES}") + string(STRIP "${CPACK_RPM_INSTALL_FILES}" install_files_) + string(REPLACE "\n" ";" install_files_ "${install_files_}") + string(REPLACE "\"" "" install_files_ "${install_files_}") else() unset(install_files_) endif() @@ -2214,7 +2216,11 @@ function(cpack_rpm_generate_package) cpack_rpm_debugsymbol_check("${install_files_}" "${WDIR}") else() - cpack_rpm_debugsymbol_check("${CPACK_RPM_INSTALL_FILES}" "${WDIR}") + string(STRIP "${CPACK_RPM_INSTALL_FILES}" install_files_) + string(REPLACE "\n" ";" install_files_ "${install_files_}") + string(REPLACE "\"" "" install_files_ "${install_files_}") + + cpack_rpm_debugsymbol_check("${install_files_}" "${WDIR}") endif() if(TMP_DEBUGINFO_ADDITIONAL_SOURCES) diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake new file mode 100644 index 0000000..6f7bc82 --- /dev/null +++ b/Modules/CheckIPOSupported.cmake @@ -0,0 +1,215 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CheckIPOSupported +----------------- + +Check whether the compiler supports an interprocedural optimization (IPO/LTO). +Use this before enabling the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target +property. + +.. command:: check_ipo_supported + + :: + + check_ipo_supported([RESULT <result>] [OUTPUT <output>] + [LANGUAGES <lang>...]) + + Options are: + + ``RESULT <result>`` + Set ``<result>`` variable to ``YES`` if IPO is supported by the + compiler and ``NO`` otherwise. If this option is not given then + the command will issue a fatal error if IPO is not supported. + ``OUTPUT <output>`` + Set ``<output>`` variable with details about any error. + ``LANGUAGES <lang>...`` + Specify languages whose compilers to check. + Languages ``C`` and ``CXX`` are supported. + +Examples +^^^^^^^^ + +.. code-block:: cmake + + check_ipo_supported() # fatal error if IPO is not supported + set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + +.. code-block:: cmake + + # Optional IPO. Do not use IPO if it's not supported by compiler. + check_ipo_supported(RESULT result OUTPUT output) + if(result) + set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(WARNING "IPO is not supported: ${output}") + endif() + +#]=======================================================================] + +include(CMakeParseArguments) # cmake_parse_arguments + +# X_RESULT - name of the final result variable +# X_OUTPUT - name of the variable with information about error +macro(_ipo_not_supported output) + string(COMPARE EQUAL "${X_RESULT}" "" is_empty) + if(is_empty) + message(FATAL_ERROR "IPO is not supported (${output}).") + endif() + + set("${X_RESULT}" NO PARENT_SCOPE) + set("${X_OUTPUT}" "${output}" PARENT_SCOPE) +endmacro() + +# Run IPO/LTO test +macro(_ipo_run_language_check language) + set(testdir "${CMAKE_CURRENT_BINARY_DIR}/_CMakeLTOTest-${language}") + + file(REMOVE_RECURSE "${testdir}") + file(MAKE_DIRECTORY "${testdir}") + + set(bindir "${testdir}/bin") + set(srcdir "${testdir}/src") + + file(MAKE_DIRECTORY "${bindir}") + file(MAKE_DIRECTORY "${srcdir}") + + set(TRY_COMPILE_PROJECT_NAME "lto-test") + + set(try_compile_src "${CMAKE_ROOT}/Modules/CheckIPOSupported") + + # Use: + # * TRY_COMPILE_PROJECT_NAME + # * CMAKE_VERSION + configure_file( + "${try_compile_src}/CMakeLists-${language}.txt.in" + "${srcdir}/CMakeLists.txt" + @ONLY + ) + + string(COMPARE EQUAL "${language}" "C" is_c) + string(COMPARE EQUAL "${language}" "CXX" is_cxx) + + if(is_c) + set(copy_sources foo.c main.c) + elseif(is_cxx) + set(copy_sources foo.cpp main.cpp) + else() + message(FATAL_ERROR "Language not supported") + endif() + + foreach(x ${copy_sources}) + configure_file( + "${try_compile_src}/${x}" + "${srcdir}/${x}" + COPYONLY + ) + endforeach() + + try_compile( + result + "${bindir}" + "${srcdir}" + "${TRY_COMPILE_PROJECT_NAME}" + CMAKE_FLAGS + "-DCMAKE_VERBOSE_MAKEFILE=ON" + "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON" + OUTPUT_VARIABLE output + ) + + if(NOT result) + _ipo_not_supported("${output}") + return() + endif() +endmacro() + +function(check_ipo_supported) + # TODO: IPO policy + + set(optional) + set(one RESULT OUTPUT) + set(multiple LANGUAGES) + + # Introduce: + # * X_RESULT + # * X_OUTPUT + # * X_LANGUAGES + cmake_parse_arguments(X "${optional}" "${one}" "${multiple}" "${ARGV}") + + string(COMPARE NOTEQUAL "${X_UNPARSED_ARGUMENTS}" "" has_unparsed) + if(has_unparsed) + message(FATAL_ERROR "Unparsed arguments: ${X_UNPARSED_ARGUMENTS}") + endif() + + string(COMPARE EQUAL "${X_LANGUAGES}" "" no_languages) + if(no_languages) + # User did not set any languages, use defaults + get_property(enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + string(COMPARE EQUAL "${enabled_languages}" "" no_languages) + if(no_languages) + _ipo_not_supported( + "no languages found in ENABLED_LANGUAGES global property" + ) + return() + endif() + + set(languages "") + list(FIND enabled_languages "CXX" result) + if(NOT result EQUAL -1) + list(APPEND languages "CXX") + endif() + + list(FIND enabled_languages "C" result) + if(NOT result EQUAL -1) + list(APPEND languages "C") + endif() + + list(FIND enabled_languages "Fortran" result) + if(NOT result EQUAL -1) + list(APPEND languages "Fortran") + endif() + + string(COMPARE EQUAL "${languages}" "" no_languages) + if(no_languages) + _ipo_not_supported( + "no C/CXX/Fortran languages found in ENABLED_LANGUAGES global property" + ) + return() + endif() + else() + set(languages "${X_LANGUAGES}") + + set(unsupported_languages "${languages}") + list(REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran") + string(COMPARE NOTEQUAL "${unsupported_languages}" "" has_unsupported) + if(has_unsupported) + _ipo_not_supported( + "language(s) '${unsupported_languages}' not supported" + ) + return() + endif() + endif() + + list(FIND languages "Fortran" result) + if(NOT result EQUAL -1) + _ipo_not_supported("Fortran is not supported") + return() + endif() + + if(NOT _CMAKE_IPO_SUPPORTED_BY_CMAKE) + _ipo_not_supported("CMake doesn't support IPO for current compiler") + return() + endif() + + if(NOT _CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER) + _ipo_not_supported("compiler doesn't support IPO") + return() + endif() + + foreach(x ${languages}) + _ipo_run_language_check(${x}) + endforeach() + + set("${X_RESULT}" YES PARENT_SCOPE) +endfunction() diff --git a/Modules/CheckIPOSupported/CMakeLists-C.txt.in b/Modules/CheckIPOSupported/CMakeLists-C.txt.in new file mode 100644 index 0000000..d20f31f --- /dev/null +++ b/Modules/CheckIPOSupported/CMakeLists-C.txt.in @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION "@CMAKE_VERSION@") +project("@TRY_COMPILE_PROJECT_NAME@" LANGUAGES C) + +# TODO: IPO policy + +add_library(foo foo.c) +add_executable(boo main.c) +target_link_libraries(boo PUBLIC foo) diff --git a/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in b/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in new file mode 100644 index 0000000..4b55c70 --- /dev/null +++ b/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION "@CMAKE_VERSION@") +project("@TRY_COMPILE_PROJECT_NAME@" LANGUAGES CXX) + +# TODO: IPO policy + +add_library(foo foo.cpp) +add_executable(boo main.cpp) +target_link_libraries(boo PUBLIC foo) diff --git a/Modules/CheckIPOSupported/foo.c b/Modules/CheckIPOSupported/foo.c new file mode 100644 index 0000000..1e56597 --- /dev/null +++ b/Modules/CheckIPOSupported/foo.c @@ -0,0 +1,4 @@ +int foo() +{ + return 0x42; +} diff --git a/Modules/CheckIPOSupported/foo.cpp b/Modules/CheckIPOSupported/foo.cpp new file mode 100644 index 0000000..1e56597 --- /dev/null +++ b/Modules/CheckIPOSupported/foo.cpp @@ -0,0 +1,4 @@ +int foo() +{ + return 0x42; +} diff --git a/Modules/CheckIPOSupported/main.c b/Modules/CheckIPOSupported/main.c new file mode 100644 index 0000000..5be0864 --- /dev/null +++ b/Modules/CheckIPOSupported/main.c @@ -0,0 +1,6 @@ +int foo(); + +int main() +{ + return foo(); +} diff --git a/Modules/CheckIPOSupported/main.cpp b/Modules/CheckIPOSupported/main.cpp new file mode 100644 index 0000000..5be0864 --- /dev/null +++ b/Modules/CheckIPOSupported/main.cpp @@ -0,0 +1,6 @@ +int foo(); + +int main() +{ + return foo(); +} diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index 853a6b4..2684617 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -32,13 +32,32 @@ # all the possibilities # BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK # -# ######### ## List of vendors (BLA_VENDOR) valid in this module # -# Goto,OpenBLAS,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL, -# Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit, -# lp thread model, lp64 model), # Intel10_64lp_seq (intel mkl v10 64 -# bit,sequential code, lp64 model), # Intel( older versions of mkl 32 -# and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic C/CXX should be -# enabled to use Intel mkl +# List of vendors (BLA_VENDOR) valid in this module: +# +# * Goto +# * OpenBLAS +# * ATLAS PhiPACK +# * CXML +# * DXML +# * SunPerf +# * SCSL +# * SGIMATH +# * IBMESSL +# * Intel10_32 (intel mkl v10 32 bit) +# * Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model) +# * Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model) +# * Intel (older versions of mkl 32 and 64 bit) +# * ACML +# * ACML_MP +# * ACML_GPU +# * Apple +# * NAS +# * Generic +# +# .. note:: +# +# C/CXX should be enabled to use Intel mkl +# include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake) include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index ff19866..1e2ea69 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -96,9 +96,14 @@ # # The following variable can be set to guide the search for HDF5 libraries and includes: # -# HDF5_ROOT +# ``HDF5_ROOT`` +# Specify the path to the HDF5 installation to use. # -# Set HDF5_FIND_DEBUG to true to get some extra debugging output. +# ``HDF5_FIND_DEBUG`` +# Set to a true value to get some extra debugging output. +# +# ``HDF5_NO_FIND_PACKAGE_CONFIG_FILE`` +# Set to a true value to skip trying to find ``hdf5-config.cmake``. # This module is maintained by Will Dicharry <wdicharry@stellarscience.com>. @@ -399,7 +404,7 @@ else() endif() # Try to find HDF5 using an installed hdf5-config.cmake -if(NOT HDF5_FOUND) +if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) find_package(HDF5 QUIET NO_MODULE HINTS ${HDF5_ROOT} ${_HDF5_SEARCH_OPTS} diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index fe6af91..a451e6c 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -33,8 +33,15 @@ # all the possibilities # BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK # -# ## List of vendors (BLA_VENDOR) valid in this module # Intel(mkl), -# OpenBLAS, ACML,Apple, NAS, Generic +# List of vendors (BLA_VENDOR) valid in this module: +# +# * Intel(mkl) +# * OpenBLAS +# * ACML +# * Apple +# * NAS +# * Generic +# set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake index 85a0772..45dc36f 100644 --- a/Modules/Platform/Linux-Intel.cmake +++ b/Modules/Platform/Linux-Intel.cmake @@ -30,12 +30,17 @@ macro(__linux_compiler_intel lang) # executables that use dlopen but do not set ENABLE_EXPORTS. set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic") + set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES) + if(XIAR) # INTERPROCEDURAL_OPTIMIZATION set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -ipo) set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> " "${XIAR} -s <TARGET> ") + set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + else() + set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO) endif() if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0) diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index e41850a..47c7565 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -64,7 +64,7 @@ #include "bindexplib.h" #include <cmsys/Encoding.hxx> -#include <fstream> +#include <cmsys/FStream.hxx> #include <iostream> #include <windows.h> @@ -426,24 +426,46 @@ DumpFile(const char* filename, bool bindexplib::AddObjectFile(const char* filename) { - if(!DumpFile(filename, this->Symbols, this->DataSymbols)) - { - return false; - } - return true; + return DumpFile(filename, this->Symbols, this->DataSymbols); +} + +bool bindexplib::AddDefinitionFile(const char* filename) +{ + cmsys::ifstream infile(filename); + if (!infile) { + fprintf(stderr, "Couldn't open definition file '%s'\n", filename); + return false; + } + std::string str; + while (std::getline(infile, str)) { + // skip the LIBRAY and EXPORTS lines (if any) + if ((str.compare(0,7,"LIBRARY") == 0) || + (str.compare(0,7,"EXPORTS") == 0)) { + continue; + } + // remove leading tabs & spaces + str.erase(0, str.find_first_not_of(" \t")); + std::size_t found = str.find(" \t DATA"); + if (found != std::string::npos) { + str.erase (found, std::string::npos); + this->DataSymbols.insert(str); + } else { + this->Symbols.insert(str); + } + } + infile.close(); + return true; } void bindexplib::WriteFile(FILE* file) { fprintf(file,"EXPORTS \n"); - for(std::set<std::string>::const_iterator i = this->DataSymbols.begin(); - i!= this->DataSymbols.end(); ++i) - { + for (std::set<std::string>::const_iterator i = this->DataSymbols.begin(); + i != this->DataSymbols.end(); ++i) { fprintf(file, "\t%s \t DATA\n", i->c_str()); - } - for(std::set<std::string>::const_iterator i = this->Symbols.begin(); - i!= this->Symbols.end(); ++i) - { + } + for (std::set<std::string>::const_iterator i = this->Symbols.begin(); + i != this->Symbols.end(); ++i) { fprintf(file, "\t%s\n", i->c_str()); - } + } } diff --git a/Source/bindexplib.h b/Source/bindexplib.h index d6900ba..7f0615f 100644 --- a/Source/bindexplib.h +++ b/Source/bindexplib.h @@ -13,6 +13,7 @@ class bindexplib { public: bindexplib() {} + bool AddDefinitionFile(const char* filename); bool AddObjectFile(const char* filename); void WriteFile(FILE* file); private: diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 29698cf..e27424f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1973,15 +1973,16 @@ cmGeneratorTarget::GetModuleDefinitionInfo(std::string const& config) const void cmGeneratorTarget::ComputeModuleDefinitionInfo( std::string const& config, ModuleDefinitionInfo& info) const { - std::vector<cmSourceFile const*> sources; - this->GetModuleDefinitionSources(sources, config); + this->GetModuleDefinitionSources(info.Sources, config); info.WindowsExportAllSymbols = this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") && this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"); - if (info.WindowsExportAllSymbols) { + info.DefFileGenerated = + info.WindowsExportAllSymbols || info.Sources.size() > 1; + if (info.DefFileGenerated) { info.DefFile = this->ObjectDirectory /* has slash */ + "exports.def"; - } else if (!sources.empty()) { - info.DefFile = sources.front()->GetFullPath(); + } else if (!info.Sources.empty()) { + info.DefFile = info.Sources.front()->GetFullPath(); } } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 92285f3..68d6ef8 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -238,7 +238,9 @@ public: struct ModuleDefinitionInfo { std::string DefFile; + bool DefFileGenerated; bool WindowsExportAllSymbols; + std::vector<cmSourceFile const*> Sources; }; ModuleDefinitionInfo const* GetModuleDefinitionInfo( std::string const& config) const; diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 81d9765..32579aa 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -815,7 +815,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( { cmGeneratorTarget::ModuleDefinitionInfo const* mdi = gt->GetModuleDefinitionInfo(configName); - if (!mdi || !mdi->WindowsExportAllSymbols) { + if (!mdi || !mdi->DefFileGenerated) { return; } @@ -842,46 +842,55 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( std::string obj_dir_expanded = obj_dir; cmSystemTools::ReplaceString(obj_dir_expanded, this->GetCMakeCFGIntDir(), configName.c_str()); - std::string objs_file = obj_dir_expanded; - cmSystemTools::MakeDirectory(objs_file.c_str()); - objs_file += "/objects.txt"; + cmSystemTools::MakeDirectory(obj_dir_expanded); + std::string const objs_file = obj_dir_expanded + "/objects.txt"; cmdl.push_back(objs_file); cmGeneratedFileStream fout(objs_file.c_str()); if (!fout) { cmSystemTools::Error("could not open ", objs_file.c_str()); return; } - std::vector<std::string> objs; - for (std::vector<cmSourceFile const*>::const_iterator it = - objectSources.begin(); - it != objectSources.end(); ++it) { - // Find the object file name corresponding to this source file. - std::map<cmSourceFile const*, std::string>::const_iterator map_it = - mapping.find(*it); - // It must exist because we populated the mapping just above. - assert(!map_it->second.empty()); - std::string objFile = obj_dir + map_it->second; - objs.push_back(objFile); - } - std::vector<cmSourceFile const*> externalObjectSources; - gt->GetExternalObjects(externalObjectSources, configName); - for (std::vector<cmSourceFile const*>::const_iterator it = - externalObjectSources.begin(); - it != externalObjectSources.end(); ++it) { - objs.push_back((*it)->GetFullPath()); - } - gt->UseObjectLibraries(objs, configName); - for (std::vector<std::string>::iterator it = objs.begin(); it != objs.end(); - ++it) { - std::string objFile = *it; - // replace $(ConfigurationName) in the object names - cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(), - configName.c_str()); - if (cmHasLiteralSuffix(objFile, ".obj")) { - fout << objFile << "\n"; + if (mdi->WindowsExportAllSymbols) { + std::vector<std::string> objs; + for (std::vector<cmSourceFile const*>::const_iterator it = + objectSources.begin(); + it != objectSources.end(); ++it) { + // Find the object file name corresponding to this source file. + std::map<cmSourceFile const*, std::string>::const_iterator map_it = + mapping.find(*it); + // It must exist because we populated the mapping just above. + assert(!map_it->second.empty()); + std::string objFile = obj_dir + map_it->second; + objs.push_back(objFile); + } + std::vector<cmSourceFile const*> externalObjectSources; + gt->GetExternalObjects(externalObjectSources, configName); + for (std::vector<cmSourceFile const*>::const_iterator it = + externalObjectSources.begin(); + it != externalObjectSources.end(); ++it) { + objs.push_back((*it)->GetFullPath()); + } + + gt->UseObjectLibraries(objs, configName); + for (std::vector<std::string>::iterator it = objs.begin(); + it != objs.end(); ++it) { + std::string objFile = *it; + // replace $(ConfigurationName) in the object names + cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(), + configName.c_str()); + if (cmHasLiteralSuffix(objFile, ".obj")) { + fout << objFile << "\n"; + } } } + + for (std::vector<cmSourceFile const*>::const_iterator i = + mdi->Sources.begin(); + i != mdi->Sources.end(); ++i) { + fout << (*i)->GetFullPath() << "\n"; + } + cmCustomCommandLines commandLines; commandLines.push_back(cmdl); cmCustomCommand command(gt->Target->GetMakefile(), outputs, empty, empty, diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index a8fa4f9..421c3dd 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -57,8 +57,19 @@ bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, // watch for our state change if (scopeDepth == 0 && !cmSystemTools::Strucmp(this->Functions[c].Name.c_str(), "else")) { + + if (this->ElseSeen) { + cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]); + mf.GetCMakeInstance()->IssueMessage( + cmake::FATAL_ERROR, + "A duplicate ELSE command was found inside an IF block.", bt); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + this->IsBlocking = this->HasRun; this->HasRun = true; + this->ElseSeen = true; // if trace is enabled, print a (trivially) evaluated "else" // statement @@ -68,6 +79,15 @@ bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, } else if (scopeDepth == 0 && !cmSystemTools::Strucmp(this->Functions[c].Name.c_str(), "elseif")) { + if (this->ElseSeen) { + cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]); + mf.GetCMakeInstance()->IssueMessage( + cmake::FATAL_ERROR, + "An ELSEIF command was found after an ELSE command.", bt); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + if (this->HasRun) { this->IsBlocking = true; } else { diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 56eef30..f81db67 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -21,6 +21,7 @@ public: cmIfFunctionBlocker() { this->HasRun = false; + this->ElseSeen = false; this->ScopeDepth = 0; } ~cmIfFunctionBlocker() CM_OVERRIDE {} @@ -32,6 +33,7 @@ public: std::vector<cmListFileFunction> Functions; bool IsBlocking; bool HasRun; + bool ElseSeen; unsigned int ScopeDepth; }; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f8490bf..7c33821 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1819,7 +1819,7 @@ void cmLocalVisualStudio7Generator::OutputTargetRules( bool addedPrelink = false; cmGeneratorTarget::ModuleDefinitionInfo const* mdi = target->GetModuleDefinitionInfo(configName); - if (mdi && mdi->WindowsExportAllSymbols) { + if (mdi && mdi->DefFileGenerated) { addedPrelink = true; std::vector<cmCustomCommand> commands = target->GetPreLinkCommands(); cmGlobalVisualStudioGenerator* gg = diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 1fa8702..ed38024 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1414,10 +1414,14 @@ void cmMakefileTargetGenerator::AppendLinkDepends( this->AppendTargetDepends(depends); // Add a dependency on the link definitions file, if any. - cmGeneratorTarget::ModuleDefinitionInfo const* mdi = - this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName()); - if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) { - depends.push_back(mdi->DefFile); + if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi = + this->GeneratorTarget->GetModuleDefinitionInfo( + this->GetConfigName())) { + for (std::vector<cmSourceFile const*>::const_iterator i = + mdi->Sources.begin(); + i != mdi->Sources.end(); ++i) { + depends.push_back((*i)->GetFullPath()); + } } // Add a dependency on user-specified manifest files, if any. @@ -1724,7 +1728,7 @@ void cmMakefileTargetGenerator::GenDefFile( { cmGeneratorTarget::ModuleDefinitionInfo const* mdi = this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName()); - if (!mdi || !mdi->WindowsExportAllSymbols) { + if (!mdi || !mdi->DefFileGenerated) { return; } std::string cmd = cmSystemTools::GetCMakeCommand(); @@ -1744,15 +1748,24 @@ void cmMakefileTargetGenerator::GenDefFile( real_link_commands.insert(real_link_commands.begin(), cmd); // create a list of obj files for the -E __create_def to read cmGeneratedFileStream fout(objlist_file.c_str()); - for (std::vector<std::string>::const_iterator i = this->Objects.begin(); - i != this->Objects.end(); ++i) { - if (cmHasLiteralSuffix(*i, ".obj")) { + + if (mdi->WindowsExportAllSymbols) { + for (std::vector<std::string>::const_iterator i = this->Objects.begin(); + i != this->Objects.end(); ++i) { + if (cmHasLiteralSuffix(*i, ".obj")) { + fout << *i << "\n"; + } + } + for (std::vector<std::string>::const_iterator i = + this->ExternalObjects.begin(); + i != this->ExternalObjects.end(); ++i) { fout << *i << "\n"; } } - for (std::vector<std::string>::const_iterator i = - this->ExternalObjects.begin(); - i != this->ExternalObjects.end(); ++i) { - fout << *i << "\n"; + + for (std::vector<cmSourceFile const*>::const_iterator i = + mdi->Sources.begin(); + i != mdi->Sources.end(); ++i) { + fout << (*i)->GetFullPath() << "\n"; } } diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 300618f..5552fa9 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -747,11 +747,10 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator(); - int commandLineLengthLimit = -1; - if (!this->ForceResponseFile()) { - commandLineLengthLimit = calculateCommandLineLengthLimit( - globalGen.GetRuleCmdLength(this->LanguageLinkerDeviceRule())); - } + // Device linking currently doesn't support response files so + // do not check if the user has explicitly forced a response file. + int const commandLineLengthLimit = calculateCommandLineLengthLimit( + globalGen.GetRuleCmdLength(this->LanguageLinkerDeviceRule())); const std::string rspfile = std::string(cmake::GetCMakeFilesDirectoryPostSlash()) + @@ -978,7 +977,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // maybe create .def file from list of objects cmGeneratorTarget::ModuleDefinitionInfo const* mdi = gt.GetModuleDefinitionInfo(this->GetConfigName()); - if (mdi && mdi->WindowsExportAllSymbols) { + if (mdi && mdi->DefFileGenerated) { std::string cmakeCommand = this->GetLocalGenerator()->ConvertToOutputFormat( cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); @@ -987,18 +986,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmd += this->GetLocalGenerator()->ConvertToOutputFormat( mdi->DefFile, cmOutputConverter::SHELL); cmd += " "; - cmNinjaDeps objs = this->GetObjects(); std::string obj_list_file = mdi->DefFile + ".objs"; cmd += this->GetLocalGenerator()->ConvertToOutputFormat( obj_list_file, cmOutputConverter::SHELL); preLinkCmdLines.push_back(cmd); + // create a list of obj files for the -E __create_def to read cmGeneratedFileStream fout(obj_list_file.c_str()); - for (cmNinjaDeps::iterator i = objs.begin(); i != objs.end(); ++i) { - if (cmHasLiteralSuffix(*i, ".obj")) { - fout << *i << "\n"; + + if (mdi->WindowsExportAllSymbols) { + cmNinjaDeps objs = this->GetObjects(); + for (cmNinjaDeps::iterator i = objs.begin(); i != objs.end(); ++i) { + if (cmHasLiteralSuffix(*i, ".obj")) { + fout << *i << "\n"; + } } } + + for (std::vector<cmSourceFile const*>::const_iterator i = + mdi->Sources.begin(); + i != mdi->Sources.end(); ++i) { + fout << (*i)->GetFullPath() << "\n"; + } } // If we have any PRE_LINK commands, we need to go back to CMAKE_BINARY_DIR // for @@ -1023,8 +1032,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator(); + bool const lang_supports_response = + !(this->TargetLinkLanguage == "RC" || this->TargetLinkLanguage == "CUDA"); int commandLineLengthLimit = -1; - if (!this->ForceResponseFile()) { + if (!lang_supports_response || !this->ForceResponseFile()) { commandLineLengthLimit = calculateCommandLineLengthLimit( globalGen.GetRuleCmdLength(this->LanguageLinkerRule())); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 917383d..2b16e19 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -212,10 +212,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath()); // Add a dependency on the link definitions file, if any. - cmGeneratorTarget::ModuleDefinitionInfo const* mdi = - this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName()); - if (mdi && !mdi->WindowsExportAllSymbols && !mdi->DefFile.empty()) { - result.push_back(this->ConvertToNinjaPath(mdi->DefFile)); + if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi = + this->GeneratorTarget->GetModuleDefinitionInfo( + this->GetConfigName())) { + for (std::vector<cmSourceFile const*>::const_iterator i = + mdi->Sources.begin(); + i != mdi->Sources.end(); ++i) { + result.push_back(this->ConvertToNinjaPath((*i)->GetFullPath())); + } } // Add a dependency on user-specified manifest files, if any. @@ -406,7 +410,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) std::string rspcontent; std::string responseFlag; - if (lang != "RC" && this->ForceResponseFile()) { + bool const lang_supports_response = !(lang == "RC" || lang == "CUDA"); + if (lang_supports_response && this->ForceResponseFile()) { rspfile = "$RSP_FILE"; responseFlag = "@" + rspfile; rspcontent = " $DEFINES $INCLUDES $FLAGS"; @@ -931,9 +936,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( this->SetMsvcTargetPdbVariable(vars); - bool const isRC = (language == "RC"); + bool const lang_supports_response = + !(language == "RC" || language == "CUDA"); int const commandLineLengthLimit = - ((!isRC && this->ForceResponseFile())) ? -1 : 0; + ((lang_supports_response && this->ForceResponseFile())) ? -1 : 0; std::string const rspfile = objectFileName + ".rsp"; this->GetGlobalGenerator()->WriteBuild( @@ -979,7 +985,9 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang) lang, this->GetConfigName()); for (std::vector<std::string>::iterator i = includes.begin(); i != includes.end(); ++i) { - tdi_include_dirs.append(*i); + // Convert the include directories the same way we do for -I flags. + // See upstream ninja issue 1251. + tdi_include_dirs.append(this->ConvertToNinjaPath(*i)); } Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] = diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 052cc7f..84767a8 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3300,7 +3300,7 @@ void cmVisualStudio10TargetGenerator::WriteEvents( bool addedPrelink = false; cmGeneratorTarget::ModuleDefinitionInfo const* mdi = this->GeneratorTarget->GetModuleDefinitionInfo(configName); - if (mdi && mdi->WindowsExportAllSymbols) { + if (mdi && mdi->DefFileGenerated) { addedPrelink = true; std::vector<cmCustomCommand> commands = this->GeneratorTarget->GetPreLinkCommands(); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 823b38f..9e08b9c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -258,11 +258,18 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) << "\n"; return 1; } - std::string objfile; + std::string file; bindexplib deffile; - while (cmSystemTools::GetLineFromStream(fin, objfile)) { - if (!deffile.AddObjectFile(objfile.c_str())) { - return 1; + while (cmSystemTools::GetLineFromStream(fin, file)) { + std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); + if (cmSystemTools::LowerCase(ext) == ".def") { + if (!deffile.AddDefinitionFile(file.c_str())) { + return 1; + } + } else { + if (!deffile.AddObjectFile(file.c_str())) { + return 1; + } } } deffile.WriteFile(fout); diff --git a/Tests/ModuleDefinition/CMakeLists.txt b/Tests/ModuleDefinition/CMakeLists.txt index bfbb343..e49ebea 100644 --- a/Tests/ModuleDefinition/CMakeLists.txt +++ b/Tests/ModuleDefinition/CMakeLists.txt @@ -4,6 +4,8 @@ project(ModuleDefinition C) # Test .def file source recognition for DLLs. add_library(example_dll SHARED example_dll.c example_dll.def) +add_library(split_dll SHARED split_dll.c split_dll_1.def split_dll_2.def) + # Test generated .def file. add_custom_command(OUTPUT example_dll_gen.def DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/example_dll_gen.def.in @@ -24,7 +26,12 @@ endif() # Test .def file source recognition for EXEs. add_executable(example_exe example_exe.c example_exe.def) set_property(TARGET example_exe PROPERTY ENABLE_EXPORTS 1) -target_link_libraries(example_exe example_dll example_dll_gen ${example_dll_2}) +target_link_libraries(example_exe + example_dll + example_dll_gen + ${example_dll_2} + split_dll + ) # Test linking to the executable. add_library(example_mod_1 MODULE example_mod_1.c) diff --git a/Tests/ModuleDefinition/example_exe.c b/Tests/ModuleDefinition/example_exe.c index dff566f..8e86fc4 100644 --- a/Tests/ModuleDefinition/example_exe.c +++ b/Tests/ModuleDefinition/example_exe.c @@ -3,15 +3,19 @@ extern int __declspec(dllimport) example_dll_gen_function(void); #ifdef EXAMPLE_DLL_2 extern int __declspec(dllimport) example_dll_2_function(void); #endif +extern int __declspec(dllimport) split_dll_1(void); +extern int __declspec(dllimport) split_dll_2(void); + int example_exe_function(void) { return 0; } + int main(void) { return example_dll_function() + example_dll_gen_function() + #ifdef EXAMPLE_DLL_2 example_dll_2_function() + #endif - example_exe_function(); + split_dll_1() + split_dll_2() + example_exe_function(); } diff --git a/Tests/ModuleDefinition/split_dll.c b/Tests/ModuleDefinition/split_dll.c new file mode 100644 index 0000000..1546a2d --- /dev/null +++ b/Tests/ModuleDefinition/split_dll.c @@ -0,0 +1,9 @@ +int split_dll_1(void) +{ + return 0; +} + +int split_dll_2(void) +{ + return 0; +} diff --git a/Tests/ModuleDefinition/split_dll_1.def b/Tests/ModuleDefinition/split_dll_1.def new file mode 100644 index 0000000..ced9f10 --- /dev/null +++ b/Tests/ModuleDefinition/split_dll_1.def @@ -0,0 +1,2 @@ +EXPORTS +split_dll_1 diff --git a/Tests/ModuleDefinition/split_dll_2.def b/Tests/ModuleDefinition/split_dll_2.def new file mode 100644 index 0000000..b072c50 --- /dev/null +++ b/Tests/ModuleDefinition/split_dll_2.def @@ -0,0 +1,2 @@ +EXPORTS +split_dll_2 diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 5157b9f..217f0d5 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -293,6 +293,7 @@ add_RunCMake_test(target_link_libraries) add_RunCMake_test(target_compile_features) add_RunCMake_test(CheckModules) +add_RunCMake_test(CheckIPOSupported) add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}) add_RunCMake_test(CommandLineTar) diff --git a/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt b/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt new file mode 100644 index 0000000..a0effc9 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} NONE) +include(CheckIPOSupported) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake new file mode 100644 index 0000000..e304c61 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake @@ -0,0 +1,9 @@ +include(RunCMake) + +run_cmake(unparsed-arguments) +run_cmake(user-lang-unknown) +run_cmake(user-lang-fortran) +run_cmake(default-lang-none) +run_cmake(not-supported-by-cmake) +run_cmake(not-supported-by-compiler) +run_cmake(save-to-result) diff --git a/Tests/RunCMake/CheckIPOSupported/default-lang-none-result.txt b/Tests/RunCMake/CheckIPOSupported/default-lang-none-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/default-lang-none-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt b/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt new file mode 100644 index 0000000..dc2c3ad --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt @@ -0,0 +1,7 @@ +^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\): + IPO is not supported \(no C/CXX/Fortran languages found in ENABLED_LANGUAGES + global property\)\. +Call Stack \(most recent call first\): + .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\) + default-lang-none\.cmake:[0-9]+ \(check_ipo_supported\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CheckIPOSupported/default-lang-none.cmake b/Tests/RunCMake/CheckIPOSupported/default-lang-none.cmake new file mode 100644 index 0000000..0a2ac69 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/default-lang-none.cmake @@ -0,0 +1 @@ +check_ipo_supported() diff --git a/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-result.txt b/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-stderr.txt b/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-stderr.txt new file mode 100644 index 0000000..f63f30f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\): + IPO is not supported \(CMake doesn't support IPO for current compiler\)\. +Call Stack \(most recent call first\): + .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\) + not-supported-by-cmake\.cmake:[0-9]+ \(check_ipo_supported\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake.cmake b/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake.cmake new file mode 100644 index 0000000..6f61f7e --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake.cmake @@ -0,0 +1,3 @@ +project(${RunCMake_TEST} LANGUAGES C) +set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO) +check_ipo_supported() diff --git a/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-result.txt b/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-stderr.txt b/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-stderr.txt new file mode 100644 index 0000000..73e2f26 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\): + IPO is not supported \(compiler doesn't support IPO\)\. +Call Stack \(most recent call first\): + .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\) + not-supported-by-compiler\.cmake:[0-9]+ \(check_ipo_supported\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler.cmake b/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler.cmake new file mode 100644 index 0000000..652cfd5 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler.cmake @@ -0,0 +1,4 @@ +project(${RunCMake_TEST} LANGUAGES C) +set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES) +set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO) +check_ipo_supported() diff --git a/Tests/RunCMake/CheckIPOSupported/save-to-result.cmake b/Tests/RunCMake/CheckIPOSupported/save-to-result.cmake new file mode 100644 index 0000000..f76db72 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/save-to-result.cmake @@ -0,0 +1,22 @@ +project(${RunCMake_TEST} LANGUAGES C) +check_ipo_supported(RESULT result OUTPUT output) + +string(COMPARE EQUAL "${result}" "" is_empty) +if(is_empty) + message(FATAL_ERROR "Result variable is empty") +endif() + +string(COMPARE EQUAL "${result}" "YES" is_yes) +string(COMPARE EQUAL "${result}" "NO" is_no) + +if(is_yes) + # Compiler supports IPO +elseif(is_no) + # Compiler doesn't support IPO, output should not be empty. + string(COMPARE EQUAL "${output}" "" is_empty) + if(is_empty) + message(FATAL_ERROR "Output is empty") + endif() +else() + message(FATAL_ERROR "Unexpected result: ${result}") +endif() diff --git a/Tests/RunCMake/CheckIPOSupported/unparsed-arguments-result.txt b/Tests/RunCMake/CheckIPOSupported/unparsed-arguments-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/unparsed-arguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CheckIPOSupported/unparsed-arguments-stderr.txt b/Tests/RunCMake/CheckIPOSupported/unparsed-arguments-stderr.txt new file mode 100644 index 0000000..a3fee53 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/unparsed-arguments-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\): + Unparsed arguments: xxx +Call Stack \(most recent call first\): + unparsed-arguments\.cmake:[0-9]+ \(check_ipo_supported\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CheckIPOSupported/unparsed-arguments.cmake b/Tests/RunCMake/CheckIPOSupported/unparsed-arguments.cmake new file mode 100644 index 0000000..3ee7326 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/unparsed-arguments.cmake @@ -0,0 +1 @@ +check_ipo_supported(RESULT result OUTPUT output xxx) diff --git a/Tests/RunCMake/CheckIPOSupported/user-lang-fortran-result.txt b/Tests/RunCMake/CheckIPOSupported/user-lang-fortran-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/user-lang-fortran-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CheckIPOSupported/user-lang-fortran-stderr.txt b/Tests/RunCMake/CheckIPOSupported/user-lang-fortran-stderr.txt new file mode 100644 index 0000000..2cb595d --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/user-lang-fortran-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\): + IPO is not supported \(Fortran is not supported\)\. +Call Stack \(most recent call first\): + .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\) + user-lang-fortran\.cmake:[0-9]+ \(check_ipo_supported\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CheckIPOSupported/user-lang-fortran.cmake b/Tests/RunCMake/CheckIPOSupported/user-lang-fortran.cmake new file mode 100644 index 0000000..275dbd9 --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/user-lang-fortran.cmake @@ -0,0 +1 @@ +check_ipo_supported(LANGUAGES "Fortran") diff --git a/Tests/RunCMake/CheckIPOSupported/user-lang-unknown-result.txt b/Tests/RunCMake/CheckIPOSupported/user-lang-unknown-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/user-lang-unknown-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CheckIPOSupported/user-lang-unknown-stderr.txt b/Tests/RunCMake/CheckIPOSupported/user-lang-unknown-stderr.txt new file mode 100644 index 0000000..278ba0b --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/user-lang-unknown-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\): + IPO is not supported \(language\(s\) 'UnknownLanguage' not supported\)\. +Call Stack \(most recent call first\): + .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\) + user-lang-unknown\.cmake:[0-9]+ \(check_ipo_supported\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CheckIPOSupported/user-lang-unknown.cmake b/Tests/RunCMake/CheckIPOSupported/user-lang-unknown.cmake new file mode 100644 index 0000000..ac743ad --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/user-lang-unknown.cmake @@ -0,0 +1 @@ +check_ipo_supported(LANGUAGES UnknownLanguage) diff --git a/Tests/RunCMake/if/RunCMakeTest.cmake b/Tests/RunCMake/if/RunCMakeTest.cmake index 077d00a..f54edf7 100644 --- a/Tests/RunCMake/if/RunCMakeTest.cmake +++ b/Tests/RunCMake/if/RunCMakeTest.cmake @@ -3,7 +3,11 @@ include(RunCMake) run_cmake(InvalidArgument1) run_cmake(IsDirectory) run_cmake(IsDirectoryLong) +run_cmake(duplicate-deep-else) +run_cmake(duplicate-else) +run_cmake(duplicate-else-after-elseif) run_cmake(elseif-message) +run_cmake(misplaced-elseif) run_cmake(MatchesSelf) diff --git a/Tests/RunCMake/if/duplicate-deep-else-result.txt b/Tests/RunCMake/if/duplicate-deep-else-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/if/duplicate-deep-else-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/if/duplicate-deep-else-stderr.txt b/Tests/RunCMake/if/duplicate-deep-else-stderr.txt new file mode 100644 index 0000000..ac2335c --- /dev/null +++ b/Tests/RunCMake/if/duplicate-deep-else-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at duplicate-deep-else.cmake:[0-9]+ \(else\): + A duplicate ELSE command was found inside an IF block. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/if/duplicate-deep-else.cmake b/Tests/RunCMake/if/duplicate-deep-else.cmake new file mode 100644 index 0000000..94f06de --- /dev/null +++ b/Tests/RunCMake/if/duplicate-deep-else.cmake @@ -0,0 +1,7 @@ +if(0) +else() + if(0) + else() + else() + endif() +endif() diff --git a/Tests/RunCMake/if/duplicate-else-after-elseif-result.txt b/Tests/RunCMake/if/duplicate-else-after-elseif-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/if/duplicate-else-after-elseif-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt b/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt new file mode 100644 index 0000000..ba6765c --- /dev/null +++ b/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at duplicate-else-after-elseif.cmake:[0-9]+ \(else\): + A duplicate ELSE command was found inside an IF block. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/if/duplicate-else-after-elseif.cmake b/Tests/RunCMake/if/duplicate-else-after-elseif.cmake new file mode 100644 index 0000000..d1d4ac1 --- /dev/null +++ b/Tests/RunCMake/if/duplicate-else-after-elseif.cmake @@ -0,0 +1,5 @@ +if(0) +elseif(0) +else() +else() +endif() diff --git a/Tests/RunCMake/if/duplicate-else-result.txt b/Tests/RunCMake/if/duplicate-else-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/if/duplicate-else-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/if/duplicate-else-stderr.txt b/Tests/RunCMake/if/duplicate-else-stderr.txt new file mode 100644 index 0000000..e0dd01f --- /dev/null +++ b/Tests/RunCMake/if/duplicate-else-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at duplicate-else.cmake:[0-9]+ \(else\): + A duplicate ELSE command was found inside an IF block. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/if/duplicate-else.cmake b/Tests/RunCMake/if/duplicate-else.cmake new file mode 100644 index 0000000..14a03ac --- /dev/null +++ b/Tests/RunCMake/if/duplicate-else.cmake @@ -0,0 +1,4 @@ +if(0) +else() +else() +endif() diff --git a/Tests/RunCMake/if/misplaced-elseif-result.txt b/Tests/RunCMake/if/misplaced-elseif-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/if/misplaced-elseif-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/if/misplaced-elseif-stderr.txt b/Tests/RunCMake/if/misplaced-elseif-stderr.txt new file mode 100644 index 0000000..c4b0266 --- /dev/null +++ b/Tests/RunCMake/if/misplaced-elseif-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at misplaced-elseif.cmake:[0-9]+ \(elseif\): + An ELSEIF command was found after an ELSE command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/if/misplaced-elseif.cmake b/Tests/RunCMake/if/misplaced-elseif.cmake new file mode 100644 index 0000000..d27f24e --- /dev/null +++ b/Tests/RunCMake/if/misplaced-elseif.cmake @@ -0,0 +1,4 @@ +if(0) +else() +elseif(1) +endif() diff --git a/Utilities/cmlibarchive/libarchive/archive_random.c b/Utilities/cmlibarchive/libarchive/archive_random.c index 357f973..90ee7c6 100644 --- a/Utilities/cmlibarchive/libarchive/archive_random.c +++ b/Utilities/cmlibarchive/libarchive/archive_random.c @@ -222,7 +222,7 @@ arc4_stir(void) * Discard early keystream, as per recommendations in: * "(Not So) Random Shuffles of RC4" by Ilya Mironov. */ - for (i = 0; i < 1024; i++) + for (i = 0; i < 3072; i++) (void)arc4_getbyte(); arc4_count = 1600000; } |