summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-18 12:42:34 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-09-18 12:43:13 (GMT)
commitce89f54ee30038fea7abe7a25a2bfe5c14f08cce (patch)
tree36dc5d7b9a03481e825e820f9b0da749fa73a3cb
parent9472ed34e9567fb7d89970125fcca773346dcfe4 (diff)
parent6a88e6332f1b31c337f8a7ddb73b1cf8c782f35e (diff)
downloadCMake-ce89f54ee30038fea7abe7a25a2bfe5c14f08cce.zip
CMake-ce89f54ee30038fea7abe7a25a2bfe5c14f08cce.tar.gz
CMake-ce89f54ee30038fea7abe7a25a2bfe5c14f08cce.tar.bz2
Merge topic 'rel-drop-old'
6a88e6332f Utilities/Release: Drop now-unused scripts Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5234
-rw-r--r--Tests/CMakeLists.txt17
-rw-r--r--Utilities/CMakeLists.txt20
-rw-r--r--Utilities/Release/README.rst20
-rw-r--r--Utilities/Release/create-cmake-release.cmake52
-rw-r--r--Utilities/Release/release_cmake.cmake165
-rwxr-xr-xUtilities/Release/release_cmake.sh.in158
6 files changed, 1 insertions, 431 deletions
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index b0cb8d4..ee3ac3d 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -788,23 +788,6 @@ if(BUILD_TESTING)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SubProject")
endif()
- # macro to add a test that will build a nightly release
- # of CMake for given platform using the release scripts
- macro(ADD_NIGHTLY_BUILD_TEST name script)
- set(_TEST_DIR "${CMake_BINARY_DIR}/Tests/${name}")
- file(MAKE_DIRECTORY "${_TEST_DIR}")
- file(WRITE "${_TEST_DIR}/nightly-cmake.sh"
- "set -e
-cd ${_TEST_DIR}
-${CMake_BINARY_DIR}/bin/cmake -DCMAKE_CREATE_VERSION=nightly -P ${CMake_SOURCE_DIR}/Utilities/Release/${script}
-${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGHTLY_RELEASES}'
- ")
- add_test(${name} /bin/sh ${_TEST_DIR}/nightly-cmake.sh)
- if(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY)
- set_tests_properties (${name} PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
- endif()
- endmacro()
-
# add tests with more complex invocations
add_test(Framework ${CMAKE_CTEST_COMMAND}
--build-and-test
diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt
index b739ae2..2a8c855 100644
--- a/Utilities/CMakeLists.txt
+++ b/Utilities/CMakeLists.txt
@@ -3,25 +3,7 @@
subdirs(Doxygen)
-if(CMAKE_DOC_TARBALL)
- # Undocumented option to extract and install pre-built documentation.
- # This is intended for use during packaging of CMake itself.
- if(CMAKE_DOC_TARBALL MATCHES "/([^/]+)\\.tar\\.gz$")
- set(dir "${CMAKE_MATCH_1}")
- else()
- message(FATAL_ERROR "CMAKE_DOC_TARBALL must end in .tar.gz")
- endif()
- add_custom_command(
- OUTPUT ${dir}.stamp
- COMMAND cmake -E rm -rf ${dir}
- COMMAND cmake -E tar xf ${CMAKE_DOC_TARBALL}
- COMMAND cmake -E touch ${dir}.stamp
- DEPENDS ${CMAKE_DOC_TARBALL}
- )
- add_custom_target(documentation ALL DEPENDS ${dir}.stamp)
- install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir}/
- DESTINATION . USE_SOURCE_PERMISSIONS)
-elseif (CMake_DOC_ARTIFACT_PREFIX)
+if (CMake_DOC_ARTIFACT_PREFIX)
# Undocumented option for CI usage to reuse already
# built documentation.
install(DIRECTORY ${CMake_DOC_ARTIFACT_PREFIX}/
diff --git a/Utilities/Release/README.rst b/Utilities/Release/README.rst
index 9993afa..2d3525d 100644
--- a/Utilities/Release/README.rst
+++ b/Utilities/Release/README.rst
@@ -74,23 +74,3 @@ Each ``<os>/<arch>/`` directory contains the following:
argument specifying either ``x86_64`` or ``i386``.
.. _`kitware/cmake Docker Hub Repository`: https://hub.docker.com/r/kitware/cmake
-
-Scripts for Kitware
--------------------
-
-Kitware uses the following scripts to produce binaries for ``cmake.org``.
-They work only on specific machines Kitware uses for such builds.
-
-* ``create-cmake-release.cmake``:
- Run ``cmake -DCMAKE_CREATE_VERSION=$ver -P ../create-cmake-release.cmake``
- to generate ``create-$ver-*.sh`` release scripts. It also displays
- instructions to run them.
-
-* ``*_release.cmake``:
- Platform-specific settings used in corresponding scripts generated above.
-
-* ``release_cmake.cmake``:
- Code shared by all ``*_release.cmake`` scripts.
-
-* ``release_cmake.sh.in``:
- Template for script that runs on the actual build machines.
diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake
deleted file mode 100644
index 562df91..0000000
--- a/Utilities/Release/create-cmake-release.cmake
+++ /dev/null
@@ -1,52 +0,0 @@
-if(NOT DEFINED CMAKE_CREATE_VERSION)
- set(CMAKE_CREATE_VERSION "release")
- message("Using default value of 'release' for CMAKE_CREATE_VERSION")
-endif()
-
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/logs)
-
-function(write_rel_shell_script filename script)
- file(WRITE ${filename} "#!/usr/bin/env bash
-\"${CMAKE_COMMAND}\" -DCMAKE_CREATE_VERSION=${CMAKE_CREATE_VERSION} -DCMAKE_DOC_TARBALL=\"${CMAKE_DOC_TARBALL}\" -P \"${CMAKE_CURRENT_LIST_DIR}/${script}.cmake\" < /dev/null 2>&1 | tee \"${CMAKE_CURRENT_SOURCE_DIR}/logs/${script}-${CMAKE_CREATE_VERSION}.log\"
-")
- execute_process(COMMAND chmod a+x ${filename})
-endfunction()
-
-function(write_docs_shell_script filename)
- find_program(SPHINX_EXECUTABLE
- NAMES sphinx-build sphinx-build.py
- DOC "Sphinx Documentation Builder (sphinx-doc.org)"
- )
- if(NOT SPHINX_EXECUTABLE)
- message(FATAL_ERROR "SPHINX_EXECUTABLE (sphinx-build) is not found!")
- endif()
-
- set(name cmake-${CMAKE_CREATE_VERSION}-docs)
- file(WRITE "${filename}" "#!/usr/bin/env bash
-
-name=${name} &&
-inst=\"\$PWD/\$name\"
-(GIT_WORK_TREE=x git archive --prefix=\${name}-src/ ${CMAKE_CREATE_VERSION}) | tar x &&
-rm -rf \${name}-build &&
-mkdir \${name}-build &&
-cd \${name}-build &&
-\"${CMAKE_COMMAND}\" ../\${name}-src/Utilities/Sphinx \\
- -DCMAKE_INSTALL_PREFIX=\"\$inst/\" \\
- -DCMAKE_DOC_DIR=doc/cmake \\
- -DSPHINX_EXECUTABLE=\"${SPHINX_EXECUTABLE}\" \\
- -DSPHINX_HTML=ON -DSPHINX_MAN=ON -DSPHINX_QTHELP=ON &&
-make install &&
-cd .. &&
-tar czf \${name}.tar.gz \${name} ||
-echo 'Failed to create \${name}.tar.gz'
-")
- execute_process(COMMAND chmod a+x ${filename})
- set(CMAKE_DOC_TARBALL "${name}.tar.gz" PARENT_SCOPE)
-endfunction()
-
-write_docs_shell_script("create-${CMAKE_CREATE_VERSION}-docs.sh")
-
-message("Build docs first and then build for each platform:
- ./create-${CMAKE_CREATE_VERSION}-docs.sh &&
- echo done
-")
diff --git a/Utilities/Release/release_cmake.cmake b/Utilities/Release/release_cmake.cmake
deleted file mode 100644
index b2c21b7..0000000
--- a/Utilities/Release/release_cmake.cmake
+++ /dev/null
@@ -1,165 +0,0 @@
-get_filename_component(SCRIPT_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH)
-
-# default to self extracting tgz, tgz, and tar.Z
-if(NOT DEFINED CPACK_BINARY_GENERATORS)
- set(CPACK_BINARY_GENERATORS "STGZ TGZ TZ")
-endif()
-if(NOT DEFINED CMAKE_RELEASE_DIRECTORY)
- set(CMAKE_RELEASE_DIRECTORY "~/CMakeReleaseDirectory")
-endif()
-if(NOT DEFINED SCRIPT_NAME)
- set(SCRIPT_NAME "${HOST}")
-endif()
-if(NOT DEFINED MAKE_PROGRAM)
- message(FATAL_ERROR "MAKE_PROGRAM must be set")
-endif()
-if(NOT DEFINED MAKE)
- set(MAKE "${MAKE_PROGRAM}")
-endif()
-if(NOT DEFINED RUN_SHELL)
- set(RUN_SHELL "/bin/sh")
-endif()
-if(NOT DEFINED RUN_LAUNCHER)
- set(RUN_LAUNCHER "")
-endif()
-if(NOT DEFINED PROCESSORS)
- set(PROCESSORS 1)
-endif()
-if(NOT DEFINED CMAKE_CREATE_VERSION)
- message(FATAL_ERROR "CMAKE_CREATE_VERSION not defined")
-endif()
-if(NOT DEFINED GIT_COMMAND)
- set(GIT_COMMAND git)
-endif()
-
-if(CMAKE_CREATE_VERSION MATCHES "^(master|release)$")
- set(GIT_FETCH "")
- set(GIT_BRANCH origin/${CMAKE_CREATE_VERSION})
-elseif(CMAKE_CREATE_VERSION STREQUAL "nightly")
- set(nightly stage/master/nightly/latest)
- set(GIT_FETCH "${GIT_COMMAND} fetch origin refs/${nightly}:refs/remotes/origin/${nightly}")
- set(GIT_BRANCH origin/${nightly})
-else()
- set(stage stage/master/head)
- set(GIT_FETCH "${GIT_COMMAND} fetch origin refs/${stage}:refs/remotes/origin/${stage}")
- set(GIT_BRANCH ${CMAKE_CREATE_VERSION})
-endif()
-
-if(NOT DEFINED FINAL_PATH )
- set(FINAL_PATH ${CMAKE_RELEASE_DIRECTORY}/${CMAKE_CREATE_VERSION}-build)
-endif()
-
-if(NOT HOST)
- message(FATAL_ERROR "HOST must be specified with -DHOST=host")
-endif()
-if(NOT DEFINED MAKE)
- message(FATAL_ERROR "MAKE must be specified with -DMAKE=\"make -j2\"")
-endif()
-
-message("Creating CMake release ${CMAKE_CREATE_VERSION} on ${HOST} with parallel = ${PROCESSORS}")
-
-# define a macro to run a remote command
-macro(remote_command comment command)
- message("${comment}")
- if(${ARGC} GREATER 2)
- message("ssh ${HOST} ${RUN_LAUNCHER} ${command}")
- execute_process(COMMAND ssh ${HOST} ${RUN_LAUNCHER} ${command} RESULT_VARIABLE result INPUT_FILE ${ARGV2})
- else()
- message("ssh ${HOST} ${RUN_LAUNCHER} ${command}")
- execute_process(COMMAND ssh ${HOST} ${RUN_LAUNCHER} ${command} RESULT_VARIABLE result)
- endif()
- if(${result} GREATER 0)
- message(FATAL_ERROR "Error running command: ${command}, return value = ${result}")
- endif()
-endmacro()
-
-if(CMAKE_DOC_TARBALL)
- get_filename_component(CMAKE_DOC_TARBALL_NAME "${CMAKE_DOC_TARBALL}" NAME)
- string(REPLACE ".tar.gz" "-${SCRIPT_NAME}.tar.gz" CMAKE_DOC_TARBALL_STAGED "${CMAKE_DOC_TARBALL_NAME}")
- message("scp '${CMAKE_DOC_TARBALL}' '${HOST}:${CMAKE_DOC_TARBALL_STAGED}'")
- execute_process(COMMAND
- scp ${CMAKE_DOC_TARBALL} ${HOST}:${CMAKE_DOC_TARBALL_STAGED}
- RESULT_VARIABLE result)
- if(${result} GREATER 0)
- message("error sending doc tarball with scp '${CMAKE_DOC_TARBALL}' '${HOST}:${CMAKE_DOC_TARBALL_STAGED}'")
- endif()
-endif()
-
-# set this so configure file will work from script mode
-# create the script specific for the given host
-set(SCRIPT_FILE release_cmake-${SCRIPT_NAME}.sh)
-configure_file(${SCRIPT_PATH}/release_cmake.sh.in ${SCRIPT_FILE} @ONLY)
-
-# run the script by starting a shell on the remote machine
-# then using the script file as input to the shell
-if(RUN_LOCAL)
- message(FATAL_ERROR "run this command: ${RUN_SHELL} ${SCRIPT_FILE}")
-else()
- remote_command("run release_cmake-${HOST}.sh on server"
- "${RUN_SHELL}" ${SCRIPT_FILE})
-endif()
-
-# now figure out which types of packages were created
-set(generators ${CPACK_BINARY_GENERATORS} ${CPACK_SOURCE_GENERATORS})
-separate_arguments(generators)
-foreach(gen ${generators})
- if("${gen}" STREQUAL "TGZ")
- set(SUFFIXES ${SUFFIXES} "*.tar.gz")
- endif()
- if("${gen}" STREQUAL "STGZ")
- set(SUFFIXES ${SUFFIXES} "*.sh")
- endif()
- if("${gen}" STREQUAL "DragNDrop")
- set(SUFFIXES ${SUFFIXES} "*.dmg")
- endif()
- if("${gen}" STREQUAL "TBZ2")
- set(SUFFIXES ${SUFFIXES} "*.tar.bz2")
- endif()
- if("${gen}" STREQUAL "TZ")
- set(SUFFIXES ${SUFFIXES} "*.tar.Z")
- endif()
- if("${gen}" STREQUAL "WIX")
- set(SUFFIXES ${SUFFIXES} "*.msi")
- endif()
- if("${gen}" STREQUAL "ZIP")
- set(SUFFIXES ${SUFFIXES} "*.zip")
- endif()
- if("${gen}" STREQUAL "NSIS")
- set(SUFFIXES ${SUFFIXES} "*.exe")
- endif()
-endforeach()
-
-if(SUFFIXES)
- list(REMOVE_DUPLICATES SUFFIXES)
-endif()
-
-if(LOCAL_DIR)
- file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${LOCAL_DIR}")
-else()
- set(LOCAL_DIR .)
-endif()
-
-# copy all the files over from the remote machine
-set(PROJECT_PREFIX cmake-)
-foreach(suffix ${SUFFIXES})
- message("scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} ${LOCAL_DIR}")
- execute_process(COMMAND
- scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} ${LOCAL_DIR}
- RESULT_VARIABLE result)
- if(${result} GREATER 0)
- message("error getting file back scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} ${LOCAL_DIR}")
- endif()
-endforeach()
-
-# if there are extra files to copy get them as well
-if(extra_files)
- foreach(f ${extra_files})
- message("scp ${HOST}:${FINAL_PATH}/${f} ${LOCAL_DIR}")
- execute_process(COMMAND
- scp ${HOST}:${FINAL_PATH}/${f} ${LOCAL_DIR}
- RESULT_VARIABLE result)
- if(${result} GREATER 0)
- message("error getting file back scp ${HOST}:${FINAL_PATH}/${f} ${LOCAL_DIR}")
- endif()
- endforeach()
-endif()
diff --git a/Utilities/Release/release_cmake.sh.in b/Utilities/Release/release_cmake.sh.in
deleted file mode 100755
index 696a3f4..0000000
--- a/Utilities/Release/release_cmake.sh.in
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/bin/sh
-echo "Start release"
-date
-echo ""
-echo "remove and create working directory @CMAKE_RELEASE_DIRECTORY@"
-rm -rf @CMAKE_RELEASE_DIRECTORY@
-mkdir @CMAKE_RELEASE_DIRECTORY@
-@ENV@
-
-check_exit_value()
-{
- VALUE="$1"
- if [ "$VALUE" != "0" ]; then
- echo "error in $2"
- exit 1
- fi
-}
-
-CMAKE_DOC_TARBALL=""
-if [ ! -z "@CMAKE_DOC_TARBALL_NAME@" ] ; then
- CMAKE_DOC_TARBALL=@CMAKE_RELEASE_DIRECTORY@/@CMAKE_DOC_TARBALL_NAME@
- mv "$HOME/@CMAKE_DOC_TARBALL_STAGED@" "$CMAKE_DOC_TARBALL"
- check_exit_value $? "mv doc tarball" || exit 1
-fi
-
-if [ ! -z "@CC@" ]; then
- export CC="@CC@"
- check_exit_value $? "set CC compiler env var" || exit 1
-fi
-
-if [ ! -z "@FC@" ]; then
- export FC="@FC@"
- check_exit_value $? "set FC compiler env var" || exit 1
-fi
-
-if [ ! -z "@CXX@" ]; then
- export CXX="@CXX@"
- check_exit_value $? "set CC compiler env var" || exit 1
-fi
-
-if [ ! -z "@LDFLAGS@" ]; then
- export LDFLAGS="@LDFLAGS@"
- check_exit_value $? "set LDFLAGS env var" || exit 1
-fi
-
-if [ ! -z "@FFLAGS@" ]; then
- export FFLAGS="@FFLAGS@"
- check_exit_value $? "set FFLAGS env var" || exit 1
-fi
-
-if [ ! -z "@CFLAGS@" ]; then
- export CFLAGS="@CFLAGS@"
- check_exit_value $? "set CFLAGS env var" || exit 1
-fi
-
-if [ ! -z "@CXXFLAGS@" ]; then
- export CXXFLAGS="@CXXFLAGS@"
- check_exit_value $? "setCXXFLAGS env var" || exit 1
-fi
-
-if [ ! -z "@USER_MAKE_RULE_FILE_CONTENTS@" ]; then
- echo "@USER_MAKE_RULE_FILE_CONTENTS@" > "@USER_MAKE_RULE_FILE@"
- check_exit_value $? "Create User Rule file" || exit 1
-fi
-echo "Create a directory to build in"
-rm -rf @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build
-check_exit_value $? "Remove build tree" || exit 1
-mkdir @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build
-check_exit_value $? "Create build directory" || exit 1
-# make sure directory was created
-if [ ! -d @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build ]; then
- echo "Could not create @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build"
- exit -1
-fi
-
-echo "Create initial cache"
-echo "@INITIAL_CACHE@" > @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/CMakeCache.txt
-check_exit_value $? "Create initial cache" || exit 1
-
-# create a user override file user.txt if USER_OVERRIDE is set,
-# and append the cache variable to the cache
-if [ ! -z "@USER_OVERRIDE@" ]; then
- echo "@USER_OVERRIDE@" > @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/user.txt
- echo "CMAKE_USER_MAKE_RULES_OVERRIDE:FILEPATH=@CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/user.txt" >> @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/CMakeCache.txt
-fi
-
-# Point build at pre-built documentation tarball, if any.
-if [ ! -z "$CMAKE_DOC_TARBALL" ]; then
- echo "CMAKE_DOC_TARBALL:FILEPATH=$CMAKE_DOC_TARBALL" >> @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/CMakeCache.txt
-fi
-
-echo "Checkout the source for @CMAKE_CREATE_VERSION@"
-cd @CMAKE_RELEASE_DIRECTORY@
-if [ ! -z "@GIT_COMMAND@" ]; then
- # clone the repo without creating any source files in the directory
- # matching the branch being built (i.e. master CMake-2-8, etc)
- @GIT_COMMAND@ clone -n https://gitlab.kitware.com/cmake/cmake.git @CMAKE_CREATE_VERSION@
- check_exit_value $? "git clone cmake source" || exit 1
- # go into the git directory
- cd @CMAKE_CREATE_VERSION@
- # run any extra commands if they exist
- @GIT_EXTRA@
- check_exit_value $? "git extra cmake source" || exit 1
- @GIT_FETCH@
- check_exit_value $? "git extra fetch" || exit 1
- # now checkout a copy on the local branch working
- @GIT_COMMAND@ checkout -b working @GIT_BRANCH@
- check_exit_value $? "git checkout" || exit 1
- cd ..
-else
- echo GIT_COMMAND does not exist
- exit 1
-fi
-
-cd @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build
-
-if [ ! -z "@CONFIGURE_WITH_CMAKE@" ]; then
- echo "Run cmake to configure cmake"
- @CMAKE_CONFIGURE_PATH@ ../@CMAKE_CREATE_VERSION@
- check_exit_value $? "Configure cmake" || exit 1
-else
- echo "Run cmake bootstrap @BOOTSTRAP_ARGS@ --parallel=@PROCESSORS@"
- ../@CMAKE_CREATE_VERSION@/bootstrap @BOOTSTRAP_ARGS@ --parallel=@PROCESSORS@
- check_exit_value $? "Bootstrap cmake" || exit 1
-fi
-
-echo "Build cmake with @MAKE@"
-@MAKE@
-check_exit_value $? "Build cmake" || exit 1
-
-if [ -z "@SKIP_TESTS@" ]; then
- echo "Run cmake tests"
- ./bin/ctest --output-on-failure -j @PROCESSORS@ @EXTRA_CTEST_ARGS@
- check_exit_value $? "Test cmake" || exit 1
-fi
-
-# loop over binary generators
-generators="@CPACK_BINARY_GENERATORS@"
-for GEN in $generators; do
- echo "Create $GEN package"
- ./bin/cpack -D CMAKE_MAKE_PROGRAM=@MAKE_PROGRAM@ -G $GEN
- check_exit_value $? "Create $GEN package" || exit 1
-done
-
-# loop over source generators
-generators="@CPACK_SOURCE_GENERATORS@"
-for GEN in $generators; do
- echo "Create $GEN package"
- ./bin/cpack -D CMAKE_MAKE_PROGRAM=@MAKE_PROGRAM@ -G $GEN --config CPackSourceConfig.cmake
- check_exit_value $? "Create $GEN package" || exit 1
-done
-
-@SIGN@
-
-echo "End release"
-date
-echo ""
-exit 0