From 57fa9b3d5f63bf3c63e7b0ef64665b7c8d75b195 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Wed, 27 Mar 2013 19:15:00 +0000 Subject: [PATCH] Merged latest changes from netcdf-cmake branch. Includes a few windows fixes, plus the skeleton for 'make dist' and 'make distcheck' support in cmake-based builds. --- CMakeLists.txt | 13 ++ cmake/modules/FindMakeDist.cmake | 250 +++++++++++++++++++++++++++++++ cmake_config.h.in | 9 +- include/onstack.h | 7 +- 4 files changed, 274 insertions(+), 5 deletions(-) create mode 100644 cmake/modules/FindMakeDist.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f28c3a74a..eadae4e6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ cmake_minimum_required(VERSION 2.8.8) #Project Name project(netCDF C) +set(PACKAGE "netCDF" CACHE STRING "") SET(netCDF_VERSION_MAJOR 4) SET(netCDF_VERSION_MINOR 3) SET(netCDF_VERSION_PATCH 0) @@ -71,6 +72,15 @@ INCLUDE (${CMAKE_ROOT}/Modules/TestBigEndian.cmake) INCLUDE (${CMAKE_ROOT}/Modules/CheckSymbolExists.cmake) INCLUDE (${CMAKE_ROOT}/Modules/GetPrerequisites.cmake) FIND_PACKAGE(PkgConfig QUIET) + + +## Enable 'dist and distcheck'. +## File taken from http://ensc.de/cmake/FindMakeDist.cmake +FIND_PACKAGE(MakeDist) +ADD_MAKEDIST() +ENABLE_MAKEDIST(cmake_config.h.in CMakeLists.txt cmake) + +## End 'enable dist and distcheck' # Only necessary for Windows IF(MSVC) INCLUDE (${CMAKE_SOURCE_DIR}/cmake/modules/windows/FindHDF5.cmake) @@ -606,6 +616,7 @@ IF(NOT HAVE_UNISTD_H) ENDIF() CHECK_INCLUDE_FILE("alloca.h" HAVE_ALLOCA_H) +CHECK_INCLUDE_FILE("malloc.h" HAVE_MALLOC_H) CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H) CHECK_INCLUDE_FILE("dirent.h" HAVE_DIRENT_H) CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H) @@ -672,6 +683,8 @@ CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE) CHECK_FUNCTION_EXISTS(sysconf HAVE_SYSCONF) CHECK_FUNCTION_EXISTS(mremap HAVE_MREMAP) CHECK_FUNCTION_EXISTS(getrlimit HAVE_GETRLIMIT) + + ##### # End system inspection checks. ##### diff --git a/cmake/modules/FindMakeDist.cmake b/cmake/modules/FindMakeDist.cmake new file mode 100644 index 000000000..47df53972 --- /dev/null +++ b/cmake/modules/FindMakeDist.cmake @@ -0,0 +1,250 @@ +# - adds support for the 'make dist' and 'make distcheck' commands -*- cmake -*- +# +# Usage: +# add_makedist() ... called exactly once per project in the top-level +# CMakeLists.txt; it adds the 'dist' and 'distcheck' +# targets +# +# enable_makedist(...list-of-sources...) +# ... called in every CMakeLists.txt which has source +# files. Beside the listed sources, the CMakeLists.txt +# file itself and all files listed in ${EXTRA_DIST} +# will be added to the tarball +# +# This module implements the 'make dist' and 'make distcheck' +# commands. When sources are given to enable_makedist() which are +# having the 'GENERATED' property, they will be ignored unless +# they are in ${EXTRA_DIST} or are having the EXTRADIST property. +# +# It supports the following variables: +# +# MAKEDIST_TMPDIR ... directory for temporary files +# MAKEDIST_PKGBASE ... basename of the created tarball; defaults to +# ${PACKAGE}-${VERSION} (see below) +# MAKEDIST_TARFLAGS ... flags which are used to create the tarball +# MAKEDIST_CMAKEFLAGS +# ... flags which are given to 'cmake' by 'make distcheck' +# MAKEDIST_BUILDTARGETS +# ... the build-targets tried by 'make distcheck'; +# defaults to nothing (--> all) +# MAKEDIST_CHECKTARGETS +# ... the check-targets tried by 'make distcheck'; +# defaults to 'test' +# MAKEDIST_INSTALLTARGETS +# ... the install-targets tried by 'make distcheck'; +# defaults to 'install' +# +# EXTRA_DIST ... set per CMakeLists.txt file to add non-source or +# generated source files to the tarball +# +# Unless MAKEDIST_PKGBASE is modified, the following variables are +# required to be set: +# +# PACKAGE ... name of the package (e.g. 'foo') +# VERSION ... version of the package (e.g. '0.1.2') +# +# +# Example: +# --- top-level CMakeLists.txt --- +# set(PACKAGE foo) +# set(VERSION 1.2.3) +# +# find_package(MakeDist) +# add_subdirectory(foo) +# +# add_makedist() +# +# set(EXTRA_DIST COPYING) +# enable_makedist(config.h.in) +# +# --> adds ./COPYING and ./config.h.in to the tarball +# +# --- foo/CMakeLists.txt --- +# set_source_files_properties( +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-A.h +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-B.h +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-C.h +# PROPERTIES GENERATED TRUE) +# +# set_source_files_properties( +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-A.h +# PROPERTIES EXTRADIST TRUE) +# set(EXTRA_DIST ${CMAKE_CURRENT_BINARY_DIR}/generated-file-B.h) +# +# enable_makedist( +# foo.c +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-A.h +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-B.h +# ${CMAKE_CURRENT_BINARY_DIR}/generated-file-C.h) +# +# --> adds ./foo/generated-file-{A,B}.h and ./foo/foo.c to the +# tarball, but not ${CMAKE_CURRENT_BINARY_DIR}/generated-file-C.h +# +# TODO/limitations: +# * works probably with the 'make' generator only +# * requires at least a SUSv3/POSIX compliant system; some parts +# (e.g. bzip2-tarballs) depend on some GNUisms; this should be +# made configurable perhaps +# * there could be added some more tests (e.g. gnit-style (check for +# existence of required files and a proper VERSION format)) +# * it is somehow ugly, to see hundreds of 'Built target .distdir' +# messages +# * is is ugly that all sources must be specified for enable_makedist(); +# there should be added support to 'cmake' to enumerate targets and +# their sources + + +# Copyright (C) 2006 Enrico Scholz +# +# Redistribution and use, with or without modification, are permitted +# provided that the following conditions are met: +# +# 1. Redistributions must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +set(MakeDist_FOUND 1) + +set(MAKEDIST_TMPDIR "${CMAKE_BINARY_DIR}/.make-dist" CACHE PATH "directory for temporary files created by'make dist*'") +set(MAKEDIST_PKGBASE "${PACKAGE}-${VERSION}" CACHE STRING "basename of the tarball created by 'make dist*'") +set(MAKEDIST_TARFLAGS --bzip2 CACHE STRING "flags used by 'make dist' to create the tarball") +set(MAKEDIST_TARBALL "${CMAKE_BINARY_DIR}/${MAKEDIST_PKGBASE}.tar.bz2" CACHE PATH "tarball created by 'make dist'") +set(MAKEDIST_CMAKEFLAGS -DBUILD_SHARED_LIBS:BOOL=ON CACHE STRING "flags which are given to 'cmake' by 'make distcheck'") +set(MAKEDIST_BUILDTARGETS "" CACHE STRING "build-target(s) tried by 'make distcheck'") +set(MAKEDIST_CHECKTARGETS test CACHE STRING "check-target(s) tried by 'make distcheck'") +set(MAKEDIST_INSTALLTARGETS install CACHE STRING "install-target(s) tried by 'make distcheck'") + +mark_as_advanced( + MAKEDIST_TMPDIR MAKEDIST_PKGBASE MAKEDIST_TARBALL + MAKEDIST_BUILDTARGETS MAKEDIST_CHECKTARGETS MAKEDIST_INSTALLTARGETS) + + +set(MAKEDIST_TARDIR "${MAKEDIST_TMPDIR}/tar/${MAKEDIST_PKGBASE}") +set(MAKEDIST_CHECKDIR "${MAKEDIST_TMPDIR}/check") + +macro(enable_makedist) + add_custom_target(.distdir) + set_source_files_properties(.distdir PROPERTIES + SYMBOLIC TRUE + GENERATED TRUE) + + foreach(__makedist_i ${EXTRA_DIST}) + set_source_files_properties("${__makedist_i}" PROPERTIES EXTRADIST TRUE) + endforeach(__makedist_i) + + foreach(__makedist_source CMakeLists.txt ${EXTRA_DIST} ${ARGN}) + get_filename_component(__makedist_full_cur_path "${__makedist_source}" ABSOLUTE) + get_source_file_property(__makedist_generated "${__makedist_source}" GENERATED) + get_source_file_property(__makedist_extradist "${__makedist_source}" EXTRADIST) + + if(NOT __makedist_generated) + file(RELATIVE_PATH __makedist_cur_path "${CMAKE_SOURCE_DIR}" "${__makedist_full_cur_path}") + elseif(__makedist_extradist) + file(RELATIVE_PATH __makedist_cur_path "${CMAKE_BINARY_DIR}" "${__makedist_full_cur_path}") + else(__makedist_extradist) + set(__makedist_cur_path) + endif(NOT __makedist_generated) + + if(__makedist_cur_path) + get_filename_component(__makedist_tmp "${MAKEDIST_TARDIR}/${__makedist_cur_path}" PATH) + + add_custom_command(TARGET .distdir + COMMAND mkdir -p "${__makedist_tmp}" + COMMAND cp -a "${__makedist_full_cur_path}" "${__makedist_tmp}/" + DEPENDS ${__makedist_source}) + else(__makedist_cur_path) + message(STATUS "skipping ${__makedist_source}") + endif(__makedist_cur_path) + endforeach(__makedist_source) +endmacro(enable_makedist) + + +macro(add_makedist) + set_source_files_properties(dist distcheck .distcheck PROPERTIES + SYMBOLIC TRUE + GENERATED TRUE) + + add_custom_target(dist + # cleanup tmpdir + COMMAND chmod -R u+Xw "${MAKEDIST_TMPDIR}" 2>/dev/null || : + COMMAND rm -rf "${MAKEDIST_TMPDIR}" + + # execute 'make .distdir' + COMMAND ${CMAKE_MAKE_PROGRAM} .distdir + # set proper permissions + COMMAND chmod -R go-w,a+rX,u+w "${MAKEDIST_TARDIR}" + + # create the tarball + COMMAND cd "${MAKEDIST_TARDIR}/.." && tar cf "${MAKEDIST_TARBALL}\${MAKEDIST_TARBALL_TMP}" ${MAKEDIST_TARFLAGS} ${MAKEDIST_PKGBASE} + + # cleanup tmpdir + COMMAND rm -rf "${MAKEDIST_TMPDIR}" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + + + add_custom_target(distcheck + COMMAND rm -f "${MAKEDIST_TARBALL}".tmp + COMMAND ${CMAKE_MAKE_PROGRAM} dist MAKEDIST_TARBALL_TMP=.tmp + COMMAND ${CMAKE_MAKE_PROGRAM} .distcheck MAKEDIST_TARBALL_TMP=.tmp + COMMAND rm -f "${MAKEDIST_TARBALL}" + COMMAND mv -f "${MAKEDIST_TARBALL}.tmp" "${MAKEDIST_TARBALL}") + + + add_custom_target(.distcheck + # cleanup tmpdir and create directory layout + COMMAND chmod -R u+Xw "${MAKEDIST_CHECKDIR}" 2>/dev/null || : + COMMAND rm -rf "${MAKEDIST_CHECKDIR}" + COMMAND mkdir -p "${MAKEDIST_CHECKDIR}/source" "${MAKEDIST_CHECKDIR}/build" + + # extract tarball + COMMAND cd "${MAKEDIST_CHECKDIR}/source" && tar xf "${MAKEDIST_TARBALL}\${MAKEDIST_TARBALL_TMP}" ${MAKEDIST_TARFLAGS} + # write-protect sources to detect modifies-sourcetree bugs + COMMAND chmod -R a-w "${MAKEDIST_CHECKDIR}/source" + + # invoke 'cmake' + COMMAND ${CMAKE_COMMAND} -E echo "executing initial cmake" + COMMAND cd "${MAKEDIST_CHECKDIR}/build" && + ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH="${MAKEDIST_CHECKDIR}/install" + ${MAKEDIST_CMAKEFLAGS} "${MAKEDIST_CHECKDIR}/source/${MAKEDIST_PKGBASE}" + COMMAND ${CMAKE_COMMAND} -E echo "initial cmake succeeded" + + # execute 'make build' and 'make check' + COMMAND ${CMAKE_COMMAND} -E echo "building project" + COMMAND cd "${MAKEDIST_CHECKDIR}/build" && ${CMAKE_MAKE_PROGRAM} ${MAKEDIST_BUILDTARGETS} + COMMAND cd "${MAKEDIST_CHECKDIR}/build" && ${CMAKE_MAKE_PROGRAM} ${MAKEDIST_CHECKTARGETS} + + # execute 'make install' without DESTDIR + COMMAND cd "${MAKEDIST_CHECKDIR}/build" && ${CMAKE_MAKE_PROGRAM} ${MAKEDIST_INSTALLTARGETS} DESTDIR= + # write protect installation path to detect writing outside of DESTDIR + COMMAND chmod -R a-w "${MAKEDIST_CHECKDIR}/install" + # execute 'make install' with DESTDIR and move the files to a better location + COMMAND cd "${MAKEDIST_CHECKDIR}/build" && ${CMAKE_MAKE_PROGRAM} ${MAKEDIST_INSTALLTARGETS} DESTDIR="${MAKEDIST_CHECKDIR}/install-tmp" + COMMAND mv "${MAKEDIST_CHECKDIR}/install-tmp/${MAKEDIST_CHECKDIR}/install" "${MAKEDIST_CHECKDIR}/install-destdir" + + # generate list of files which were installed by the both 'make + # install' commands above and compare them + COMMAND cd "${MAKEDIST_CHECKDIR}/install" && find -type f | sort > ../files.install + COMMAND cd "${MAKEDIST_CHECKDIR}/install-destdir" && find -type f | sort > ../files.destdir + COMMAND cd "${MAKEDIST_CHECKDIR}" && diff files.install files.destdir + + # cleanup tmpdir + COMMAND chmod -R u+Xw "${MAKEDIST_TMPDIR}" 2>/dev/null || : + COMMAND rm -rf "${MAKEDIST_TMPDIR}" + ) +endmacro(add_makedist) diff --git a/cmake_config.h.in b/cmake_config.h.in index 1cb2d3201..ecf89f4ee 100644 --- a/cmake_config.h.in +++ b/cmake_config.h.in @@ -89,10 +89,10 @@ #cmakedefine LARGE_FILE_TESTS 1 #cmakedefine HAVE_CURLOPT_KEYPASSWD #cmakedefine HAVE_DECL_ISFINITE 1 -//#cmakedefine HAVE_DECL_ISNAN 1 #cmakedefine HAVE_DECL_ISNAN #cmakedefine HAVE_DECL_SIGNBIT 1 #cmakedefine HAVE_DOPRNT +#cmakedefine HAVE_ALLOCA #cmakedefine HAVE_LIBPNETCDF @@ -109,7 +109,7 @@ #cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ #cmakedefine YY_NO_UNISTD_H @YY_NO_UNISTD_H@ -/* Define to 1 if you have the header file. */ +/* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@ /* Define to 1 if you have the header file. */ @@ -137,7 +137,7 @@ #cmakedefine HAVE_LOCAL_H @HAVE_LOCAL_H@ /* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H @HAVE_STDINCC=mpicc CPPFLAGS="-I/machine/local_par7/include -I/machine/local_mpich2/include -I/machine/local_par/include -I/machine/local_szlib/include" LDFLAGS="-L/machine/local_par7/lib -L/machine/local_mpich2/lib -L/machine/local_par/lib -L/machine/local_szlib/lib" LDLIBS='-lmpich -lmpl -lsz' ./configure --enable-pnetcdf --enable-parallel-tests --disable-sharedT_H@ +#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDIO_H @HAVE_STDIO_H@ @@ -181,6 +181,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H @HAVE_FCNTL_H@ +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MALLOC_H @HAVE_MALLOC_H@ + #if !defined(__APPLE__) /* The size of `double` as computed by sizeof. */ #cmakedefine SIZEOF_DOUBLE @SIZEOF_DOUBLE@ diff --git a/include/onstack.h b/include/onstack.h index 659944b00..28414eb1b 100644 --- a/include/onstack.h +++ b/include/onstack.h @@ -19,12 +19,15 @@ * The macro ALLOC_ONSTACK wraps a call to alloca() on most systems. */ -#if defined(_WIN32) || defined(_WIN64) +#ifdef _MSC_VER +#ifdef HAVE_MALLOC_H #undef HAVE_ALLOCA #define HAVE_ALLOCA 1 +#include +#endif #endif -#if HAVE_ALLOCA +#ifdef HAVE_ALLOCA /* * Implementation based on alloca() */