diff --git a/CMakeLists.txt b/CMakeLists.txt index 164cfa1123..16a069524c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -401,3 +401,6 @@ if(NOT _is_multi_config_generator) ) message(STATUS "PROJ: Configured 'dist' target") endif() + +configure_file(cmake/uninstall.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake @ONLY) +add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake) diff --git a/cmake/uninstall.cmake.in b/cmake/uninstall.cmake.in new file mode 100644 index 0000000000..fc949db289 --- /dev/null +++ b/cmake/uninstall.cmake.in @@ -0,0 +1,66 @@ +# install_manifest.txt is created in the top build tree, not the project one +if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"") +endif() + +set(uninstall_file_list "@CMAKE_BINARY_DIR@/install_manifest.txt") +if(EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest_extra.txt") + list(APPEND uninstall_file_list "@CMAKE_CURRENT_BINARY_DIR@/install_manifest_extra.txt") +endif() + +set(dir_list) +foreach (manifest_file IN ITEMS ${uninstall_file_list}) + file(READ "${manifest_file}" files) + string(REGEX REPLACE "\n$" "" files "${files}") + string(REGEX REPLACE "\n" ";" files "${files}") + list(REVERSE files) + foreach (file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if (IS_DIRECTORY "$ENV{DESTDIR}${file}") + list(APPEND dir_list "${file}") + elseif (EXISTS "$ENV{DESTDIR}${file}") + get_filename_component(dir "${file}" DIRECTORY) + list(APPEND dir_list "${dir}") + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + if(NOT ${rm_retval} EQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif (NOT ${rm_retval} EQUAL 0) + else () + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif () + endforeach(file) +endforeach() +list(REMOVE_DUPLICATES dir_list) + +while(NOT "${dir_list}" STREQUAL "") + set(new_dir_list) + foreach (file IN ITEMS ${dir_list}) + if (IS_DIRECTORY "$ENV{DESTDIR}${file}" AND "${file}" MATCHES "@CMAKE_INSTALL_PREFIX@.+") + file(GLOB file_list "$ENV{DESTDIR}${file}/*") + list(LENGTH file_list file_list_len) + # Only remove empty directories + if(file_list_len EQUAL 0) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove_directory "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + if(${rm_retval} EQUAL 0) + get_filename_component(upper_dir "${file}" DIRECTORY) + list(APPEND new_dir_list "${upper_dir}") + else() + message(STATUS "Problem when removing directory \"$ENV{DESTDIR}${file}\"") + endif() + endif() + endif() + endforeach() + list(REMOVE_DUPLICATES new_dir_list) + set(dir_list "${new_dir_list}") +endwhile() + + diff --git a/travis/install.sh b/travis/install.sh index 57b3857e86..ddbb7f9a03 100755 --- a/travis/install.sh +++ b/travis/install.sh @@ -76,6 +76,15 @@ make install $TRAVIS_BUILD_DIR/test/postinstall/test_cmake.sh /tmp/proj_shared_install_from_dist shared $TRAVIS_BUILD_DIR/test/postinstall/test_autotools.sh /tmp/proj_shared_install_from_dist shared +# Test install and uninstall targets with DESTDIR +make install DESTDIR=/tmp/destdir +make uninstall DESTDIR=/tmp/destdir +if [ ! -z "$(ls -A /tmp/destdir/tmp/proj_shared_install_from_dist)" ]; then + echo "Directory /tmp/destdir/tmp/proj_shared_install_from_dist should be empty, but its content is:" + find /tmp/destdir/tmp/proj_shared_install_from_dist + exit 1 +fi + echo "Build static ${CMAKE_BUILD_TYPE} configuration from generated tarball" cd .. mkdir static_build