Reputation: 37
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.
Upvotes: 0
Views: 2440
Reputation: 101
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.
Upvotes: 1