Skip to content

Commit

Permalink
CMake build infrastucture
Browse files Browse the repository at this point in the history
support for building the CVMix library and the CVMix driver using CMake
  • Loading branch information
bolding authored Jun 22, 2020
1 parent bbbf5c8 commit 9423197
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 6 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ python:
script:
- cd bld; ./cvmix_setup gfortran $(dirname $(dirname $(which nc-config)))
- cd ../CVMix_tools; ./run_test_suite.sh --already-ran-setup
- cd ../reg_tests/Bryan-Lewis/; ./Bryan-Lewis-test.sh --cmake

branches:
only:
Expand Down
103 changes: 103 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
cmake_minimum_required( VERSION 3.9 )

project( cvmix VERSION 4.0.1 LANGUAGES Fortran )

# Use solution folders in IDEs
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Use standard GNU installation directories
if ( NOT WIN32 )
include( GNUInstallDirs )
endif()

# Configuration options
option( CVMIX_USE_NetCDF "Enable NetCDF format" OFF )
if(CVMIX_USE_NetCDF)
add_compile_definitions(_NETCDF)
include_directories($ENV{NetCDF_INCLUDE})
endif(CVMIX_USE_NetCDF)
option( CVMIX_BUILD_STATIC_LIBS "Build static library" ON )
option( CVMIX_BUILD_SHARED_LIBS "Build shared library" ON )
option( CVMIX_BUILD_DRIVER "Build CVMix example/test driver" OFF )

# Check if shared or static builds are turned off
if( NOT CVMIX_BUILD_STATIC_LIBS )
message( STATUS "Turning STATIC builds OFF" )
endif()
if( NOT CVMIX_BUILD_SHARED_LIBS )
message( STATUS "Turning SHARED builds OFF" )
endif()

# Set default build type to Release if not specified
if( NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE )
message( STATUS "Setting default build type to 'Release'. Set CMAKE_BUILD_TYPE variable to change build types." )
set_property( CACHE CMAKE_BUILD_TYPE PROPERTY VALUE "Release" )
endif()

set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules )
set( CMAKE_POSITION_INDEPENDENT_CODE ON )

add_subdirectory( src )

# Note - KB:
# Building static and shared libs require an ugly construct to build on both
# Windows and Linux. Windows will not create the libraries unless a Fortran
# file is explicitly given - and Linux complains (I think due to a race
# condition) if it is. Therefor the construct below - a proper solution is
# most welcome.

# Add static lib target
if( CVMIX_BUILD_STATIC_LIBS )
if ( WIN32 )
add_library( cvmix_static STATIC ${CMAKE_SOURCE_DIR}/src/dummy.F90 $<TARGET_OBJECTS:cvmix_objects> )
else()
add_library( cvmix_static STATIC $<TARGET_OBJECTS:cvmix_objects> )
endif()
list( APPEND LIB_TARGETS cvmix_static )
endif()

# Add shared lib target
if( CVMIX_BUILD_SHARED_LIBS )
if ( WIN32 )
add_library( cvmix_shared SHARED ${CMAKE_SOURCE_DIR}/src/dummy.F90 $<TARGET_OBJECTS:cvmix_objects> )
else()
add_library( cvmix_shared SHARED $<TARGET_OBJECTS:cvmix_objects> )
endif()
list( APPEND LIB_TARGETS cvmix_shared )
endif()

# Set common lib target properties
foreach( _lib IN LISTS LIB_TARGETS )
target_compile_definitions( ${_lib} PUBLIC "${PUBLIC_FLAGS}" )
target_include_directories( ${_lib}
PUBLIC
$<INSTALL_INTERFACE:include/cvmix>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${INCLUDE_DIR}> )
set_target_properties( ${_lib} PROPERTIES OUTPUT_NAME cvmix)
endforeach()

if(CVMIX_BUILD_DRIVER)

add_executable( cvmix_driver . )
target_sources( cvmix_driver PRIVATE src/cvmix_driver.F90 )
set_property( TARGET cvmix_driver PROPERTY FOLDER driver )
target_include_directories( cvmix_driver PRIVATE ${CMAKE_BINARY_DIR}/modules )
target_link_libraries( cvmix_driver PRIVATE cvmix_drivers )

