Skip to content

Commit c7e3120

Browse files
committed
Merge pull request #6 from zbeekman/CMake-build
CMake build
2 parents 0793c96 + 5153ee3 commit c7e3120

11 files changed

+363
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
bin/
22
lib/
3+
builds/
34
*.mod
45
*.o

CMakeLists.txt

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# CMake Configuration and build added by Izaak Beekman -- May, 2014
2+
3+
# Copy right (c) 2014, Izaak Beekman
4+
# All rights reserved.
5+
6+
# This file is contributed to the json-fortran project, and
7+
# is licensed under the terms of json-fortran license. The json-fortran
8+
# license is located in the LICENSE file which must be distributed with
9+
# this software. The contributing author, Izaak Beekman, retains all
10+
# rights permitted by the terms of the json-fortran license.
11+
12+
cmake_minimum_required ( VERSION 2.8 FATAL_ERROR )
13+
14+
# Set the type/configuration of build to perform
15+
set ( CMAKE_CONFIGURATION_TYPES "Debug" "Release" "MinSizeRel" "RelWithDebInfo" )
16+
set ( CMAKE_BUILD_TYPE "Release"
17+
CACHE STRING "Select which configuration to build." )
18+
set_property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} )
19+
20+
21+
enable_language ( Fortran )
22+
include ( "cmake/pickFortranCompilerFlags.cmake" )
23+
24+
# Check for in-source builds and error out if found
25+
# Provides an advanced option to allow in source builds
26+
include ( "cmake/checkOutOfSource.cmake" )
27+
28+
#---------------------
29+
# Declare project name
30+
#---------------------
31+
project ( jsonfortran NONE )
32+
33+
#----------------------------------
34+
# Set version (semantic versioning)
35+
# C.F. semver.org
36+
#----------------------------------
37+
set ( VERSION_MAJOR 1 )
38+
set ( VERSION_MINOR 0 )
39+
set ( VERSION_PATCH 0 )
40+
set ( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" )
41+
42+
#-------------------------------------
43+
# Collect source files for the library
44+
#-------------------------------------
45+
set ( JF_LIB_SRCS src/json_module.f90 )
46+
47+
#-----------------------------------------
48+
# Collect all the mod files into their own
49+
# directory to ease installation issues
50+
#-----------------------------------------
51+
set ( CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/lib" )
52+
53+
#-------------------------------------
54+
# Define where our files get installed
55+
#-------------------------------------
56+
# Set the package name to be specific to the compiler used, so that
57+
# versions compiled with different compilers can be installed in parallel
58+
string ( TOLOWER ${CMAKE_PROJECT_NAME}-${CMAKE_Fortran_COMPILER_ID} PACKAGE_NAME )
59+
string ( TOLOWER ${CMAKE_Fortran_COMPILER_ID}-compiler FCOMPILER_DIR )
60+
set ( PACKAGE_VERSION "${PACKAGE_NAME}-${VERSION}" )
61+
62+
63+
# Most of this could be 'wrong' for Windows/Cygwin
64+
65+
set ( INSTALL_MOD_DIR "${PACKAGE_VERSION}/lib" )
66+
set ( INSTALL_LIB_DIR "${INSTALL_MOD_DIR}" )
67+
set( ABS_LIB_INSTALL_DIR "\${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}" )
68+
69+
# Put package export CMake files where they can be found
70+
# use `find_package ( jsonfortran-${CMAKE_Fortran_COMPILER_ID} <version> REQUIRED )`
71+
set ( EXPORT_INSTALL_DIR "${PACKAGE_VERSION}/cmake" )
72+
73+
if ( "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" )
74+
set ( ENABLE_DYLIBS_USE_RPATH TRUE CACHE BOOL
75+
"Enable @rpath install name for dylibs" )
76+
mark_as_advanced ( ENABLE_DYLIBS_USE_RPATH )
77+
endif ( "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" )
78+
79+
if ( ENABLE_DYLIBS_USE_RPATH )
80+
set ( CMAKE_MACOSX_RPATH TRUE )
81+
else ( ENABLE_DYLIBS_USE_RPATH )
82+
set ( CMAKE_INSTALL_NAME_DIR
83+
"${ABS_LIB_INSTALL_DIR}" )
84+
endif ( ENABLE_DYLIBS_USE_RPATH )
85+
86+
#---------------------------------------------
87+
# Build a shared and static library by default
88+
#---------------------------------------------
89+
90+
set ( LIB_NAME ${CMAKE_PROJECT_NAME} )
91+
add_library ( ${LIB_NAME} SHARED ${JF_LIB_SRCS} )
92+
add_library ( ${LIB_NAME}-static STATIC ${JF_LIB_SRCS} )
93+
set_target_properties ( ${LIB_NAME}-static
94+
PROPERTIES
95+
OUTPUT_NAME ${LIB_NAME}
96+
PREFIX lib
97+
VERSION ${VERSION} )
98+
set_target_properties ( ${LIB_NAME}
99+
PROPERTIES
100+
OUTPUT_NAME ${LIB_NAME}
101+
PREFIX lib
102+
SOVERSION ${VERSION_MAJOR}.${VERSION_MINOR}
103+
VERSION ${VERSION} )
104+
105+
#---------------------------------------------------------------------
106+
# Add some tests to ensure that the software is performing as expected
107+
#---------------------------------------------------------------------
108+
# Not implemented yet
109+
110+
#-------------------------
111+
# Perform the installation
112+
#-------------------------
113+
114+
install ( TARGETS ${LIB_NAME} ${LIB_NAME}-static
115+
EXPORT ${PACKAGE_NAME}-targets
116+
LIBRARY DESTINATION "${INSTALL_LIB_DIR}"
117+
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" )
118+
119+
# Code to fix the dylib install name on Mac.
120+
include ( cmake/fixupInstallNameDir.cmake )
121+
122+
install ( DIRECTORY "${CMAKE_Fortran_MODULE_DIRECTORY}/" DESTINATION "${INSTALL_MOD_DIR}" )
123+
124+
#------------------------------------------
125+
# Add portable unistall command to makefile
126+
#------------------------------------------
127+
# Adapted from the CMake Wiki FAQ
128+
configure_file ( "${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in" "${CMAKE_BINARY_DIR}/uninstall.cmake"
129+
@ONLY)
130+
131+
add_custom_target ( uninstall
132+
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_BINARY_DIR}/uninstall.cmake" )
133+
134+
#-----------------------------------------------------
135+
# Publicize installed location to other CMake projects
136+
#-----------------------------------------------------
137+
install ( EXPORT ${PACKAGE_NAME}-targets DESTINATION "${EXPORT_INSTALL_DIR}" )
138+
139+
include ( CMakePackageConfigHelpers ) # Standard CMake module
140+
write_basic_package_version_file( "${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake"
141+
VERSION ${VERSION}
142+
COMPATIBILITY SameMajorVersion )
143+
144+
# provides COMPILER_CONSISTENCY_CHECK
145+
include ( cmake/FCompilerConsistencyCheck.cmake )
146+
147+
# install package config file
148+
configure_package_config_file (
149+
"${CMAKE_SOURCE_DIR}/cmake/pkg/${CMAKE_PROJECT_NAME}-config.cmake.in"
150+
"${CMAKE_BINARY_DIR}/pkg/${PACKAGE_NAME}-config.cmake"
151+
INSTALL_DESTINATION "${EXPORT_INSTALL_DIR}"
152+
PATH_VARS EXPORT_INSTALL_DIR INSTALL_MOD_DIR )
153+
154+
# Install the config and version files so that we can find this project with others
155+
install ( FILES
156+
"${CMAKE_BINARY_DIR}/pkg/${PACKAGE_NAME}-config.cmake"
157+
"${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake"
158+
DESTINATION "${EXPORT_INSTALL_DIR}" )
159+
160+
#----------------------------------------------
161+
# Make build tree targets accessible for import
162+
#----------------------------------------------
163+
export ( TARGETS ${LIB_NAME} ${LIB_NAME}-static FILE ${PACKAGE_NAME}-targets.cmake )
164+
165+
# build tree package config file, NOT installed
166+
configure_file (
167+
"${CMAKE_SOURCE_DIR}/cmake/${CMAKE_PROJECT_NAME}-config.cmake.in"
168+
"${CMAKE_BINARY_DIR}/${PACKAGE_NAME}-config.cmake"
169+
@ONLY )
170+
171+
set ( ENABLE_BUILD_TREE_EXPORT FALSE CACHE BOOL
172+
"Add the ${PACKAGE_NAME} build tree to the CMake package registry?" )
173+
if ( ENABLE_BUILD_TREE_EXPORT )
174+
export ( PACKAGE ${PACKAGE_NAME} )
175+
endif ( ENABLE_BUILD_TREE_EXPORT )

README.md

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,54 @@ A Fortran 2008 JSON API
66
Brief Description
77
---------------
88

9-
A mostly-complete API for reading and writing JSON files, written in modern Fortran. The code requires a Fortran compiler that supports various Fortran 2003 and Fortran 2008 features such as: allocatable strings, associate, newunit, generic, class, and abstract interface. It has been successfully compiled with the Intel Fortran compiler 13.1.0 and the recent experimental 4.9 release of the GNU gfortran compiler. The source code is a single Fortran module file (json_module.f90).
9+
A mostly-complete API for reading and writing JSON files, written in
10+
modern Fortran. The code requires a Fortran compiler that supports
11+
various Fortran 2003 and Fortran 2008 features such as: allocatable
12+
strings, associate, newunit, generic, class, and abstract interface.
13+
It has been successfully compiled with the Intel Fortran compiler
14+
13.1.0 (and greater) and the recent [4.9 release of the GNU gfortran
15+
compiler](http://gcc.gnu.org/wiki/GFortran/News#GCC4.9). The source
16+
code is a single Fortran module file (json_module.f90).
17+
18+
Building the Library
19+
--------------------
20+
21+
Currently two ways are provided to build the jsonfortran library
22+
(libjsonfortran). A build script, build.sh is provided in the project
23+
root directory. Additionally, a [CMake](http://www.cmake.org) build
24+
system is provided. This build system has been tested on Mac and Linux
25+
using the Intel Fortran Compiler and gfortran 4.9. It has not been
26+
tested on Windows. This CMake based build provides an install target,
27+
and exports from both the install location and the build location so
28+
that building and using json-fortran in another CMake based project is
29+
trivial. To get started with the CMake based build, set the
30+
environment variable `FC` to point to your Fortran compiler, and
31+
create a build directory. Then `(cmake-gui|ccmake|cmake)
32+
/path/to/json-fortran-root` to configure, `make` to build and `make
33+
install` to optionally install. As long as the project is built with
34+
CMake other CMake projects can find it and link against it:
35+
36+
```CMake
37+
cmake_minimum_required ( VERSION 2.8 FATAL_ERROR )
38+
enable_language ( Fortran )
39+
project ( jf_test NONE )
40+
41+
find_package ( jsonfortran-${CMAKE_Fortran_COMPILER_ID} 1.0.0 REQUIRED )
42+
43+
add_executable ( json_example src/json_example.f90 )
44+
target_include_directories ( json_example BEFORE PUBLIC ${jsonfortran_INCLUDE_DIRS} )
45+
target_link_libraries ( json_example jsonfortran-static )
46+
# or for linking against the dynamic/shared library:
47+
# target_link_libraries ( json_example jsonfortran ) # instead
48+
```
1049

1150
Reading a JSON file
1251
---------------
1352

14-
Reading a JSON file and getting data from it is fairly straightforward. Here is an example. See the json_example.f90 file for more examples.
53+
Reading a JSON file and getting data from it is fairly
54+
straightforward. Here is an example. See the json_example.f90 file
55+
for more examples.
56+
1557
```fortran
1658
program example1
1759
@@ -45,7 +87,9 @@ Reading a JSON file and getting data from it is fairly straightforward. Here is
4587
Writing a JSON file
4688
---------------
4789

48-
Writing a json file is slightly more complicated and involves the use of pointers. See the json_example.f90 file for more examples.
90+
Writing a json file is slightly more complicated and involves the use
91+
of pointers. See the json_example.f90 file for more examples.
92+
4993
```fortran
5094
program example2
5195
@@ -88,11 +132,15 @@ Writing a json file is slightly more complicated and involves the use of pointer
88132
89133
end program example2
90134
```
135+
91136
Other Comments
92137
---------------
93138

94-
This code is a fork and extensive upgrade of the Fortran 95 FSON code that can be found at: <https://github.com/josephalevin/fson>. It includes many features that the original code did not have, and fixes many of that code's bugs.
139+
This code is a fork and extensive upgrade of the Fortran 95 FSON code
140+
that can be found at: <https://github.com/josephalevin/fson>. It
141+
includes many features that the original code did not have, and fixes
142+
many of that code's bugs.
95143

96144
More About JSON
97145
------------
98-
For more information about JSON, see: <http://www.json.org/>
146+
For more information about JSON, see: <http://www.json.org/>

build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# This is just a simple script to
55
# build the json-fortran library and
6-
# example program on Linux.
6+
# example program on Linux and Mac.
77
#
88
# Jacob Williams : 2/8/2014
99
#
@@ -40,7 +40,7 @@ LIBEXT='.a'
4040
MODEXT='.mod'
4141
WC='*'
4242

43-
LIBOUT='libjson'
43+
LIBOUT='libjsonfortran'
4444
EXEOUT='json'
4545

4646
MODCODE='json_module'

cmake/FCompilerConsistencyCheck.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Put common compiler compatibility check in a variable to be written out, rather than
2+
# duplicating it across the build and install package-config files
3+
4+
set ( COMPILER_CONSISTENCY_CHECK
5+
"# Check that the correct compiler is in use. Mod files and object files/archives
6+
# are NOT compatible across different Fortran compilers when modules are present
7+
set ( ${PACKAGE_NAME}_Fortran_COMPILER_ID ${CMAKE_Fortran_COMPILER_ID} )
8+
set ( ${PACKAGE_NAME}_COMPATIBLE_COMPILER TRUE )
9+
if ( NOT (\"${CMAKE_Fortran_COMPILER_ID}\" MATCHES \"\${CMAKE_Fortran_COMPILER_ID}\") )
10+
message ( SEND_ERROR \"Incompatible Fortran compilers detected! ${PACKAGE_NAME} was compiled with the ${CMAKE_Fortran_COMPILER_ID} Fortran compiler, but the current project is trying to use the \${CMAKE_Fortran_COMPILER_ID} Fortran compiler! In general, Fortran modules and libraries can only link against other projects built using the same compiler.\" )
11+
set ( ${PACKAGE_NAME}_COMPATIBLE_COMPILER FALSE )
12+
endif ( NOT (\"${CMAKE_Fortran_COMPILER_ID}\" MATCHES \"\${CMAKE_Fortran_COMPILER_ID}\") )" )

cmake/checkOutOfSource.cmake

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
option ( ENABLE_IN_SOURCE_BUILDS
2+
"Allow in source builds? Do so at your own risk, only if you know what you are doing. We STRONGLY advise against in source builds."
3+
OFF )
4+
mark_as_advanced ( ENABLE_IN_SOURCE_BUILDS )
5+
get_filename_component ( FULL_BUILD_DIR "${CMAKE_BINARY_DIR}" REALPATH )
6+
get_filename_component ( FULL_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH )
7+
if ( "${FULL_BUILD_DIR}" STREQUAL "${FULL_SOURCE_DIR}" )
8+
if ( ENABLE_IN_SOURCE_BUILDS )
9+
message ( WARNING
10+
"Caution, in source build detected, procede at your own risk. Build and source directories are the same: ${CMAKE_SOURCE_DIR}" )
11+
else ( ENABLE_IN_SOURCE_BUILDS )
12+
message ( SEND_ERROR
13+
"Error, in source builds are not supported. If you really want an in source build (and know what you are doing) you may set the advanced ENABLE_IN_SOURCE_BUILDS variable to ON. Otherwise create a build directory not matching the source directory, '${CMAKE_SOURCE_DIR}'." )
14+
endif ( ENABLE_IN_SOURCE_BUILDS )
15+
endif ( "${FULL_BUILD_DIR}" STREQUAL "${FULL_SOURCE_DIR}" )

cmake/fixupInstallNameDir.cmake

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Code to fixup install names when dylibs not using @rpath are installed using DESTDIR
2+
# I think this could be considered a CMake Bug. This is a work around.
3+
if ( NOT ENABLE_DYLIBS_USE_RPATH )
4+
if ( CMAKE_INSTALL_NAME_TOOL ) # On Mac and have install_name_tool
5+
install ( CODE
6+
"if ( DEFINED ENV{DESTDIR} )
7+
string ( REGEX REPLACE \"/$\" \"\" DESTDIR \"\$ENV{DESTDIR}\" ) # strip trailing /
8+
get_filename_component ( INSTALL_LIB
9+
\${DESTDIR}/${ABS_LIB_INSTALL_DIR}/lib${LIB_NAME}.${VERSION_MAJOR}.${VERSION_MINOR}.dylib
10+
ABSOLUTE )
11+
execute_process ( COMMAND \"${CMAKE_INSTALL_NAME_TOOL}\"
12+
-id \"\${INSTALL_LIB}\" \"\${INSTALL_LIB}\" )
13+
endif ( DEFINED ENV{DESTDIR} )" )
14+
endif ( CMAKE_INSTALL_NAME_TOOL )
15+
endif ( NOT ENABLE_DYLIBS_USE_RPATH )

cmake/jsonfortran-config.cmake.in

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# config file for the build tree
2+
# Allow other CMake projects to find this one without installing jsonfortran
3+
# (e.g. only configuring and building it)
4+
# No need to use CMakePackageConfigHelpers since we know all the paths with
5+
# certainty in the build tree.
6+
7+
set ( @CMAKE_PROJECT_NAME@_VERSION @VERSION@ )
8+
9+
@COMPILER_CONSISTENCY_CHECK@
10+
11+
# Make targets available to be built
12+
include ( "@CMAKE_BINARY_DIR@/@[email protected]" )
13+
14+
# Tell the compiler where to find the mod files
15+
set ( @CMAKE_PROJECT_NAME@_INCLUDE_DIRS "@CMAKE_Fortran_MODULE_DIRECTORY@" )

cmake/pickFortranCompilerFlags.cmake

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
if ( NOT Fortran_FLAGS_INIT )
2+
set ( Fortran_FLAGS_INIT TRUE )
3+
set ( ENABLE_BACK_TRACE TRUE CACHE BOOL
4+
"Enable backtraces on unexpected runtime errors? (Recommended)" )
5+
set ( ENABLE_COMPILE_TIME_WARNINGS TRUE CACHE BOOL
6+
"Enable diagnostic warnings at compile time? (Recommended)" )
7+
set ( ENABLE_RUNTIME_CHECKS FALSE CACHE BOOL
8+
"Enable compiler run-time checks? (Enabling this will turn off most compiler optimizations.)" )
9+
mark_as_advanced ( ENABLE_RUNTIME_CHECKS )
10+
11+
if ( "${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel" )
12+
if ( ENABLE_BACK_TRACE )
13+
add_compile_options ( -traceback )
14+
endif ( ENABLE_BACK_TRACE )
15+
if ( ENABLE_COMPILE_TIME_WARNINGS )
16+
# The following warning might be triggered by ifort unless explicitly silenced:
17+
# warning #7601: F2008 standard does not allow an internal procedure to be an actual argument procedure
18+
# name. (R1214.4). In the context of F2008 this is an erroneous warning.
19+
# See https://prd1idz.cps.intel.com/en-us/forums/topic/486629
20+
add_compile_options ( -warn -stand f08 -diag-disable 7601 )
21+
endif ( ENABLE_COMPILE_TIME_WARNINGS )
22+
if ( ENABLE_RUNTIME_CHECKS )
23+
add_compile_options ( -check all )
24+
endif ( ENABLE_RUNTIME_CHECKS )
25+
elseif ( "{CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU" )
26+
if ( ENABLE_BACK_TRACE )
27+
add_compile_options ( -fbacktrace )
28+
endif ( ENABLE_BACK_TRACE )
29+
if ( ENABLE_COMPILETIME_CHECKS )
30+
add_compile_options ( -Wall -Wextra -Wno-maybe-uninitialized -pedantic -std=f2008 )
31+
endif ( ENABLE_COMPILETIME_CHECKS )
32+
if ( ENABLE_RUNTIME_CHECKS )
33+
add_compile_options ( -fcheck=all )
34+
endif ( ENABLE_RUNTIME_CHECKS )
35+
endif ( "${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel" )
36+
endif ( NOT Fortran_FLAGS_INIT )

0 commit comments

Comments
 (0)