Skip to content

Commit 9423197

Browse files
authored
CMake build infrastucture
support for building the CVMix library and the CVMix driver using CMake
1 parent bbbf5c8 commit 9423197

File tree

10 files changed

+234
-6
lines changed

10 files changed

+234
-6
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ python:
1414
script:
1515
- cd bld; ./cvmix_setup gfortran $(dirname $(dirname $(which nc-config)))
1616
- cd ../CVMix_tools; ./run_test_suite.sh --already-ran-setup
17+
- cd ../reg_tests/Bryan-Lewis/; ./Bryan-Lewis-test.sh --cmake
1718

1819
branches:
1920
only:

CMakeLists.txt

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
cmake_minimum_required( VERSION 3.9 )
2+
3+
project( cvmix VERSION 4.0.1 LANGUAGES Fortran )
4+
5+
# Use solution folders in IDEs
6+
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
7+
8+
# Use standard GNU installation directories
9+
if ( NOT WIN32 )
10+
include( GNUInstallDirs )
11+
endif()
12+
13+
# Configuration options
14+
option( CVMIX_USE_NetCDF "Enable NetCDF format" OFF )
15+
if(CVMIX_USE_NetCDF)
16+
add_compile_definitions(_NETCDF)
17+
include_directories($ENV{NetCDF_INCLUDE})
18+
endif(CVMIX_USE_NetCDF)
19+
option( CVMIX_BUILD_STATIC_LIBS "Build static library" ON )
20+
option( CVMIX_BUILD_SHARED_LIBS "Build shared library" ON )
21+
option( CVMIX_BUILD_DRIVER "Build CVMix example/test driver" OFF )
22+
23+
# Check if shared or static builds are turned off
24+
if( NOT CVMIX_BUILD_STATIC_LIBS )
25+
message( STATUS "Turning STATIC builds OFF" )
26+
endif()
27+
if( NOT CVMIX_BUILD_SHARED_LIBS )
28+
message( STATUS "Turning SHARED builds OFF" )
29+
endif()
30+
31+
# Set default build type to Release if not specified
32+
if( NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE )
33+
message( STATUS "Setting default build type to 'Release'. Set CMAKE_BUILD_TYPE variable to change build types." )
34+
set_property( CACHE CMAKE_BUILD_TYPE PROPERTY VALUE "Release" )
35+
endif()
36+
37+
set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules )
38+
set( CMAKE_POSITION_INDEPENDENT_CODE ON )
39+
40+
add_subdirectory( src )
41+
42+
# Note - KB:
43+
# Building static and shared libs require an ugly construct to build on both
44+
# Windows and Linux. Windows will not create the libraries unless a Fortran
45+
# file is explicitly given - and Linux complains (I think due to a race
46+
# condition) if it is. Therefor the construct below - a proper solution is
47+
# most welcome.
48+
49+
# Add static lib target
50+
if( CVMIX_BUILD_STATIC_LIBS )
51+
if ( WIN32 )
52+
add_library( cvmix_static STATIC ${CMAKE_SOURCE_DIR}/src/dummy.F90 $<TARGET_OBJECTS:cvmix_objects> )
53+
else()
54+
add_library( cvmix_static STATIC $<TARGET_OBJECTS:cvmix_objects> )
55+
endif()
56+
list( APPEND LIB_TARGETS cvmix_static )
57+
endif()
58+
59+
# Add shared lib target
60+
if( CVMIX_BUILD_SHARED_LIBS )
61+
if ( WIN32 )
62+
add_library( cvmix_shared SHARED ${CMAKE_SOURCE_DIR}/src/dummy.F90 $<TARGET_OBJECTS:cvmix_objects> )
63+
else()
64+
add_library( cvmix_shared SHARED $<TARGET_OBJECTS:cvmix_objects> )
65+
endif()
66+
list( APPEND LIB_TARGETS cvmix_shared )
67+
endif()
68+
69+
# Set common lib target properties
70+
foreach( _lib IN LISTS LIB_TARGETS )
71+
target_compile_definitions( ${_lib} PUBLIC "${PUBLIC_FLAGS}" )
72+
target_include_directories( ${_lib}
73+
PUBLIC
74+
$<INSTALL_INTERFACE:include/cvmix>
75+
PRIVATE
76+
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${INCLUDE_DIR}> )
77+
set_target_properties( ${_lib} PROPERTIES OUTPUT_NAME cvmix)
78+
endforeach()
79+
80+
if(CVMIX_BUILD_DRIVER)
81+
82+
add_executable( cvmix_driver . )
83+
target_sources( cvmix_driver PRIVATE src/cvmix_driver.F90 )
84+
set_property( TARGET cvmix_driver PROPERTY FOLDER driver )
85+
target_include_directories( cvmix_driver PRIVATE ${CMAKE_BINARY_DIR}/modules )
86+
target_link_libraries( cvmix_driver PRIVATE cvmix_drivers )
87+
88+
endif()
89+
90+
# Install
91+
if(CVMIX_BUILD_DRIVER)
92+
install( TARGETS cvmix_driver EXPORT cvmixConfig
93+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
94+
endif()
95+
install( TARGETS ${LIB_TARGETS} EXPORT cvmixConfig
96+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
97+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
98+
install( DIRECTORY ${CMAKE_BINARY_DIR}/modules/ EXPORT cvmixConfig
99+
DESTINATION include/cvmix
100+
FILES_MATCHING
101+
PATTERN "*.mod" )
102+
install(EXPORT cvmixConfig DESTINATION cmake)
103+

README.md

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ goes into details about how to contribute, but basically we ask three things:
3737
INSTALLATION NOTES
3838
------------------
3939

40+
CVMix can be installed using two different methods. The original uses Make
41+
and a set of Makefiles. The new method uses CMake and two CMakelists.txt
42+
files.
43+
44+
#### Building/installing using Make
45+
4046
The src directory contains a Makefile and a simple 'make' should be sufficient
4147
to build the standalone driver. The first time you build, the 'cvmix_setup'
4248
utility will run and prompt you for compiler and netcdf information - it will
@@ -58,14 +64,60 @@ $ make FC=[compiler] \
5864
And then use -I$(INC_DIR) -L$(LIB_DIR) -lcvmix when you build software using
5965
the CVMix library.
6066

67+
#### Building/installing using CMake
68+
69+
[CMake](https://cmake.org/) can be used in GUI mode. Further information can
70+
be found on the CMake web-page. Below is provided the command line commands
71+
to configure and compile CVMix. Note that CVMix has been build on Windows using
72+
VisualStudio and the Intel Fortran compiler but NetCDF support has not been
73+
tested.
74+
75+
1. cd $CVMix/bld/cmake_bld
76+
* [CMake](https://cmake.org/) promotes out of source compilation,
77+
any such directory will do.
78+
2. cmake $CVMix
79+
* The simplest configuration - using default Fortran compiler
80+
3. cmake $CVMix -DCMAKE\_Fortran\_COMPILER=ifort
81+
* Specifying a Fortran compiler
82+
4. cmake $CVMix -DCVMIX\_BUILD\_DRIVER=on
83+
* Build the CVMix driver program - off by default
84+
5. cmake $CVMix -DCVMIX\_BUILD\_DRIVER=on CVMIX\_USE\_NetCDF=on
85+
* Include support for NetCDF in the driver model(1)
86+
* Note that this requires proper configuration of the installed NetCDF library.
87+
* Setting NetCDF\_INCLUDE and NetCDF\_LIBRARIES might help.
88+
6. cmake $CVMix -DCMAKE\_INSTALL\_PREFIX=$CVMix/bin
89+
* Providing an installation folder (again, any such directory will do)
90+
91+
Combination of the above commands is possible.
92+
93+
After configuration has been done compilation is as simple as:
94+
95+
```
96+
make
97+
```
98+
99+
and installation by:
100+
101+
```
102+
make install
103+
```
104+
105+
After installation the build directory can be removed.
106+
107+
The support for CMake builds provides sufficient infrastructure for CVMix
108+
being included in ocean models using the GIT submodule feature. This has
109+
been used in the [GOTM](https:/gotm.net) inclusion of the CVMix mixing
110+
models as a supplement to the original turbulence models in GOTM.
111+
112+
1): There is unfortunately not an official NetCDF module finder in CMake.
61113

62114
DIRECTORY STRUCTURE
63115
-------------------
64116

65117
bin/ -- Default location for the cvmix executable.
66118

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

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

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

bld/cmake_bld/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

cmake_bin/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bin
2+
include
3+
lib
4+
cmake

reg_tests/common/build.sh

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@
22

33
build () {
44
if [ -z ${NO_BUILD} ]; then
5-
make -f $CVMix/src/Makefile CVMIX_ROOT=$CVMix ${USE_NETCDF}
6-
if [ $? != 0 ]; then
5+
if [ "${CMAKE_BUILD}" == "TRUE" ]; then
6+
CWD=$PWD
7+
cd $CVMix/bld/cmake_bld
8+
cmake $CVMix -DCVMIX_BUILD_DRIVER=on \
9+
-DCMAKE_Fortran_COMPILER=gfortran \
10+
-DCMAKE_INSTALL_PREFIX=$CVMix/cmake_bin \
11+
&& make && make install
12+
STATUS=$?
13+
cd $CWD
14+
else
15+
make -f $CVMix/src/Makefile CVMIX_ROOT=$CVMix ${USE_NETCDF}
16+
STATUS=$?
17+
fi
18+
if [ $STATUS != 0 ]; then
719
echo "Build error!"
820
exit 2
921
fi
@@ -12,7 +24,7 @@ build () {
1224
if [ "`cat ../../bld/.netcdf_info`" == "YES" ]; then
1325
USE_NETCDF=netcdf
1426
fi
15-
fi
27+
fi
1628
fi
1729

1830
}

reg_tests/common/parse_inputs.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ while [ $# -gt 0 ]; do
4343
bad_input $1
4444
fi
4545
;;
46+
-cm|--cmake)
47+
CMAKE_BUILD=TRUE
48+
;;
4649
* )
4750
bad_input $1
4851
;;

reg_tests/common/run.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
run () {
44

5-
$CVMix/bin/cvmix < $NAMELIST
5+
if [ "${CMAKE_BUILD}" == "TRUE" ]; then
6+
CVMIX_EXE=$CVMix/cmake_bin/bin/cvmix_driver
7+
else
8+
CVMIX_EXE=$CVMix/bin/cvmix
9+
fi
10+
${CVMIX_EXE} < $NAMELIST
611

712
if [ $? != 0 ]; then
813
echo "Error in execution!"

src/CMakeLists.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# CVMix library
2+
add_library(cvmix_objects OBJECT .)
3+
set_property( TARGET cvmix_objects PROPERTY FOLDER cvmixlib )
4+
target_sources( cvmix_objects PRIVATE
5+
shared/cvmix_kinds_and_types.F90
6+
shared/cvmix_background.F90
7+
shared/cvmix_convection.F90
8+
shared/cvmix_ddiff.F90
9+
shared/cvmix_kpp.F90
10+
shared/cvmix_math.F90
11+
shared/cvmix_put_get.F90
12+
shared/cvmix_shear.F90
13+
shared/cvmix_tidal.F90
14+
shared/cvmix_utils.F90
15+
)
16+
17+
#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cvmix_version.F90.in ${CMAKE_CURRENT_BINARY_DIR}/cvmix_version.F90)
18+
19+
# CVMix driver dependencies
20+
if(CVMIX_BUILD_DRIVER)
21+
22+
add_library(cvmix_io STATIC .)
23+
set_property( TARGET cvmix_io PROPERTY FOLDER driver )
24+
target_sources( cvmix_io PRIVATE
25+
cvmix_io.F90
26+
)
27+
# target_link_libraries(cvmix_io PRIVATE cvmix_static PUBLIC netcdff )
28+
target_link_libraries(cvmix_io PRIVATE cvmix_static PUBLIC $ENV{NetCDF_LIBRARIES} )
29+
30+
add_library(cvmix_drivers STATIC .)
31+
set_property( TARGET cvmix_drivers PROPERTY FOLDER driver )
32+
target_sources( cvmix_drivers PRIVATE
33+
drivers/cvmix_bgrnd_BL.F90
34+
drivers/cvmix_ddiff_drv.F90
35+
drivers/cvmix_kpp_drv.F90
36+
drivers/cvmix_shear_drv.F90
37+
drivers/cvmix_tidal_Simmons.F90
38+
)
39+
target_link_libraries( cvmix_drivers PRIVATE cvmix_io )
40+
41+
endif()

src/dummy.F90

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
! This file is needed to compile the driver program using VisualStudio.
2+
! This is a known issue when building static/dynamic libraries based on
3+
! object library.
4+
! VisualStudio requires an explicit listed Fortran file to make the
5+
! libraries - even if it is empty.

0 commit comments

Comments
 (0)