# Machinery for running the external project
set(EXTERNAL_FFTW_VERSION 3.3.3)
# cmake make eats slashes //// -> //
-set(GMX_BUILD_OWN_FFTW_URL "http:////www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CACHE PATH "URL from where to download fftw, (use an absolute path when offline)")
-mark_as_advanced(GMX_BUILD_OWN_FFTW_URL)
-set(EXTERNAL_FFTW_MD5SUM 0a05ca9c7b3bfddc8278e7c40791a1c2)
-set (EXTERNAL_FFTW_BUILD_TARGET fftwBuild)
+set(GMX_BUILD_OWN_FFTW_URL
+ "http:////www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CACHE PATH
+ "URL from where to download fftw (use an absolute path when offline, adjust GMX_BUILD_OWN_FFTW_MD5 if downloading other version than ${EXTERNAL_FFTW_VERSION})")
+set(GMX_BUILD_OWN_FFTW_MD5 0a05ca9c7b3bfddc8278e7c40791a1c2 CACHE STRING
+ "Expected MD5 hash for the file at GMX_BUILD_OWN_FFTW_URL")
+mark_as_advanced(GMX_BUILD_OWN_FFTW_URL GMX_BUILD_OWN_FFTW_MD5)
+
+# ExternalProject at least up to CMake 3.0 prints a confusing error message if
+# download fails when MD5 verification is enabled. So we manage the download
+# ourselves so that MD5 sum is not verified there, and then pass a local file
+# as the URL to ExternalProject. This way, ExternalProject still verifies the
+# MD5 sum with a proper message if that fails.
+set(url "${GMX_BUILD_OWN_FFTW_URL}")
+# Determine whether we are actually downloading (this matches the conditions in
+# ExternalProject). ExternalProject works as expected if passed a local file.
+set(is_download TRUE)
+if (IS_DIRECTORY "${url}" OR "${url}" MATCHES "^file://" OR NOT "${url}" MATCHES "^[a-z]+://")
+ set(is_download FALSE)
+endif()
+if (is_download)
+ # For simplicity, don't try to extract the file name from the URL, but use
+ # a hard-coded value.
+ set(remote_url "${GMX_BUILD_OWN_FFTW_URL}")
+ set(local_path "${CMAKE_CURRENT_BINARY_DIR}/fftw.tar.gz")
+ set(url ${local_path})
+ # Write a script to do our own download step (mimics what ExternalProject
+ # would do, but without MD5 sum verification at this step).
+ set(download_script ${CMAKE_CURRENT_BINARY_DIR}/fftw-download.cmake)
+ configure_file(fftw-download.cmake.cmakein ${download_script} @ONLY)
+endif()
+
+# The actual build target.
+set(EXTERNAL_FFTW_BUILD_TARGET fftwBuild)
include(ExternalProject)
-# TODO in master branch - show this warning only on the first run
-# by using gmx_check_if_changed_result from I21b791ab8e4f3 when
-# that becomes available
-message(WARNING "The GROMACS build will download FFTW ${EXTERNAL_FFTW_VERSION} as requested, but it will not know the file it receives is correct. If you now use\nmake\n GROMACS will build and link to FFTW anyway, but there is a possible security risk if you execute a GROMACS tool that calls this library. Instead, you can use\nmake ${EXTERNAL_FFTW_BUILD_TARGET}\n to do just the download and build of FFTW, and then run\nmd5sum src/contrib/fftw/${EXTERNAL_FFTW_BUILD_TARGET}-prefix/src/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz\nto see if it matches ${EXTERNAL_FFTW_MD5SUM}. If so, everything is OK and you should use \nmake\n to proceed with the rest of the GROMACS build. Alternatively, you could stop using GMX_BUILD_OWN_FFTW, and instead follow the GROMACS installation instructions to build FFTW yourself.")
-# TODO if/when CMake fixes http://www.cmake.org/Bug/view.php?id=14330
-# (ie. at least version > 2.8.11.2), consider reverting to using an
-# md5sum check to avoid needing the above warning
- ExternalProject_add(${EXTERNAL_FFTW_BUILD_TARGET}
- URL "${GMX_BUILD_OWN_FFTW_URL}"
+ExternalProject_add(${EXTERNAL_FFTW_BUILD_TARGET}
+ URL "${url}" URL_MD5 ${GMX_BUILD_OWN_FFTW_MD5}
CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --libdir=<INSTALL_DIR>/lib --disable-fortran
${GMX_BUILD_OWN_FFTW_SHARED_FLAG} ${GMX_BUILD_OWN_FFTW_OPTIMIZATION_CONFIGURATION}
${GMX_BUILD_OWN_FFTW_PREC}
${GMX_BUILD_OWN_FFTW_TARGET_HOST})
-externalproject_get_property(${EXTERNAL_FFTW_BUILD_TARGET} INSTALL_DIR)
+# Add a custom step to do our own download if that is necessary.
+if (is_download)
+ ExternalProject_add_step(${EXTERNAL_FFTW_BUILD_TARGET} pre-download
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/fftw-download.cmake
+ DEPENDERS download)
+endif()
+
+ExternalProject_get_property(${EXTERNAL_FFTW_BUILD_TARGET} INSTALL_DIR)
string(TOUPPER "${FFTW}" UPPERFFTW)
string(TOLOWER "${FFTW}" LOWERFFTW)
--- /dev/null
+# Custom download script for Gromacs external FFTW build.
+
+# Mimics a similar script generated by CMake ExternalProject package, but
+# does not verify the MD5 sum (which would give confusing error messages if the
+# download fails).
+message(STATUS "downloading...
+ src='@remote_url@'
+ dest='@local_path@'")
+file(DOWNLOAD "@remote_url@" "@local_path@"
+ SHOW_PROGRESS STATUS status LOG log)
+list(GET status 0 status_code)
+list(GET status 1 status_string)
+if (NOT status_code EQUAL 0)
+ message(FATAL_ERROR "error: downloading '@remote_url@' failed
+ status_code: ${status_code}
+ status_string: ${status_string}
+ log: ${log}")
+endif()
+message(STATUS "downloading... done")