diff options
31 files changed, 449 insertions, 101 deletions
diff --git a/Help/command/install.rst b/Help/command/install.rst index 3a2b4da..08c5718 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -89,6 +89,13 @@ Command signatures that install files may print messages during installation. Use the :variable:`CMAKE_INSTALL_MESSAGE` variable to control which messages are printed. +Many of the ``install()`` variants implicitly create the directories +containing the installed files. If +:variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` is set, these +directories will be created with the permissions specified. Otherwise, +they will be created according to the uname rules on Unix-like platforms. +Windows platforms are unaffected. + Installing Targets ^^^^^^^^^^^^^^^^^^ diff --git a/Help/release/dev/byproducts_make_clean.rst b/Help/release/dev/byproducts_make_clean.rst new file mode 100644 index 0000000..54df77d --- /dev/null +++ b/Help/release/dev/byproducts_make_clean.rst @@ -0,0 +1,5 @@ +byproducts_make_clean +--------------------- + +* The :ref:`Makefile Generators` learned to remove custom command and + custom target byproducts during ``make clean``. diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index 4913e05..fdddcc7 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -1,29 +1,49 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindJNI -# ------- -# -# Find JNI java libraries. -# -# This module finds if Java is installed and determines where the -# include files and libraries are. It also determines what the name of -# the library is. The caller may set variable JAVA_HOME to specify a -# Java installation prefix explicitly. -# -# This module sets the following result variables: -# -# :: -# -# JNI_INCLUDE_DIRS = the include dirs to use -# JNI_LIBRARIES = the libraries to use -# JNI_FOUND = TRUE if JNI headers and libraries were found. -# JAVA_AWT_LIBRARY = the path to the jawt library -# JAVA_JVM_LIBRARY = the path to the jvm library -# JAVA_INCLUDE_PATH = the include path to jni.h -# JAVA_INCLUDE_PATH2 = the include path to jni_md.h -# JAVA_AWT_INCLUDE_PATH = the include path to jawt.h +#[=======================================================================[.rst: +FindJNI +------- + +Find Java Native Interface (JNI) libraries. + +JNI enables Java code running in a Java Virtual Machine (JVM) to call +and be called by native applications and libraries written in other +languages such as C, C++. + +This module finds if Java is installed and determines where the +include files and libraries are. It also determines what the name of +the library is. The caller may set variable ``JAVA_HOME`` to specify a +Java installation prefix explicitly. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module sets the following result variables: + +``JNI_INCLUDE_DIRS`` + the include dirs to use +``JNI_LIBRARIES`` + the libraries to use (JAWT and JVM) +``JNI_FOUND`` + TRUE if JNI headers and libraries were found. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables are also available to set or use: + +``JAVA_AWT_LIBRARY`` + the path to the Java AWT Native Interface (JAWT) library +``JAVA_JVM_LIBRARY`` + the path to the Java Virtual Machine (JVM) library +``JAVA_INCLUDE_PATH`` + the include path to jni.h +``JAVA_INCLUDE_PATH2`` + the include path to jni_md.h and jniport.h +``JAVA_AWT_INCLUDE_PATH`` + the include path to jawt.h +#]=======================================================================] # Expand {libarch} occurrences to java_libarch subdirectory(-ies) and set ${_var} macro(java_append_library_directories _var) @@ -187,6 +207,7 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES /usr/lib/jvm/default/jre/lib/{libarch} /usr/lib/jvm/default/lib/{libarch} # Ubuntu specific paths for default JVM + /usr/lib/jvm/java-11-openjdk-{libarch}/jre/lib/{libarch} # Ubuntu 18.04 LTS /usr/lib/jvm/java-8-openjdk-{libarch}/jre/lib/{libarch} # Ubuntu 15.10 /usr/lib/jvm/java-7-openjdk-{libarch}/jre/lib/{libarch} # Ubuntu 15.10 /usr/lib/jvm/java-6-openjdk-{libarch}/jre/lib/{libarch} # Ubuntu 15.10 diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index cddc5d2..bcdf166 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -8,19 +8,19 @@ # Find Java # # This module finds if Java is installed and determines where the -# include files and libraries are. The caller may set variable JAVA_HOME +# include files and libraries are. The caller may set variable ``JAVA_HOME`` # to specify a Java installation prefix explicitly. # -# See also the :module:`FindJNI` module to find Java development tools. +# See also the :module:`FindJNI` module to find Java Native Interface (JNI). # # Specify one or more of the following components as you call this find module. See example below. # # :: # -# Runtime = User just want to execute some Java byte-compiled +# Runtime = Java Runtime Environment used to execute Java byte-compiled applications # Development = Development tools (java, javac, javah, jar and javadoc), includes Runtime component -# IdlJ = idl compiler for Java -# JarSigner = signer tool for jar +# IdlJ = Interface Description Language (IDL) to Java compiler +# JarSigner = Signer and verifier tool for Java Archive (JAR) files # # # This module sets the following result variables: @@ -44,14 +44,18 @@ # # # The minimum required version of Java can be specified using the -# standard CMake syntax, e.g. find_package(Java 1.5) +# :command:`find_package` syntax, e.g. # -# NOTE: ${Java_VERSION} and ${Java_VERSION_STRING} are not guaranteed to +# .. code-block:: cmake +# +# find_package(Java 1.8) +# +# NOTE: ``${Java_VERSION}`` and ``${Java_VERSION_STRING}`` are not guaranteed to # be identical. For example some java version may return: -# Java_VERSION_STRING = 1.5.0_17 and Java_VERSION = 1.5.0.17 +# ``Java_VERSION_STRING = 1.8.0_17`` and ``Java_VERSION = 1.8.0.17`` # -# another example is the Java OEM, with: Java_VERSION_STRING = 1.6.0-oem -# and Java_VERSION = 1.6.0 +# another example is the Java OEM, with: ``Java_VERSION_STRING = 1.8.0-oem`` +# and ``Java_VERSION = 1.8.0`` # # For these components the following variables are set: # @@ -67,6 +71,7 @@ # :: # # find_package(Java) +# find_package(Java 1.8 REQUIRED) # find_package(Java COMPONENTS Runtime) # find_package(Java COMPONENTS Development) diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 0bf0b4f..8645a0d 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -135,6 +135,12 @@ Hints Value ``ONLY`` is not supported so ``FIRST`` will be used instead. +.. note:: + + If a Python virtual environment is configured, set variable + ``Python_FIND_REGISTRY`` (Windows) or ``CMAKE_FIND_FRAMEWORK`` (macOS) with + value ``LAST`` or ``NEVER`` to select it preferably. + Commands ^^^^^^^^ diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 1834591..a8a73a7 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -355,20 +355,23 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) + if (WIN32) + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR) + else() + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + NAMES_PER_DIR) + endif() # Apple frameworks handling if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") @@ -413,6 +416,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 2735a25..998e992 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -136,6 +136,12 @@ Hints Value ``ONLY`` is not supported so ``FIRST`` will be used instead. +.. note:: + + If a Python virtual environment is configured, set variable + ``Python_FIND_REGISTRY`` (Windows) or ``CMAKE_FIND_FRAMEWORK`` (macOS) with + value ``LAST`` or ``NEVER`` to select it preferably. + Commands ^^^^^^^^ diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index ed7e1a3..2176f3f 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -136,6 +136,12 @@ Hints Value ``ONLY`` is not supported so ``FIRST`` will be used instead. +.. note:: + + If a Python virtual environment is configured, set variable + ``Python_FIND_REGISTRY`` (Windows) or ``CMAKE_FIND_FRAMEWORK`` (macOS) with + value ``LAST`` or ``NEVER`` to select it preferably. + Commands ^^^^^^^^ diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 408cc7d..129c6fb 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 12) -set(CMake_VERSION_PATCH 20181001) +set(CMake_VERSION_PATCH 20181003) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index c7f3f39..ecf309a 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -392,8 +392,12 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); std::string local_file = file; + bool initialize_cdash_buildid = false; if (!cmSystemTools::FileExists(local_file)) { local_file = localprefix + "/" + file; + // If this file exists within the local Testing directory we assume + // that it will be associated with the current build in CDash. + initialize_cdash_buildid = true; } std::string remote_file = remoteprefix + cmSystemTools::GetFilenameName(file); @@ -425,26 +429,30 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ((url.find('?') == std::string::npos) ? '?' : '&') + "FileName=" + ofile; - cmCTestCurl ctest_curl(this->CTest); - upload_as += "&build="; - upload_as += - ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")); - upload_as += "&site="; - upload_as += - ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")); - upload_as += "&stamp="; - upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); - upload_as += "-"; - upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script")); - cmake* cm = ch->GetCMake(); - if (cm) { - const char* subproject = - cm->GetState()->GetGlobalProperty("SubProject"); - if (subproject) { - upload_as += "&subproject="; - upload_as += ctest_curl.Escape(subproject); + if (initialize_cdash_buildid) { + // Provide extra arguments to CDash so that it can initialize and + // return a buildid. + cmCTestCurl ctest_curl(this->CTest); + upload_as += "&build="; + upload_as += + ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")); + upload_as += "&site="; + upload_as += + ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")); + upload_as += "&stamp="; + upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); + upload_as += "-"; + upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); + cmCTestScriptHandler* ch = static_cast<cmCTestScriptHandler*>( + this->CTest->GetHandler("script")); + cmake* cm = ch->GetCMake(); + if (cm) { + const char* subproject = + cm->GetState()->GetGlobalProperty("SubProject"); + if (subproject) { + upload_as += "&subproject="; + upload_as += ctest_curl.Escape(subproject); + } } } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 54af2f4..1f76703 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1275,6 +1275,33 @@ protected: this->DirPermissions |= mode_world_read; this->DirPermissions |= mode_world_execute; } + + bool GetDefaultDirectoryPermissions(mode_t** mode) + { + // check if default dir creation permissions were set + const char* default_dir_install_permissions = + this->Makefile->GetDefinition( + "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); + if (default_dir_install_permissions && *default_dir_install_permissions) { + std::vector<std::string> items; + cmSystemTools::ExpandListArgument(default_dir_install_permissions, + items); + for (const auto& arg : items) { + if (!this->CheckPermissions(arg, **mode)) { + std::ostringstream e; + e << this->FileCommand->GetError() + << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS " + "variable."; + this->FileCommand->SetError(e.str()); + return false; + } + } + } else { + *mode = nullptr; + } + + return true; + } }; bool cmFileCopier::Parse(std::vector<std::string> const& args) @@ -1668,8 +1695,15 @@ bool cmFileCopier::InstallDirectory(const char* source, this->ReportCopy(destination, TypeDir, !cmSystemTools::FileIsDirectory(destination)); + // check if default dir creation permissions were set + mode_t default_dir_mode_v = 0; + mode_t* default_dir_mode = &default_dir_mode_v; + if (!this->GetDefaultDirectoryPermissions(&default_dir_mode)) { + return false; + } + // Make sure the destination directory exists. - if (!cmSystemTools::MakeDirectory(destination)) { + if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) { std::ostringstream e; e << this->Name << " cannot make directory \"" << destination << "\": " << cmSystemTools::GetLastSystemError(); @@ -2073,23 +2107,9 @@ bool cmFileInstaller::HandleInstallDestination() // check if default dir creation permissions were set mode_t default_dir_mode_v = 0; - mode_t* default_dir_mode = nullptr; - const char* default_dir_install_permissions = this->Makefile->GetDefinition( - "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS"); - if (default_dir_install_permissions && *default_dir_install_permissions) { - std::vector<std::string> items; - cmSystemTools::ExpandListArgument(default_dir_install_permissions, items); - for (const auto& arg : items) { - if (!this->CheckPermissions(arg, default_dir_mode_v)) { - std::ostringstream e; - e << this->FileCommand->GetError() - << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable."; - this->FileCommand->SetError(e.str()); - return false; - } - } - - default_dir_mode = &default_dir_mode_v; + mode_t* default_dir_mode = &default_dir_mode_v; + if (!this->GetDefaultDirectoryPermissions(&default_dir_mode)) { + return false; } if (this->InstallType != cmInstallType_DIRECTORY) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 29c6058..80fb621 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5600,10 +5600,14 @@ bool cmGeneratorTarget::HasLanguage(std::string const& language, { std::set<std::string> languages; this->GetLanguages(languages, config); + // The "exclusive" check applies only to source files and not + // the linker language which may be affected by dependencies. + if (exclusive && languages.size() > 1) { + return false; + } // add linker language (if it is different from compiler languages) languages.insert(this->GetLinkerLanguage(config)); - return (languages.size() == 1 || !exclusive) && - languages.count(language) > 0; + return languages.count(language) > 0; } void cmGeneratorTarget::ComputeLinkImplementationLanguages( diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index bfd95ac..b1daa53 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -374,7 +374,7 @@ public: // Evaluate if the target uses the given language for compilation // and/or linking. If 'exclusive' is true, 'language' is expected - // to be the only language used for the target. + // to be the only language used in source files for the target. bool HasLanguage(std::string const& language, std::string const& config, bool exclusive = true) const; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index c8dc392..f423560 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -181,6 +181,36 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, output)); } + const std::vector<std::string>& byproducts = ccg.GetByproducts(); + for (std::string const& byproduct : byproducts) { + this->CleanFiles.push_back( + this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, + byproduct)); + } + } + } + + // Add byproducts from build events to the clean rules + if (clean) { + std::vector<cmCustomCommand> buildEventCommands = + this->GeneratorTarget->GetPreBuildCommands(); + + buildEventCommands.insert( + buildEventCommands.end(), + this->GeneratorTarget->GetPreLinkCommands().begin(), + this->GeneratorTarget->GetPreLinkCommands().end()); + buildEventCommands.insert( + buildEventCommands.end(), + this->GeneratorTarget->GetPostBuildCommands().begin(), + this->GeneratorTarget->GetPostBuildCommands().end()); + + for (const auto& be : buildEventCommands) { + const std::vector<std::string>& byproducts = be.GetByproducts(); + for (std::string const& byproduct : byproducts) { + this->CleanFiles.push_back( + this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, + byproduct)); + } } } std::vector<cmSourceFile const*> headerSources; diff --git a/Source/cmVS141CSharpFlagTable.h b/Source/cmVS141CSharpFlagTable.h index 5de9bf3..66c61bd 100644 --- a/Source/cmVS141CSharpFlagTable.h +++ b/Source/cmVS141CSharpFlagTable.h @@ -76,7 +76,12 @@ static cmVS7FlagTable cmVS141CSharpFlagTable[] = { { "LangVersion", "langversion:4", "", "4", 0 }, { "LangVersion", "langversion:5", "", "5", 0 }, { "LangVersion", "langversion:6", "", "6", 0 }, + { "LangVersion", "langversion:7.0", "", "7.0", 0 }, + { "LangVersion", "langversion:7.1", "", "7.1", 0 }, + { "LangVersion", "langversion:7.2", "", "7.2", 0 }, + { "LangVersion", "langversion:7.3", "", "7.3", 0 }, { "LangVersion", "langversion:default", "", "default", 0 }, + { "LangVersion", "langversion:latest", "", "latest", 0 }, { "DelaySign", "delaysign", "", "true", 0 }, { "DelaySign", "delaysign-", "", "false", 0 }, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index c79b071..16eca96 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2452,10 +2452,12 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } // Choose a language whose flags to use for ClCompile. - static const char* clLangs[] = { "CXX", "C", "Fortran", "CSharp" }; + static const char* clLangs[] = { "CXX", "C", "Fortran" }; std::string langForClCompile; - if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) != - cm::cend(clLangs)) { + if (this->ProjectType == csproj) { + langForClCompile = "CSharp"; + } else if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) != + cm::cend(clLangs)) { langForClCompile = linkLanguage; } else { std::set<std::string> languages; diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index 1bcfd0c..4dd2461 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -103,6 +103,8 @@ static int kwsysTerminalStreamIsNotInteractive(FILE* stream) /* List of terminal names known to support VT100 color escape sequences. */ static const char* kwsysTerminalVT100Names[] = { "Eterm", + "alacritty", + "alacritty-direct", "ansi", "color-xterm", "con132x25", diff --git a/Tests/CSharpLinkToCxx/CMakeLists.txt b/Tests/CSharpLinkToCxx/CMakeLists.txt index 153c57c..a3067af 100644 --- a/Tests/CSharpLinkToCxx/CMakeLists.txt +++ b/Tests/CSharpLinkToCxx/CMakeLists.txt @@ -21,3 +21,9 @@ target_link_libraries(CSharpLinkToCxx CLIApp) # because it is unmanaged add_library(CppNativeApp SHARED cpp_native.hpp cpp_native.cpp) target_link_libraries(CSharpLinkToCxx CppNativeApp) + +# Link a static C++ library into the CSharp executable. +# We do not actually use any symbols but this helps cover +# link language selection. +add_library(CppStaticLib STATIC cpp_static.cpp) +target_link_libraries(CSharpLinkToCxx CppStaticLib) diff --git a/Tests/CSharpLinkToCxx/cpp_static.cpp b/Tests/CSharpLinkToCxx/cpp_static.cpp new file mode 100644 index 0000000..9af2b6e --- /dev/null +++ b/Tests/CSharpLinkToCxx/cpp_static.cpp @@ -0,0 +1,3 @@ +void cpp_static() +{ +} diff --git a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt index 5495a9b..2e12a78 100644 --- a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt +++ b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt @@ -9,17 +9,17 @@ add_custom_command( ) set_source_files_properties( - "${TestWorkingDir_BINARY_DIR}/customTarget.c" + "${TestWorkingDir_BINARY_DIR}/customTarget1.c" "${TestWorkingDir_BINARY_DIR}/customTarget2.c" PROPERTIES GENERATED 1) add_executable(working "${TestWorkingDir_BINARY_DIR}/working.c" - "${TestWorkingDir_BINARY_DIR}/customTarget.c") + "${TestWorkingDir_BINARY_DIR}/customTarget1.c") add_custom_target( Custom ALL - COMMAND "${CMAKE_COMMAND}" -E copy_if_different ./customTarget.c "${TestWorkingDir_BINARY_DIR}/customTarget.c" - BYPRODUCTS "${TestWorkingDir_BINARY_DIR}/customTarget.c" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different ./customTarget.c "${TestWorkingDir_BINARY_DIR}/customTarget1.c" + BYPRODUCTS "${TestWorkingDir_BINARY_DIR}/customTarget1.c" WORKING_DIRECTORY "${TestWorkingDir_SOURCE_DIR}" ) diff --git a/Tests/RunCMake/Byproducts/CMakeLists.txt b/Tests/RunCMake/Byproducts/CMakeLists.txt new file mode 100644 index 0000000..bf2ef15 --- /dev/null +++ b/Tests/RunCMake/Byproducts/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.10) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/Byproducts/CleanByproducts.cmake b/Tests/RunCMake/Byproducts/CleanByproducts.cmake new file mode 100644 index 0000000..85d9582 --- /dev/null +++ b/Tests/RunCMake/Byproducts/CleanByproducts.cmake @@ -0,0 +1,93 @@ +cmake_minimum_required(VERSION 3.10) +project(CleanByproducts) + +# Configurable parameters +set(TEST_CLEAN_NO_CUSTOM FALSE CACHE BOOL "Value for the CLEAN_NO_CUSTOM PROPERTY") +set(TEST_BUILD_EVENTS TRUE CACHE BOOL "Create byproducts with build events") +set(TEST_CUSTOM_TARGET TRUE CACHE BOOL "Create a byproduct with a custom target") +set(TEST_CUSTOM_COMMAND TRUE CACHE BOOL "Create a byproduct with a custom command") + +set_property(DIRECTORY PROPERTY CLEAN_NO_CUSTOM ${TEST_CLEAN_NO_CUSTOM}) + +macro(add_build_event) + set(oneValueArgs EVENT) + + cmake_parse_Arguments(ABE "" "${oneValueArgs}" "" ${ARGN}) + + # Create two byproducts and only declare one + add_custom_command(TARGET foo + ${ABE_EVENT} + COMMAND ${CMAKE_COMMAND} -E touch foo.${ABE_EVENT} + COMMAND ${CMAKE_COMMAND} -E touch foo.${ABE_EVENT}.notdeclared + COMMENT "Creating byproducts with ${ABE_EVENT}" + BYPRODUCTS foo.${ABE_EVENT} + ) + + # The nondeclared byproduct should always be present + list(APPEND EXPECTED_PRESENT foo.${ABE_EVENT}.notdeclared) + + # If CLEAN_NO_CUSTOM is set, the declared byproduct should be present + if(TEST_CLEAN_NO_CUSTOM) + list(APPEND EXPECTED_PRESENT foo.${ABE_EVENT}) + else() + list(APPEND EXPECTED_DELETED foo.${ABE_EVENT}) + endif() +endmacro() + +add_executable(foo foo.cpp) + +# Test build events +if(TEST_BUILD_EVENTS) + add_build_event(EVENT "PRE_BUILD" ENABLE ${TEST_PRE_BUILD}) + add_build_event(EVENT "PRE_LINK" ENABLE ${TEST_PRE_LINK}) + add_build_event(EVENT "POST_BUILD" ENABLE ${TEST_POST_BUILD}) +endif() + +# Custom command that generates byproducts +if(TEST_CUSTOM_COMMAND) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar.cpp.in "void bar() {}\n") + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/bar.cpp + COMMAND ${CMAKE_COMMAND} -E touch foo.customcommand + COMMAND ${CMAKE_COMMAND} -E touch foo.customcommand.notdeclared + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bar.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/bar.cpp + BYPRODUCTS foo.customcommand + COMMENT "Creating byproducts with a custom command" + ) + + # The nondeclared byproduct should always be present + list(APPEND EXPECTED_PRESENT "foo.customcommand.notdeclared") + + # If CLEAN_NO_CUSTOM is set, both the output and byproduct should be present + if(TEST_CLEAN_NO_CUSTOM) + list(APPEND EXPECTED_PRESENT "bar.cpp") + list(APPEND EXPECTED_PRESENT "foo.customcommand") + else() + list(APPEND EXPECTED_DELETED "bar.cpp") + list(APPEND EXPECTED_DELETED "foo.customcommand") + endif() + + target_sources(foo PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/bar.cpp") +endif() + +# Custom target that generates byproducts +if(TEST_CUSTOM_TARGET) + add_custom_target(foo_file ALL + DEPENDS foo + COMMAND ${CMAKE_COMMAND} -E touch foo.customtarget + COMMAND ${CMAKE_COMMAND} -E touch foo.customtarget.notdeclared + BYPRODUCTS foo.customtarget + COMMENT "Creating byproducts with a custom target" + ) + + # The nondeclared byproduct should always be present + list(APPEND EXPECTED_PRESENT "foo.customtarget.notdeclared") + + # If CLEAN_NO_CUSTOM is set, the declared byproduct should be present + if(TEST_CLEAN_NO_CUSTOM) + list(APPEND EXPECTED_PRESENT "foo.customtarget") + else() + list(APPEND EXPECTED_DELETED "foo.customtarget") + endif() +endif() + +configure_file(files.cmake.in files.cmake) diff --git a/Tests/RunCMake/Byproducts/RunCMakeTest.cmake b/Tests/RunCMake/Byproducts/RunCMakeTest.cmake new file mode 100644 index 0000000..a7584ee --- /dev/null +++ b/Tests/RunCMake/Byproducts/RunCMakeTest.cmake @@ -0,0 +1,58 @@ +include(RunCMake) + +function(run_CleanByproducts case) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CleanByproducts-${case}-build) + set(RunCMake_TEST_OPTIONS "${ARGN}") + + run_cmake(CleanByproducts) + set(RunCMake_TEST_NO_CLEAN 1) + + run_cmake_command(CleanByProducts-build ${CMAKE_COMMAND} --build .) + include("${RunCMake_TEST_BINARY_DIR}/files.cmake") + + message("Checking that all expected files are present") + check_files(EXPECTED_PRESENT "${RunCMake_TEST_BINARY_DIR}" TRUE) + check_files(EXPECTED_DELETED "${RunCMake_TEST_BINARY_DIR}" TRUE) + + run_cmake_command(CleanByProducts-clean ${CMAKE_COMMAND} --build . --target clean) + + message("Checking that only the expected files are present after cleaning") + check_files(EXPECTED_PRESENT "${RunCMake_TEST_BINARY_DIR}" TRUE) + check_files(EXPECTED_DELETED "${RunCMake_TEST_BINARY_DIR}" FALSE) +endfunction() + +function(check_files list path has_to_exist) + foreach(file IN LISTS ${list}) + message("Checking ${file}") + set(file_exists FALSE) + if(EXISTS "${path}/${file}") + set(file_exists TRUE) + endif() + + if(file_exists AND NOT has_to_exist) + message(FATAL_ERROR "${file} should have been deleted") + elseif(NOT file_exists AND has_to_exist) + message(FATAL_ERROR "${file} does not exist") + elseif(file_exists AND has_to_exist) + message("${file} found as expected") + elseif(NOT file_exists AND NOT has_to_exist) + message("${file} deleted as expected") + endif() + + endforeach() +endfunction() + + +# Iterate through all possible test values +set(counter 0) +foreach(test_clean_no_custom TRUE FALSE) + foreach(test_build_events TRUE FALSE) + foreach(test_custom_command TRUE FALSE) + foreach(test_custom_target TRUE FALSE) + math(EXPR counter "${counter} + 1") + message("Test ${counter} - CLEAN_NO_CUSTOM: ${test_clean_no_custom}, Build events: ${test_build_events}, Custom command: ${test_custom_command}, Custom target: ${test_custom_target}") + run_CleanByproducts("buildevents${counter}" -DCLEAN_NO_CUSTOM=${test_clean_no_custom} -DTEST_BUILD_EVENTS=${test_build_events} -DTEST_CUSTOM_COMMAND=${test_custom_command} -DTEST_CUSTOM_TARGET=${test_custom_target}) + endforeach() + endforeach() + endforeach() +endforeach() diff --git a/Tests/RunCMake/Byproducts/files.cmake.in b/Tests/RunCMake/Byproducts/files.cmake.in new file mode 100644 index 0000000..a7d4831 --- /dev/null +++ b/Tests/RunCMake/Byproducts/files.cmake.in @@ -0,0 +1,2 @@ +set(EXPECTED_PRESENT "@EXPECTED_PRESENT@") +set(EXPECTED_DELETED "@EXPECTED_DELETED@") diff --git a/Tests/RunCMake/Byproducts/foo.cpp b/Tests/RunCMake/Byproducts/foo.cpp new file mode 100644 index 0000000..d47cb91 --- /dev/null +++ b/Tests/RunCMake/Byproducts/foo.cpp @@ -0,0 +1,14 @@ +int bar(int y) +{ + return y * 6; +} + +int foo(int x) +{ + return x * bar(x); +} + +int main() +{ + return foo(4); +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 080d0d0..90681b9 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -144,6 +144,9 @@ endif() add_RunCMake_test(AndroidTestUtilities) add_RunCMake_test(BuildDepends) if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja") + add_RunCMake_test(Byproducts) +endif() +if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja") add_RunCMake_test(CompilerChange) endif() add_RunCMake_test(CompilerNotFound) diff --git a/Tests/RunCMake/ctest_submit/FILESNoBuildId-result.txt b/Tests/RunCMake/ctest_submit/FILESNoBuildId-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FILESNoBuildId-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/ctest_submit/FILESNoBuildId-stderr.txt b/Tests/RunCMake/ctest_submit/FILESNoBuildId-stderr.txt new file mode 100644 index 0000000..a8f10b5 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FILESNoBuildId-stderr.txt @@ -0,0 +1 @@ + *Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*) diff --git a/Tests/RunCMake/ctest_submit/FILESNoBuildId-stdout.txt b/Tests/RunCMake/ctest_submit/FILESNoBuildId-stdout.txt new file mode 100644 index 0000000..929b254 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FILESNoBuildId-stdout.txt @@ -0,0 +1 @@ +Upload file: .* to http:\/\/-no-site-\?FileName=test-site___test-build-name___.*-Experimental___XML___RunCMakeTest.cmake&MD5=.* Size: .* diff --git a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake index 7661383..952368d 100644 --- a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake @@ -31,6 +31,7 @@ run_ctest_submit(CDashUploadMissingFile CDASH_UPLOAD bad-upload) run_ctest_submit(CDashUploadRetry CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo RETRY_COUNT 2 RETRY_DELAY 1 INTERNAL_TEST_CHECKSUM) run_ctest_submit(CDashSubmitQuiet QUIET) run_ctest_submit_debug(CDashSubmitVerbose) +run_ctest_submit_debug(FILESNoBuildId FILES ${CMAKE_CURRENT_LIST_FILE}) run_ctest_submit_debug(CDashSubmitHeaders HTTPHEADER "Authorization: Bearer asdf") run_ctest_submit_debug(CDashUploadHeaders CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo HTTPHEADER "Authorization: Bearer asdf") diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c index 4545168..a6cc6db 100644 --- a/Utilities/cmlibuv/src/unix/fs.c +++ b/Utilities/cmlibuv/src/unix/fs.c @@ -425,19 +425,22 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) { return n; } +#if defined(_POSIX_PATH_MAX) +# define UV__FS_PATH_MAX _POSIX_PATH_MAX +#elif defined(PATH_MAX) +# define UV__FS_PATH_MAX PATH_MAX +#else +# define UV__FS_PATH_MAX_FALLBACK 8192 +# define UV__FS_PATH_MAX UV__FS_PATH_MAX_FALLBACK +#endif static ssize_t uv__fs_pathmax_size(const char* path) { ssize_t pathmax; pathmax = pathconf(path, _PC_PATH_MAX); - if (pathmax == -1) { -#if defined(PATH_MAX) - return PATH_MAX; -#else -#error "PATH_MAX undefined in the current platform" -#endif - } + if (pathmax == -1) + pathmax = UV__FS_PATH_MAX; return pathmax; } @@ -446,7 +449,28 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { ssize_t len; char* buf; +#if defined(UV__FS_PATH_MAX_FALLBACK) + /* We may not have a real PATH_MAX. Read size of link. */ + struct stat st; + int ret; + ret = lstat(req->path, &st); + if (ret != 0) + return -1; + if (!S_ISLNK(st.st_mode)) { + errno = EINVAL; + return -1; + } + + len = st.st_size; + + /* According to readlink(2) lstat can report st_size == 0 + for some symlinks, such as those in /proc or /sys. */ + if (len == 0) + len = uv__fs_pathmax_size(req->path); +#else len = uv__fs_pathmax_size(req->path); +#endif + buf = uv__malloc(len + 1); if (buf == NULL) { @@ -473,9 +497,15 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { } static ssize_t uv__fs_realpath(uv_fs_t* req) { - ssize_t len; char* buf; +#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L + buf = realpath(req->path, NULL); + if (buf == NULL) + return -1; +#else + ssize_t len; + len = uv__fs_pathmax_size(req->path); buf = uv__malloc(len + 1); @@ -488,6 +518,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) { uv__free(buf); return -1; } +#endif req->ptr = buf; |