Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.10 )

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)

55 changes: 55 additions & 0 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,6 +64,55 @@ $ 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.

In this recipe CVMIX\_BASE s a convinience environmental variable pointing to
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is a convenient" rather than "s a convinience"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

the CVMix source directory. It is possible to execute the following commands
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think of "the CVMix source directory" as ${CVMIX_ROOT}/src, but when I tested this out, I needed to point to ${CVMIX_ROOT} instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me - the CVMix source directory is what is cloned from GitHub. I'm fine with calling it CVMIX_ROOT instead. The main thing is that the CMakeLists.txt file defining the project is used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMake checks the FC environment variable. Otherwise the one in the PATH is used - if any.

I don't think it is a good idea to mix the build systems and let CMake use bld/.CVMix_env. This will for sure not work on Windows :-)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me - the CVMix source directory is what is cloned from GitHub. I'm fine with calling it CVMIX_ROOT instead.

Cool, I'll make this change in bolding#1

I don't think it is a good idea to mix the build systems and let CMake use bld/.CVMix_env.

fair enough; I was caught off-guard by this, but that's just due to my lack of experience with CMake

providing the full path.


1. mkdir ~/build/cvmix
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already build CVMix outside of the source directory, can we recommend people use the existing bld/ directory? Maybe we can create an empty bld/cmake_build/directory and direct folks to build there? I.e. create bld/cmake_build/.gitignore that contains

*
!.gitignore

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The choice of build directory is up to the user - suggesting/recommending bld/ is fine with me.

When CVMix will be used as a submodule - as is the case with GOTM - it is the GOTM CMake configuration that sets the build folder.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggesting/recommending bld/ is fine with me.

Cool, I'll make this change in bolding#1 too

* [CMake](https://cmake.org/) promotes out of source compilation
2. cd ~/build/cvmix
3. cmake $CVMIX\_BASE
* The simplest configuration - using default Fortran compiler
4. cmake $CVMIX\_BASE -DCMAKE\_Fortran\_COMPILER=ifort
* Specifying a Fortran compiler
5. cmake $CVMIX\_BASE -DCVMIX\_BUILD\_DRIVER=on
* Build the CVMix driver program - off by default
6. cmake $CVMIX\_BASE -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.
7. cmake $CVMIX\_BASE -DCMAKE\_INSTALL\_PREFIX=~/local
* Providing an installation folder

Combination of the above commands is possible.

After configuration has been done compilation is as simple as:
```
make
```

and instllation by:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"installation" (missing the first "a")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what does installation do if you do not specify -DCMAKE_INSTALL_PREFIX?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo is fixed

Platform dependent
https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html

If not Windows we can introduce GNUInstallDirs if you want.

```
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
-------------------
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.
Comment thread
mnlevy1981 marked this conversation as resolved.