Skip to content

Commit 1d13869

Browse files
committed
cmake: use imported targets
1 parent f206795 commit 1d13869

File tree

7 files changed

+174
-59
lines changed

7 files changed

+174
-59
lines changed

.github/workflows/ci_linux.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: ci_linux
33
on:
44
push:
55
paths:
6-
- "**.txt"
6+
- "**/CMakeLists.txt"
77
- "**.cmake"
88
- "**.f90"
99
- ".github/workflows/ci_linux.yml"
@@ -14,15 +14,9 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v2
17-
- uses: actions/setup-python@v2
18-
with:
19-
python-version: '3.x'
2017

2118
- run: |
2219
sudo apt update -yq
2320
sudo apt install -yq --no-install-recommends gfortran libnetcdff-dev
2421
25-
- run: cmake --warn-uninitialized -B build
26-
- run: ctest -S setup.cmake -V
27-
env:
28-
FC: gfortran
22+
- run: ctest -S setup.cmake -VV

.github/workflows/ci_linux_meson.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ name: ci_linux_meson
33
on:
44
push:
55
paths:
6-
- "**.build"
6+
- "**/meson.build"
77
- ".github/workflows/ci_linux_meson.yml"
88

9+
910
jobs:
1011

1112
meson:
@@ -22,10 +23,7 @@ jobs:
2223
sudo apt install -yq --no-install-recommends gfortran ninja-build libnetcdff-dev
2324
2425
- run: meson setup build
25-
26-
- run: ninja -C build
27-
28-
# this catches configuration and build log
26+
- run: meson compile -C build
2927
- uses: actions/upload-artifact@v1
3028
if: failure()
3129
with:

.github/workflows/ci_mac.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ name: ci_mac
33
on:
44
push:
55
paths:
6-
- "**.txt"
6+
- "**/CMakeLists.txt"
77
- "**.cmake"
8-
- "**.f90"
98
- ".github/workflows/ci_mac.yml"
109

1110
jobs:

CMakeLists.txt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
cmake_minimum_required(VERSION 3.13) # 3.13 for target_sources() absolute
1+
cmake_minimum_required(VERSION 3.14)
22
if(NOT CMAKE_BUILD_TYPE)
33
set(CMAKE_BUILD_TYPE Release CACHE STRING "Debug or Release")
44
endif()
55
project(nc4fortran
66
LANGUAGES Fortran
77
VERSION 0.4.4
8-
DESCRIPTION "thin, light, easy NetCDF4 Fortran interface"
8+
DESCRIPTION "thin, light object-oriented NetCDF4 Fortran interface"
99
HOMEPAGE_URL https://github.com/geospace-code/nc4fortran)
1010

1111
enable_testing()
@@ -23,23 +23,22 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/netcdf.cmake)
2323