endif()

# Install
if(CVMIX_BUILD_DRIVER)
install( TARGETS cvmix_driver EXPORT cvmixConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
endif()
install( TARGETS ${LIB_TARGETS} EXPORT cvmixConfig
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
install( DIRECTORY ${CMAKE_BINARY_DIR}/modules/ EXPORT cvmixConfig
DESTINATION include/cvmix
FILES_MATCHING
PATTERN "*.mod" )
install(EXPORT cvmixConfig DESTINATION cmake)

56 changes: 54 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ goes into details about how to contribute, but basically we ask three things:
INSTALLATION NOTES
------------------

CVMix can be installed using two different methods. The original uses Make
and a set of Makefiles. The new method uses CMake and two CMakelists.txt
files.

#### Building/installing using Make

The src directory contains a Makefile and a simple 'make' should be sufficient
to build the standalone driver. The first time you build, the 'cvmix_setup'
utility will run and prompt you for compiler and netcdf information - it will
Expand All @@ -58,14 +64,60 @@ $ make FC=[compiler] \
And then use -I$(INC_DIR) -L$(LIB_DIR) -lcvmix when you build software using
the CVMix library.

#### Building/installing using CMake

[CMake](https://cmake.org/) can be used in GUI mode. Further information can
be found on the CMake web-page. Below is provided the command line commands
to configure and compile CVMix. Note that CVMix has been build on Windows using
VisualStudio and the Intel Fortran compiler but NetCDF support has not been
tested.

1. cd $CVMix/bld/cmake_bld
* [CMake](https://cmake.org/) promotes out of source compilation,
any such directory will do.
2. cmake $CVMix
* The simplest configuration - using default Fortran compiler
3. cmake $CVMix -DCMAKE\_Fortran\_COMPILER=ifort
* Specifying a Fortran compiler
4. cmake $CVMix -DCVMIX\_BUILD\_DRIVER=on
* Build the CVMix driver program - off by default
5. cmake $CVMix -DCVMIX\_BUILD\_DRIVER=on CVMIX\_USE\_NetCDF=on
* Include support for NetCDF in the driver model(1)
* Note that this requires proper configuration of the installed NetCDF library.
* Setting NetCDF\_INCLUDE and NetCDF\_LIBRARIES might help.
6. cmake $CVMix -DCMAKE\_INSTALL\_PREFIX=$CVMix/bin
* Providing an installation folder (again, any such directory will do)

Combination of the above commands is possible.

After configuration has been done compilation is as simple as:

```
make
```

and installation by:

```
make install
```

After installation the build directory can be removed.

The support for CMake builds provides sufficient infrastructure for CVMix
being included in ocean models using the GIT submodule feature. This has
been used in the [GOTM](https:/gotm.net) inclusion of the CVMix mixing
models as a supplement to the original turbulence models in GOTM.

1): There is unfortunately not an official NetCDF module finder in CMake.

DIRECTORY STRUCTURE
-------------------

bin/ -- Default location for the cvmix executable.

bld/ -- Contains auxiliary files needed by the build system. CompileFlags.mak
has default compile flags for 5 different compilers -- gfortran,
has default compile flags for 5 different compilers -- gfortran,
pgf90, ifort, xlf90, and nagfor, as well as ftn (the Cray wrapper for
pgf90). At this time, no other compilers are supported on Cray systems.
cvmix_setup is a python script that saves information about what
Expand Down Expand Up @@ -179,7 +231,7 @@ src/ -- Contains the source code, organized as follows. The top directory

src/drivers/ -- Subroutines called by the driver (one per test).

src/shared/ -- Where all the modules that are needed to use CVMix with an
src/shared/ -- Where all the modules that are needed to use CVMix with an
outside model are stored. Also contains the Makefile used to
build the libcvmix.a library.

Expand Down
2 changes: 2 additions & 0 deletions bld/cmake_bld/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
4 changes: 4 additions & 0 deletions cmake_bin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bin
include
lib
cmake
18 changes: 15 additions & 3 deletions reg_tests/common/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@

build () {
if [ -z ${NO_BUILD} ]; then
make -f $CVMix/src/Makefile CVMIX_ROOT=$CVMix ${USE_NETCDF}
if [ $? != 0 ]; then
if [ "${CMAKE_BUILD}" == "TRUE" ]; then
CWD=$PWD
cd $CVMix/bld/cmake_bld
cmake $CVMix -DCVMIX_BUILD_DRIVER=on \
-DCMAKE_Fortran_COMPILER=gfortran \
-DCMAKE_INSTALL_PREFIX=$CVMix/cmake_bin \
&& make && make install
STATUS=$?
cd $CWD
else
make -f $CVMix/src/Makefile CVMIX_ROOT=$CVMix ${USE_NETCDF}
STATUS=$?
fi
if [ $STATUS != 0 ]; then
echo "Build error!"
exit 2
fi
Expand All @@ -12,7 +24,7 @@ build () {
if [ "`cat ../../bld/.netcdf_info`" == "YES" ]; then
USE_NETCDF=netcdf
fi
fi
fi
fi

}
3 changes: 3 additions & 0 deletions reg_tests/common/parse_inputs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ while [ $# -gt 0 ]; do
bad_input $1
fi
;;
-cm|--cmake)
CMAKE_BUILD=TRUE
;;
* )
bad_input $1
;;
Expand Down
7 changes: 6 additions & 1 deletion reg_tests/common/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

run () {

$CVMix/bin/cvmix < $NAMELIST
if [ "${CMAKE_BUILD}" == "TRUE" ]; then
CVMIX_EXE=$CVMix/cmake_bin/bin/cvmix_driver
else
CVMIX_EXE=$CVMix/bin/cvmix
fi
${CVMIX_EXE} < $NAMELIST

if [ $? != 0 ]; then
echo "Error in execution!"
Expand Down
41 changes: 41 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# CVMix library
add_library(cvmix_objects OBJECT .)
set_property( TARGET cvmix_objects PROPERTY FOLDER cvmixlib )
target_sources( cvmix_objects PRIVATE
shared/cvmix_kinds_and_types.F90
shared/cvmix_background.F90
shared/cvmix_convection.F90
shared/cvmix_ddiff.F90
shared/cvmix_kpp.F90
shared/cvmix_math.F90
shared/cvmix_put_get.F90
shared/cvmix_shear.F90
shared/cvmix_tidal.F90
shared/cvmix_utils.F90
)

#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cvmix_version.F90.in ${CMAKE_CURRENT_BINARY_DIR}/cvmix_version.F90)

# CVMix driver dependencies
if(CVMIX_BUILD_DRIVER)

add_library(cvmix_io STATIC .)
set_property( TARGET cvmix_io PROPERTY FOLDER driver )
target_sources( cvmix_io PRIVATE
cvmix_io.F90
)
# target_link_libraries(cvmix_io PRIVATE cvmix_static PUBLIC netcdff )
target_link_libraries(cvmix_io PRIVATE cvmix_static PUBLIC $ENV{NetCDF_LIBRARIES} )

add_library(cvmix_drivers STATIC .)
set_property( TARGET cvmix_drivers PROPERTY FOLDER driver )
target_sources( cvmix_drivers PRIVATE
drivers/cvmix_bgrnd_BL.F90
drivers/cvmix_ddiff_drv.F90
drivers/cvmix_kpp_drv.F90
drivers/cvmix_shear_drv.F90
drivers/cvmix_tidal_Simmons.F90
)
target_link_libraries( cvmix_drivers PRIVATE cvmix_io )

endif()
5 changes: 5 additions & 0 deletions src/dummy.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
! This file is needed to compile the driver program using VisualStudio.
! This is a known issue when building static/dynamic libraries based on
! object library.
! VisualStudio requires an explicit listed Fortran file to make the
! libraries - even if it is empty.

0 comments on commit 9423197

Please sign in to comment.