0

So I have a small Fortran library that provides some wrappers for HDF5 Fortran calls. I also have a small test that calls the interfaces defined in the library. I know that the issue is with the way I'm linking HDF5. I've checked my build of HDF5 (specifically 1.8.15-patch1), ensured that it was all installed correctly to my machine, and that there were no alternate builds on my machine. I am building both projects with the compilers set as gcc-5, g++-5, and gfortran-5.

I am using CMake 3.2.2 to generate makefiles.

The layout of the project is something like this:

CMakeLists.txt
test
 |_____ CMakeLists.txt
 |_____ dump_test.f90
src
 |_____ data
         |_____ CMakeLists.txt
         |_____ dump_data.f90
 |_____ <other libraries>

In the main CMakeLists.txt, I have

project(testlibs)

ENABLE_LANGUAGE(Fortran)

SET(HDF5_USE_STATIC_LIBRARIES ON)
find_package(HDF5 COMPONENTS C CXX Fortran REQUIRED)

SET(CMAKE_Fortran_FLAGS_DEBUG "-g -O0 -DDEBUG")

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)

add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/data)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tests)

In the data library CMakeLists.txt, I have

include_directories(${HDF5_INCLUDE_DIRS})
add_library(dumpData STATIC ${CMAKE_CURRENT_LIST_DIR}/dump_data.f90)
target_link_libraries(dumpData hdf5 hdf5_fortran )
install(TARGETS dumpData DESTINATION ${CMAKE_INSTALL_RPATH})

In the test CMakeLists.txt, I have

include_directories(${HDF5_INCLUDE_DIRS})
include_directories("${PROJECT_BINARY_DIR}/src/data")
add_executable(dumptest EXCLUDE_FROM_ALL dump_test.f90)
target_link_libraries(dumptest dumpData)

I've seen suggestions that say to link the library against dl also, but that doesn't seem to affect anything.

I get no errors when I build the library but when I build the example, I get a bunch of undefined references

//usr/local/lib/libhdf5_fortran.a(H5_ff.f90.o): In function `__h5lib_MOD_h5dont_atexit_f':
H5_ff.f90:(.text+0xed): undefined reference to `h5dont_atexit_c_'
//usr/local/lib/libhdf5_fortran.a(H5_ff.f90.o): In function `__h5lib_MOD_h5garbage_collect_f':
H5_ff.f90:(.text+0x109): undefined reference to `h5garbage_collect_c_'
//usr/local/lib/libhdf5_fortran.a(H5_ff.f90.o): In function `__h5lib_MOD_h5check_version_f':
H5_ff.f90:(.text+0x143): undefined reference to `h5check_version_c_'
//usr/local/lib/libhdf5_fortran.a(H5_ff.f90.o): In function `__h5lib_MOD_h5get_libversion_f':
H5_ff.f90:(.text+0x17d): undefined reference to `h5get_libversion_c_'
//usr/local/lib/libhdf5_fortran.a(H5_ff.f90.o): In function `__h5lib_MOD_h5close_f':
H5_ff.f90:(.text+0x1cc): undefined reference to `h5close_types_c_'
//usr/local/lib/libhdf5_fortran.a(H5_ff.f90.o): In function `__h5lib_MOD_h5open_f':
H5_ff.f90:(.text+0x20a): undefined reference to `h5init_types_c_'
H5_ff.f90:(.text+0x2ba): undefined reference to `h5init_flags_c_'
H5_ff.f90:(.text+0x2d0): undefined reference to `h5init1_flags_c_'

Am I missing something in my CMake files? I'm getting that its a issue of the HDF5 Fortran functions not being able to find the underlying C functions.

4
  • I'm not a CMake user but it looks like you've go the wrong order for the hdf and hdf5_fortran libraries. I'm pretty certain that hdf5_fortran should be first Commented Feb 10, 2016 at 0:41
  • I had that initially, but in trying to get it to work, I switched them around. The issue still persists, no matter the order. Thank you for the suggestion though. Commented Feb 10, 2016 at 14:09
  • You want to see what the linker is trying to do. Have a look at how the linking is being done.Try compiling directly with /usr/bin/h5fc -noshlib ... and see what the differences are. Commented Feb 11, 2016 at 0:31
  • Thank you! That helped me find the issue. I wasn't linking against the hdf5_f90cstub library, which is why it was getting undefined references to the C functions from the Fortran files. This changed the link line to: target_link_libraries(dumpData hdf5_fortran hdf5_f90cstub hdf5 dl). Thanks again! Commented Feb 12, 2016 at 15:23

1 Answer 1

1

I'm doing something similar, and had the same error messages (see the small excerpt following). I have a CMakeLists.txt in the main folder that does the add_subdirectory( src ) for building the static and shared libraries I use for several executable programs and add_subdirectory( apps ) for building and linking the executable programs. Here's a sample of the error messages:

Faults/src/HDMod.f90:90: undefined reference to `__h5global_MOD_h5f_acc_trunc_f'
Faults/src/HDMod.f90:90: undefined reference to `__h5f_MOD_h5fcreate_f'
Faults/src/HDMod.f90:90: undefined reference to `__h5global_MOD_h5f_acc_rdwr_f'
Faults/src/HDMod.f90:90: undefined reference to `__h5f_MOD_h5fopen_f'
../lib/libFaultsStatic.a(HDMod.f90.o): In function `__hdmod_MOD_hd_open':

The main CMakeLists.txt has these lines (excerpts only, as there's lots more lines not shown):

cmake_minimum_required (VERSION 3.12 FATAL_ERROR)
project( Faults_Project Fortran C )
set( HDF5_USE_STATIC_LIBRARIES ON )
find_package( MPI REQUIRED )
find_package( HDF5 COMPONENTS C Fortran REQUIRED )
include_directories( SYSTEM ${HDF5_INCLUDE_DIRS} )
set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}" )
add_subdirectory( src )
add_subdirectory( apps )

The CmakeLists.txt for the src folder makes static and shared libraries from the sources:

add_library( FaultsShared SHARED ${Faults_Src_Code} )
set_target_properties( FaultsShared PROPERTIES LINKER_LANGUAGE Fortran )
set_target_properties( FaultsShared PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}" )
set_target_properties( FaultsShared PROPERTIES Fortran_FORMAT "FREE" )
install( TARGETS FaultsShared RUNTIME DESTINATION ../bin/ LIBRARY DESTINATION ../lib/ ARCHIVE DESTINATION ../lib/ )

and similarly for the STATIC library. Then in the CMakeLists.txt for the apps folder:

add_executable( artsRun artsRun.f90 )
target_link_libraries( artsRun FaultsStatic ${HDF5_Fortran_LIBRARIES} )

And so on for the other executable programs. The trick was to include the ${HDF5_Fortran_LIBRARIES} in the target_link_libraries line.

I'm just posting this here because it looks like many people have viewed this question and there were no answers posted after 3 years. Hope this helps anyone else looking for the same thing.

Sign up to request clarification or add additional context in comments.

1 Comment

Great solution. I've used this in my Fortran + PETSc + HDF5 CMake project and it works well for gfortran 10.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.