2424
if(NOT NCDFOK)
2525
message(STATUS "nc4fortran: NetCDF4 not working")
26-
if(NOT PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
26+
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
27+
message(FATAL_ERROR)
28+
else()
2729
return()
2830
endif()
2931
endif()
3032

31-
set(CTEST_TEST_TIMEOUT 15)
32-
3333
# --- build
3434

3535
add_library(nc4fortran)
3636
target_include_directories(nc4fortran
37-
PRIVATE ${NetCDF_INCLUDE_DIRS}
3837
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include # for IBM XL
3938
INTERFACE
4039
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
4140
$<INSTALL_INTERFACE:include>)
42-
target_link_libraries(nc4fortran PUBLIC ${NetCDF_LIBRARIES})
41+
target_link_libraries(nc4fortran PUBLIC NetCDF::NetCDF_Fortran)
4342
set_target_properties(nc4fortran PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include)
4443
add_library(nc4fortran::nc4fortran ALIAS nc4fortran)
4544

cmake/Modules/FindNetCDF.cmake

Lines changed: 107 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,55 @@
1-
# based on: https://github.com/Kitware/VTK/blob/master/CMake/FindNetCDF.cmake
2-
# in general, NetCDF requires C compiler even if only using Fortran
1+
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2+
# file Copyright.txt or https://cmake.org/licensing for details.
3+
4+
#[=======================================================================[.rst:
5+
FindNetCDF
6+
----------
7+
8+
Find NetCDF4 library
9+
10+
based on: https://github.com/Kitware/VTK/blob/master/CMake/FindNetCDF.cmake
11+
in general, NetCDF requires C compiler even if only using Fortran
12+
13+
Imported targets
14+
^^^^^^^^^^^^^^^^
15+
16+
This module defines the following :prop_tgt:`IMPORTED` target:
17+
18+
``NetCDF::NetCDF_C``
19+
NetCDF C / C++ libraries
20+
21+
``NetCDF::NetCDF_Fortran``
22+
NetCDF Fortran libraries
23+
24+
Result Variables
25+
^^^^^^^^^^^^^^^^
26+
27+
This module defines the following variables:
28+
29+
``NetCDF_FOUND``
30+
NetCDF4 is found (also ``NetCDF_C_FOUND`` and ``NetCDF_Fortran_FOUND``)
31+
``NetCDF_C_LIBRARIES`` and ``NetCDF_Fortran_LIBRARIES
32+
uncached list of libraries (using full path name) to link against
33+
``NetCDF_C_INCLUDE_DIRS`` and ``NetCDF_Fortran_INCLUDE_DIRS``
34+
uncached list of libraries (using full path name) to include
35+
36+
Search details:
37+
38+
1. look for CMake-build config files (for C / C++ only)
39+
2. CMake manual search optionally using pkg-config (this step always needed for Fortran, and for C if step 1 fails)
40+
41+
#]=======================================================================]
342

443
function(netcdf_c)
544

6-
pkg_check_modules(pc_nc netcdf QUIET) # C / CXX
45+
pkg_check_modules(pc_nc netcdf QUIET)
746

8-
find_path(NetCDF_INCLUDE_DIR
47+
find_path(NetCDF_C_INCLUDE_DIR
948
NAMES netcdf.h
1049
HINTS ${pc_nc_INCLUDE_DIRS}
11-
DOC "NetCDF include directories")
50+
DOC "NetCDF C include directory")
1251

13-
if(NOT NetCDF_INCLUDE_DIR)
52+
if(NOT NetCDF_C_INCLUDE_DIR)
1453
return()
1554
endif()
1655

@@ -24,20 +63,17 @@ if(NOT NetCDF_C_LIBRARY)
2463
endif()
2564

2665
set(NetCDF_C_FOUND true PARENT_SCOPE)
27-
set(NetCDF_INCLUDE_DIR ${NetCDF_INCLUDE_DIR} PARENT_SCOPE)
28-
set(NetCDF_LIBRARY ${NetCDF_C_LIBRARY} PARENT_SCOPE)
66+
set(NetCDF_C_INCLUDE_DIR ${NetCDF_C_INCLUDE_DIR} PARENT_SCOPE)
67+
set(NetCDF_C_LIBRARY ${NetCDF_C_LIBRARY} PARENT_SCOPE)
2968

3069
endfunction(netcdf_c)
3170

3271

3372
function(netcdf_fortran)
3473

35-
if(NOT CMAKE_Fortran_COMPILER)
36-
return()
37-
endif()
38-
3974
pkg_check_modules(pc_nc netcdf-fortran QUIET)
40-
if(NOT pc_nc_FOUND) # homebrew
75+
if(NOT pc_nc_FOUND)
76+
# homebrew
4177
pkg_check_modules(pc_nc netcdf QUIET)
4278
endif()
4379

@@ -60,28 +96,76 @@ if(NOT NetCDF_Fortran_LIBRARY)
6096
endif()
6197

6298
set(NetCDF_Fortran_FOUND true PARENT_SCOPE)
63-
set(NetCDF_INCLUDE_DIR ${NetCDF_INCLUDE_DIR} ${NetCDF_Fortran_INCLUDE_DIR} PARENT_SCOPE)
64-
set(NetCDF_LIBRARY ${NetCDF_LIBRARY} ${NetCDF_Fortran_LIBRARY} PARENT_SCOPE)
99+
set(NetCDF_Fortran_INCLUDE_DIR ${NetCDF_Fortran_INCLUDE_DIR} PARENT_SCOPE)
100+
set(NetCDF_Fortran_LIBRARY ${NetCDF_Fortran_LIBRARY} PARENT_SCOPE)
65101

66102
endfunction(netcdf_fortran)
67103

68104
#============================================================
69-
find_package(PkgConfig)
70-
71-
netcdf_c()
105+
# main program
106+
107+
# 1. CMake-built NetCDF.
108+
find_package(netCDF CONFIG QUIET)
109+
if(netCDF_FOUND)
110+
set(NetCDF_C_FOUND "${netCDF_FOUND}")
111+
set(NetCDF_C_INCLUDE_DIR "${netCDF_INCLUDE_DIR}")
112+
set(NetCDF_C_LIBRARY "${netCDF_LIBRARIES}")
113+
set(NetCDF_VERSION "${NetCDFVersion}")
114+
115+
add_library(NetCDF::NetCDF_C INTERFACE IMPORTED)
116+
if (TARGET "netCDF::netcdf")
117+
# 4.7.3
118+
set_target_properties(NetCDF::NetCDF_C PROPERTIES
119+
INTERFACE_LINK_LIBRARIES "netCDF::netcdf")
120+
elseif (TARGET "netcdf")
121+
set_target_properties(NetCDF::NetCDF_C PROPERTIES
122+
INTERFACE_LINK_LIBRARIES "netcdf")
123+
else()
124+
set_target_properties(NetCDF::NetCDF_C PROPERTIES
125+
INTERFACE_LINK_LIBRARIES "${netCDF_LIBRARIES}")
126+
endif()
127+
set_target_properties(NetCDF::NetCDF_C PROPERTIES
128+
INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_C_INCLUDE_DIR}")
129+
endif(netCDF_FOUND)
130+
131+
# 2. manual search for Fortran (and C if needed) using optional pkg-config
132+
find_package(PkgConfig QUIET)
133+
if(NOT NetCDF_C_FOUND)
134+
netcdf_c()
135+
endif()
136+
set(_ncdf_req ${NetCDF_C_LIBRARY})
72137

73-
if(NetCDF_LIBRARY AND Fortran IN_LIST NetCDF_FIND_COMPONENTS)
138+
if(Fortran IN_LIST NetCDF_FIND_COMPONENTS)
74139
netcdf_fortran()
140+
list(APPEND _ncdf_req ${NetCDF_Fortran_LIBRARY})
75141
endif()
76-
mark_as_advanced(NetCDF_LIBRARY NetCDF_INCLUDE_DIR)
77142

143+
mark_as_advanced(NetCDF_C_INCLUDE_DIR NetCDF_Fortran_INCLUDE_DIR NetCDF_C_LIBRARY NetCDF_Fortran_LIBRARY)
78144

79145
include(FindPackageHandleStandardArgs)
80146
find_package_handle_standard_args(NetCDF
81-
REQUIRED_VARS NetCDF_LIBRARY NetCDF_INCLUDE_DIR
147+
REQUIRED_VARS _ncdf_req
82148
HANDLE_COMPONENTS)
83149

84150
if(NetCDF_FOUND)
85-
set(NetCDF_INCLUDE_DIRS ${NetCDF_INCLUDE_DIR})
86-
set(NetCDF_LIBRARIES ${NetCDF_LIBRARY})
151+
set(NetCDF_C_INCLUDE_DIRS ${NetCDF_C_INCLUDE_DIR})
152+
set(NetCDF_C_LIBRARIES ${NetCDF_C_LIBRARY})
153+
154+
if(NetCDF_Fortran_FOUND)
155+
set(NetCDF_Fortran_INCLUDE_DIRS ${NetCDF_Fortran_INCLUDE_DIR})
156+
set(NetCDF_Fortran_LIBRARIES ${NetCDF_Fortran_LIBRARY})
157+
if(NOT TARGET NetCDF::NetCDF_Fortran)
158+
add_library(NetCDF::NetCDF_Fortran INTERFACE IMPORTED)
159+
set_target_properties(NetCDF::NetCDF_Fortran PROPERTIES
160+
INTERFACE_LINK_LIBRARIES "${NetCDF_Fortran_LIBRARY}"
161+
INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_Fortran_INCLUDE_DIR}")
162+
endif()
163+
endif()
164+
165+
if(NOT TARGET NetCDF::NetCDF_C)
166+
add_library(NetCDF::NetCDF_C INTERFACE IMPORTED)
167+
set_target_properties(NetCDF::NetCDF_C PROPERTIES
168+
INTERFACE_LINK_LIBRARIES "${NetCDF_C_LIBRARY}"
169+
INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_C_INCLUDE_DIR}")
170+
endif()
87171
endif()

cmake/netcdf.cmake

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ else()
66
find_package(NetCDF COMPONENTS Fortran)
77
endif()
88

9-
set(CMAKE_REQUIRED_INCLUDES ${NetCDF_INCLUDE_DIRS})
10-
set(CMAKE_REQUIRED_LIBRARIES ${NetCDF_LIBRARIES})
9+
set(CMAKE_REQUIRED_FLAGS)
10+
set(CMAKE_REQUIRED_INCLUDES)
11+
set(CMAKE_REQUIRED_LIBRARIES NetCDF::NetCDF_Fortran)
1112

1213
include(CheckFortranSourceCompiles)
1314
check_fortran_source_compiles("use netcdf; end" NCDFOK SRC_EXT f90)

setup.cmake

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,36 @@ set(_opts)
77

88
# --- boilerplate follows
99
message(STATUS "CMake ${CMAKE_VERSION}")
10-
if(CMAKE_VERSION VERSION_LESS 3.15)
11-
message(FATAL_ERROR "Please update CMake >= 3.15")
10+
if(CMAKE_VERSION VERSION_LESS 3.14)
11+
message(FATAL_ERROR "Please update CMake >= 3.14")
1212
endif()
1313

1414
# site is OS name
1515
if(NOT DEFINED CTEST_SITE)
1616
set(CTEST_SITE ${CMAKE_SYSTEM_NAME})
1717
endif()
1818

19+
# parallel test--use ctest_test(PARALLEL_LEVEL ${Ncpu} as setting CTEST_PARALLEL_LEVEL has no effect
20+
include(ProcessorCount)
21+
ProcessorCount(Ncpu)
22+
message(STATUS "${Ncpu} CPU cores detected")
23+
1924
# test name is Fortran compiler in FC
2025
# Note: ctest scripts cannot read cache variables like CMAKE_Fortran_COMPILER
2126
if(DEFINED ENV{FC})
22-
set(CTEST_BUILD_NAME $ENV{FC})
27+
set(FC $ENV{FC})
28+
set(CTEST_BUILD_NAME ${FC})
29+
30+
if(NOT DEFINED ENV{CC})
31+
# use same compiler for C and Fortran, which CMake might not do itself
32+
if(FC STREQUAL ifort)
33+
if(WIN32)
34+
set(ENV{CC} icl)
35+
else()
36+
set(ENV{CC} icc)
37+
endif()
38+
endif()
39+
endif()
2340
endif()
2441

2542
if(NOT DEFINED CTEST_BUILD_CONFIGURATION)
@@ -45,18 +62,41 @@ if(NOT DEFINED CTEST_CMAKE_GENERATOR)
4562
endif()
4663
endif()
4764

65+
# -- build and test
4866
ctest_start("Experimental" ${CTEST_SOURCE_DIRECTORY} ${CTEST_BINARY_DIRECTORY})
49-
if(NOT EXISTS ${CTEST_BINARY_DIRECTORY}/CMakeCache.txt)
50-
ctest_configure(BUILD ${CTEST_BINARY_DIRECTORY} SOURCE ${CTEST_SOURCE_DIRECTORY} OPTIONS "${_opts}")
67+
68+
ctest_configure(
69+
BUILD ${CTEST_BINARY_DIRECTORY}
70+
SOURCE ${CTEST_SOURCE_DIRECTORY}
71+
OPTIONS "${_opts}"
72+
RETURN_VALUE return_code
73+
CAPTURE_CMAKE_ERROR cmake_err)
74+
75+
if(return_code EQUAL 0 AND cmake_err EQUAL 0)
76+
ctest_build(
77+
BUILD ${CTEST_BINARY_DIRECTORY}
78+
CONFIGURATION ${CTEST_BUILD_CONFIGURATION}
79+
RETURN_VALUE return_code
80+
NUMBER_ERRORS Nerror
81+
CAPTURE_CMAKE_ERROR cmake_err
82+
)
83+
else()
84+
message(STATUS "SKIP: ctest_build(): returncode: ${return_code}; CMake error code: ${cmake_err}")
5185
endif()
52-
ctest_build(BUILD ${CTEST_BINARY_DIRECTORY} CONFIGURATION ${CTEST_BUILD_CONFIGURATION})
53-
ctest_test(BUILD ${CTEST_BINARY_DIRECTORY})
5486

55-
# using ctest_submit makes error code 0 even if test(s) failed!
56-
if(DEFINED ENV{CI})
57-
set(CI $ENV{CI})
87+
if(return_code EQUAL 0 AND Nerror EQUAL 0 AND cmake_err EQUAL 0)
88+
ctest_test(
89+
BUILD ${CTEST_BINARY_DIRECTORY}
90+
RETURN_VALUE return_code
91+
CAPTURE_CMAKE_ERROR ctest_err
92+
PARALLEL_LEVEL ${Ncpu}
93+
)
94+
else()
95+
message(STATUS "SKIP: ctest_test(): returncode: ${return_code}; CMake error code: ${cmake_err}")
5896
endif()
5997

60-
if(NOT CI)
61-
ctest_submit()
98+
ctest_submit()
99+
100+
if(NOT (return_code EQUAL 0 AND Nerror EQUAL 0 AND cmake_err EQUAL 0 AND ctest_err EQUAL 0))
101+
message(FATAL_ERROR "Build and test failed.")
62102
endif()

0 commit comments

Comments
 (0)