Hi All,Sorry for the month of delay, but I've addressed Mike Jackson's concerns below and I think I'm close to having the HDF5 find module ready for submission.
I've tested it on a number of Unix and Linux systems, including desktops and clusters, but it would be helpful if someone with access to Windows or Mac systems could give it a try there and let me know what needs to be fixed.
There are two modules attached to this message: The FindHDF5.cmake module and an AdjustLibraryVariables.cmake module, which is essentially a copy of what the FindQt4 module does. It seems useful enough to incorporate into the CMake Modules, and I can maintain it if you need a maintainer.
How I addressed Mike Jackson's concerns is addressed in the module documentation at the top of the file, please let me know if anyone has any other concerns.
I'd love to hear any feedback that anyone may have. Once I have some feedback from Windows and Mac users, I'd like to get this put into the CMake distribution if possible.
Thanks, --Will James C. Sutherland wrote:
Out of curiosity, was a module ever submitted for this? I would love to have a copy ;-)Specifically, I am interested in detecting statically linked libraries and the c++ library and header(s). I also would like to see a list of libraries like the "z" library for compression.Utility executables like h5diff are also really useful for regression testing, so returning handles to those would be really great as well.Thanks for your work on this! James On Jul 10, 2009, at 11:01 AM, Michael Jackson wrote:reponses in line.. On Jul 10, 2009, at 12:33 PM, Will Dicharry wrote:Michael Jackson wrote:On Jul 10, 2009, at 11:13 AM, Brad King wrote:Will Dicharry wrote:Mike Jackson wrote:Can you post your module or attach it to a bug/feature request? I alsohave a FindHDF5 module and I would like to compare the two.Sorry about that, I meant to attach the module to the first email. Itis attached to this one.After you two have combined your versions and reached consensus, please post again and Cc me. Then I'll send instructions to get CVS commit access. I see no reason not to have co-maintainers for a module. Thanks, -BradI'll let Will be the maintainer. My module ends up being a bit more specific to my own version of HDF5, ie, I am just looking for the libraries (c, c++, and High Level) but not really looking for the HDF5 compiler scripts.Couple of observations about the module: Does it find the HDF5 C++ library?No, but I'll add that in by invoking the HDF5 C++ wrapper compiler and searching the output.Great.Can it figure out if the HDF5 library is a static or dynamic library? (I configure a header file that has that information inside it which can then be tested for).No, I'll look into how to determine that. Suggestions welcome.Well, I don't think there is an easy way to do it besides looking at the fully name of the library file, but even then that can give you bad results. In my CMake build system for HDF5 I add a few more #define elements into the H5Config.h file that has the necessary parts to be able to determine how HDF5 was compiled- static or dynamic.Is it properly finding dependent libraries when needed, like szip or zip ( I don't as I do NOT compile HDF5 with that support)?Yes, I need it to work across a number of platforms, many of which do compile in szip support. I search for all libraries linked by the wrapper compiler and add them to the HDF5_LIBRARIES list.You may also want to include variables such as HDF5_SZIP_LIBRARY and HDF5_ZIP_LIBRARY. You also might want to include some CMake code to generate the following variables:HDF5_LIBRARY_DEBUG HDF5_LIBRARY_RELEASE HDF5_LIBRARYFor each library found. I think the normal hdf5 distribution will append a 'd' to the name of the hdf5 library when built in Debug mode. My own build system uses '_d' on windows and _debug on gcc. The necessary cmake code will "do the right thing" if one of the libraries are not found.############################################ # # Check the existence of the libraries. # ############################################# This macro was taken directly from the FindQt4.cmake file that is included # with the CMake distribution. This is NOT my work. All work was done by the # original authors of the FindQt4.cmake file. Only minor modifications were # made to remove references to Qt and make this file more generally applicable######################################################################### MACRO (_MXA_ADJUST_LIB_VARS basename) IF (${basename}_INCLUDE_DIR)# if only the release version was found, set the debug variable also to the release versionIF (${basename}_LIBRARY_RELEASE AND NOT ${basename}_LIBRARY_DEBUG) SET(${basename}_LIBRARY_DEBUG ${${basename}_LIBRARY_RELEASE}) SET(${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE}) SET(${basename}_LIBRARIES ${${basename}_LIBRARY_RELEASE}) ENDIF (${basename}_LIBRARY_RELEASE AND NOT ${basename}_LIBRARY_DEBUG)# if only the debug version was found, set the release variable also to the debug versionIF (${basename}_LIBRARY_DEBUG AND NOT ${basename}_LIBRARY_RELEASE) SET(${basename}_LIBRARY_RELEASE ${${basename}_LIBRARY_DEBUG}) SET(${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG}) SET(${basename}_LIBRARIES ${${basename}_LIBRARY_DEBUG}) ENDIF (${basename}_LIBRARY_DEBUG AND NOT ${basename}_LIBRARY_RELEASE) IF (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE) # if the generator supports configuration types then set# optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a valueIF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)SET(${basename}_LIBRARY optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG})ELSE(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)# if there are no configuration types and CMAKE_BUILD_TYPE has no value# then just use the release libraries SET(${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) ENDIF(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)SET(${basename}_LIBRARIES optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG})ENDIF (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE)SET(${basename}_LIBRARY ${${basename}_LIBRARY} CACHE FILEPATH "The ${basename} library")IF (${basename}_LIBRARY) SET(${basename}_FOUND 1) ENDIF (${basename}_LIBRARY) ENDIF (${basename}_INCLUDE_DIR ) # Make variables changeble to the advanced userMARK_AS_ADVANCED(${basename}_LIBRARY ${basename}_LIBRARY_RELEASE ${basename}_LIBRARY_DEBUG ${basename}_INCLUDE_DIR )ENDMACRO (_MXA_ADJUST_LIB_VARS)Make use of some sort of environment variable as a possible solution to finding the root of where HDF5 is installed, I personally use the environment variable "HDF5_INSTALL" for use in my script.No. I'd personally prefer to rely on setting something similar in the cache rather than using an environment variable, but I'm open to changing my opinion.Yes. Simply because if you gather 20 people who compile HDF5 you will probably get some, if not all, who decide they want HDF5 installed somewhere else: /opt, /sw, /usr, /usr/local, /Users/$HOME/.. , /Users/Shared/Toolkits, /Users/Shared/OpenSource, C:/hdf5, C:/Developer/GCC, C:/Program Files/hdf5 (replace the drive letter with any other drive letter on windows).Having to run cmake and cmake not being able to find HDF5 EVERY TIME is a PITA. I used to have to deal with this. A simple environment variable solves this problem. If you want a concrete case, just look at Boost. Used by lots of people, installed everywhere imaginable. Even _with_ setting Boost_ROOT CMake _still_ sometimes has problems finding boost (Of course the crazy library naming doesn't help). Qt - Same thing: Either provide QtDir or the qmake executable. Ignoring the use of an environment variable is ignoring a dead easy way to help your users use CMake effectively. So.. Yes.I imagine what I _should_ be doing is creating a HDF5Config.cmake file and UseHDF5.cmake file for my own HDF5 distribution (which is based on HDF5 version 1.6.9 and uses CMake as its build system).Just my comments. If you want to see what I've come up with let me know. My git repo is public:http://www.bluequartz.net/cgi-bin/gitweb/gitweb.cgi?p=MXADataModel.git;a=blob_plain;f=Resources/CMake/MXAFindHDF5.cmake;hb=HEADI'll take a look so I can try to make the module as useful as possible. Thanks for the suggestions!--Will_________________________________________________________ Mike Jackson mike.jack...@bluequartz.net BlueQuartz Software www.bluequartz.net Principal Software Engineer Dayton, OhioI know my system works great on OS X, Windows, and Linux when built as a serial library. What I _don't_ know is how well it works every where else (BSD, Clusters, Solaris, AIX, Crays) which is why I never tried to submit it as a module.Mike _______________________________________________ Powered by www.kitware.comVisit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.htmlPlease keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQFollow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake_______________________________________________ Powered by www.kitware.comVisit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.htmlPlease keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQFollow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake
-- Will Dicharry Software Developer Stellar Science Ltd Co
# - Adjust the library variables for a given library. # # This macro takes a library base name as an argument, and will choose good # values for basename_LIBRARY, basename_LIBRARY_DEBUG, and # basename__LIBRARY_RELEASE depending on what has been set. If only # basename_RELEASE was found, basename, basename_DEBUG, and basename_RELEASE # will be set to the release value. The same is true if only basename_DEBUG was # found, but all values will take the value of basename_DEBUG. If no build type # has been set or the generator in use does not support configuration types, # then only the release value will be used. # # This macro was taken from the FindQt4.cmake module. # Utility macro to check if one variable exists while another doesn't, and set # one that doesn't exist to the one that exists. macro( set_library_name basename GOOD BAD ) if( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} ) set( ${basename}_LIBRARY_${BAD} ${${basename}_LIBRARY_${GOOD}} ) set( ${basename}_LIBRARY ${${basename}_LIBRARY_${GOOD}} ) endif( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} ) endmacro() macro( adjust_library_variables basename ) # if only the release version was found, set the debug to be the release # version. set_library_name( ${basename} RELEASE DEBUG ) # if only the debug version was found, set the release value to be the # debug value. set_library_name( ${basename} DEBUG RELEASE ) if (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE ) # if the generator supports configuration types or CMAKE_BUILD_TYPE # is set, then set optimized and debug options. if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) set( ${basename}_LIBRARY optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG} ) else( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) # If there are no configuration types or build type, just use # the release version set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) endif( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) endif( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE ) set( ${basename}_LIBRARY ${${basename}_LIBRARY} CACHE FILEPATH "The ${basename} library" ) if( ${basename}_LIBRARY ) set( ${basename}_FOUND TRUE ) endif( ${basename}_LIBRARY ) mark_as_advanced( ${basename}_LIBRARY ${basename}_LIBRARY_RELEASE ${basename}_LIBRARY_DEBUG ) endmacro( adjust_library_variables )
# - Find the HDF5 library. # # This module invokes the HDF5 wrapper compiler that should be installed # alongside HDF5. Depending upon the HDF5 Configuration, the wrapper compiler # is called either h5cc or h5pcc. If this succeeds, the module will then call # the compiler with the -show argument to see what flags are used when compiling # an HDF5 client application. # # The module will optionally accept the COMPONENTS argument. If no COMPONENTS # are specified, then the find module will default to finding only the HDF5 C # library. If one or more COMPONENTS are specified, the module will attempt to # find the language bindings for the specified components. Currently, the only # valid components are C and CXX. The module does not yet support finding the # Fortran bindings. If the COMPONENTS argument is not given, the module will # attempt to find only the C bindings. # # On UNIX systems, this module will read the variable HDF5_USE_STATIC_LIBRARIES # to determine whether or not to prefer a static link to a dynamic link for HDF5 # and all of it's dependencies. To use this feature, make sure that the # HDF5_USE_STATIC_LIBRARIES variable is set before the call to find_package. # # To provide the module with a hint about where to find your HDF5 installation, # you can set the environment variable HDF5_ROOT. The Find module will then # look in this path when searching for HDF5 executables, paths, and libraries. # # This module will define the following variables: # HDF5_INCLUDE_DIR - location of the hdf5 includes # HDF5_DEFINITIONS - Required compiler definitions for HDF5 # HDF5_C_LIBRARIES - Required libraries for the HDF5 C bindings. # HDF5_CXX_LIBRARIES - Required libraries for the HDF5 C++ bindings # HDF5_LIBRARIES - Required libraries for all requested bindings # HDF5_FOUND - true if HDF5 was found on the system # HDF5_LIBRARY_DIRS - the full set of library directories # HDF5_C_COMPILER_EXECUTABLE - the path to the HDF5 C wrapper compiler # HDF5_CXX_COMPILER_EXECUTABLE - the path to the HDF5 C++ wrapper compiler include(AdjustLibraryVariables) include(FindPackageHandleStandardArgs) # List of the valid HDF5 components set( HDF5_VALID_COMPONENTS C CXX ) # try to find the HDF5 wrapper compilers find_program( HDF5_C_COMPILER_EXECUTABLE NAMES h5cc h5pcc PATHS ENV HDF5_ROOT PATH PATH_SUFFIXES bin Bin DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) find_program( HDF5_CXX_COMPILER_EXECUTABLE NAMES h5c++ h5pc++ PATHS ENV HDF5_ROOT PATH PATH_SUFFIXES bin Bin DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) # Invoke the HDF5 wrapper compiler. The compiler return value is stored to the # return_value argument, the text output is stored to the output variable. macro( HDF5_invoke_compiler language output return_value ) if( HDF5_${language}_COMPILER_EXECUTABLE ) exec_program( ${HDF5_${language}_COMPILER_EXECUTABLE} ARGS -show OUTPUT_VARIABLE ${output} RETURN_VALUE ${return_value} ) if( ${${return_value}} EQUAL 0 ) # do nothing else() message( STATUS "Unable to determine HDF5 ${language} flags from HDF5 wrapper." ) endif() endif() endmacro() # Parse a compile line for definitions, includes, library paths, and libraries. macro( HDF5_parse_compile_line compile_line include_paths definitions library_paths libraries ) # Match the include paths string( REGEX MATCHALL "-I([^\" ]+)" include_path_flags "${compile_line}" ) foreach( IPATH ${include_path_flags} ) string( REGEX REPLACE "^-I" "" IPATH ${IPATH} ) string( REGEX REPLACE "//" "/" IPATH ${IPATH} ) list( APPEND ${include_paths} ${IPATH} ) endforeach() # Match the definitions string( REGEX MATCHALL "-D[^ ]*" definition_flags "${compile_line}" ) foreach( DEF ${definition_flags} ) list( APPEND ${definitions} ${DEF} ) endforeach() # Match the library paths string( REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags "${compile_line}" ) foreach( LPATH ${library_path_flags} ) string( REGEX REPLACE "^-L" "" LPATH ${LPATH} ) string( REGEX REPLACE "//" "/" LPATH ${LPATH} ) list( APPEND ${library_paths} ${LPATH} ) endforeach() # now search for the library names specified in the compile line (match -l...) # match only -l's preceded by a space or comma # this is to exclude directory names like xxx-linux/ string( REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags "${compile_line}" ) # strip the -l from all of the library flags and add to the search list foreach( LIB ${library_name_flags} ) string( REGEX REPLACE "^[, ]-l" "" LIB ${LIB} ) list( APPEND ${libraries} ${LIB} ) endforeach() endmacro() if( HDF5_INCLUDE_DIR AND HDF5_LIBRARIES ) # Do nothing: we already have HDF5_INCLUDE_PATH and HDF5_LIBRARIES in the # cache, it would be a shame to override them else() HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE ) HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE ) if( NOT HDF5_FIND_COMPONENTS ) set( HDF5_LANGUAGE_BINDINGS "C" ) else() # add the extra specified components, ensuring that they are valid. foreach( component ${HDF5_FIND_COMPONENTS} ) list( FIND HDF5_VALID_COMPONENTS ${component} component_location ) if( ${component_location} EQUAL -1 ) message( FATAL_ERROR "\"${component}\" is not a valid HDF5 component." ) else() list( APPEND HDF5_LANGUAGE_BINDINGS ${component} ) endif() endforeach() endif() # seed the initial lists of libraries to find with items we know we need set( HDF5_C_LIBRARY_NAMES_INIT hdf5 hdf5_hl ) set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ) foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} ) if( HDF5_${LANGUAGE}_COMPILE_LINE ) HDF5_parse_compile_line( ${HDF5_${LANGUAGE}_COMPILE_LINE} HDF5_${LANGUAGE}_INCLUDE_FLAGS HDF5_${LANGUAGE}_DEFINITIONS HDF5_${LANGUAGE}_LIBRARY_DIRS HDF5_${LANGUAGE}_LIBRARY_NAMES ) # take a guess that the includes may be in the 'include' sibling directory # of a library directory. foreach( dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) list( APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include ) endforeach() endif() # set the definitions for the language bindings. list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} ) # find the HDF5 include directories find_path( HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h PATHS /usr/local/include /usr/include $ENV{HOME}/.local/include ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} ENV HDF5_ROOT PATH_SUFFIXES include ) mark_as_advanced( HDF5_${LANGUAGE}_INCLUDE_DIR ) list( APPEND HDF5_INCLUDE_DIR ${HDF5_${LANGUAGE}_INCLUDE_DIR} ) set( HDF5_${LANGUAGE}_LIBRARY_NAMES ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) # find the HDF5 libraries foreach( LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) if( UNIX AND HDF5_USE_STATIC_LIBRARIES ) # According to bug 1643 on the CMake bug tracker, this is the # preferred method for searching for a static library. # See http://www.cmake.org/Bug/view.php?id=1643 set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ) set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ) else() set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ) set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ) endif() find_library( HDF5_${LIB}_LIBRARY_DEBUG ${THIS_LIBRARY_SEARCH_DEBUG} PATHS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ENV HDF5_ROOT PATH_SUFFIXES lib Lib ) find_library( HDF5_${LIB}_LIBRARY_RELEASE ${THIS_LIBRARY_SEARCH_RELEASE} PATHS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ENV HDF5_ROOT PATH_SUFFIXES lib Lib ) adjust_library_variables( HDF5_${LIB} ) # even though we adjusted the individual library names in # adjust_library_variables, we still need to distinguish between # debug and release variants because HDF5_LIBRARIES will need to # specify different items for debug and optimized builds. We can't # just use the HDF5_${LIB}_LIBRARY variable (which was set up by the # adjustment macro above) because it may specify debug and optimized # variants for a particular library, but a list of libraries is # allowed to specify debug and optimized only once. list( APPEND HDF5_${LANGUAGE}_LIBRARIES_DEBUG ${HDF5_${LIB}_LIBRARY_DEBUG} ) list( APPEND HDF5_${LANGUAGE}_LIBRARIES_RELEASE ${HDF5_${LIB}_LIBRARY_RELEASE} ) endforeach() list( APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) # Append the libraries for this language binding to the list of all # required libraries. list( APPEND HDF5_LIBRARIES_DEBUG ${HDF5_${LANGUAGE}_LIBRARIES_DEBUG} ) list( APPEND HDF5_LIBRARIES_RELEASE ${HDF5_${LANGUAGE}_LIBRARIES_RELEASE} ) endforeach() # We may have picked up some duplicates in various lists during the above # process for the language bindings (both the C and C++ bindings depend on # libz for example). Remove the duplicates. list( REMOVE_DUPLICATES HDF5_INCLUDE_DIR ) list( REMOVE_DUPLICATES HDF5_LIBRARIES_DEBUG ) list( REMOVE_DUPLICATES HDF5_LIBRARIES_RELEASE ) list( REMOVE_DUPLICATES HDF5_LIBRARY_DIRS ) # Finally, we construct the complete list of HDF5 libraries with debug and # optimized variants when the generator supports them. if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) set( HDF5_LIBRARIES debug ${HDF5_LIBRARIES_DEBUG} optimized ${HDF5_LIBRARIES_RELEASE} ) else() set( HDF5_LIBRARIES ${HDF5_LIBRARIES_RELEASE} ) endif() endif() find_package_handle_standard_args( HDF5 DEFAULT_MSG HDF5_LIBRARIES HDF5_INCLUDE_DIR ) mark_as_advanced( HDF5_INCLUDE_DIR HDF5_LIBRARIES HDF5_DEFINTIONS HDF5_LIBRARY_DIRS HDF5_C_COMPILER_EXECUTABLE HDF5_CXX_COMPILER_EXECUTABLE )
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake