Skip to content

netcdf-c: code review #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions recipes/netcdf-c/all/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.1)
project(cmake_wrapper)

include(conanbuildinfo.cmake)
conan_basic_setup(TARGETS)

add_subdirectory("source_subfolder")
8 changes: 8 additions & 0 deletions recipes/netcdf-c/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sources:
"4.7.4":
url: "https://github.com/Unidata/netcdf-c/archive/v4.7.4.tar.gz"
sha256: "99930ad7b3c4c1a8e8831fb061cb02b2170fc8e5ccaeda733bd99c3b9d31666b"
patches:
"4.7.4":
- patch_file: "patches/fix-cmake.patch"
base_path: "source_subfolder"
200 changes: 200 additions & 0 deletions recipes/netcdf-c/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import glob
import os

from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration

class NetcdfConan(ConanFile):
name = "netcdf-c"
description = "The Unidata network Common Data Form (netCDF) is an interface " \
"for scientific data access and a freely-distributed software " \
"library that provides an implementation of the interface."
license = "BSD-3-Clause"
topics = ("conan", "netcdf-c", "netcdf", "array", "dataset", "scientific")
homepage = "https://www.unidata.ucar.edu/software/netcdf"
url = "https://github.com/conan-io/conan-center-index"
exports_sources = ["CMakeLists.txt", "patches/**"]
generators = "cmake", "cmake_find_package"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"build_utilities": [True, False],
"netcdf4": [True, False],
"with_hdf4": [True, False],
"with_hdf5": [True, False],
"dap": [True, False],
"parallel": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"build_utilities": True,
"netcdf4": True,
"with_hdf4": False,
"with_hdf5": True,
"dap": True,
"parallel": False,
}

_cmake = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
if self.options.shared:
del self.options.fPIC
del self.settings.compiler.cppstd
del self.settings.compiler.libcxx

if self.options.netcdf4 and not self.options.with_hdf5:
raise ConanInvalidConfiguration("netcdf4 requires hdf5")
if not self.options.netcdf4:
if self.options.with_hdf4:
raise ConanInvalidConfiguration("netcdf4 is required for hdf4 features")
if self.options.parallel:
raise ConanInvalidConfiguration("netcdf4 is required for parallel IO")
self._strict_options_requirements()

def _strict_options_requirements(self):
if self.options.with_hdf5:
self.options["hdf5"].with_zlib = True
self.options["hdf5"].hl = True
if self.options.parallel:
raise ConanInvalidConfiguration("parallel option requires openmpi which is not yet available in CCI")
self.options["hdf5"].parallel = True # TODO: option not yet available in hdf5 recipe, requires openmpi in CCI

def requirements(self):
if self.options.with_hdf4:
self.requires("hdf4/4.2.15")
if self.options.with_hdf5:
self.requires("hdf5/1.12.0")
if self.options.dap:
self.requires("libcurl/7.72.0")
if self.options.parallel:
self.requires("openmpi/4.0.3")

def _validate_dependency_graph(self):
if self.options.with_hdf5:
if not (self.options["hdf5"].with_zlib and self.options["hdf5"].hl):
raise ConanInvalidConfiguration("netcdf-c requires hdf5 with zlib and hl")
if self.options.parallel and not self.options["hdf5"].parallel:
raise ConanInvalidConfiguration("netcdf-c parallel requires hdf5 parallel")

def source(self):
tools.get(**self.conan_data["sources"][self.version])
os.rename(self.name + "-" + self.version, self._source_subfolder)

def build(self):
self._validate_dependency_graph()
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
cmake = self._configure_cmake()
cmake.build()

def _configure_cmake(self):
if self._cmake:
return self._cmake
cmake = CMake(self)
if self.settings.compiler == "Visual Studio":
cmake.definitions["NC_USE_STATIC_CRT"] = str(self.settings.compiler.runtime).startswith("MT")
cmake.definitions["ENABLE_V2_API"] = True
cmake.definitions["BUILD_UTILITIES"] = self.options.build_utilities
cmake.definitions["ENABLE_MMAP"] = True
cmake.definitions["ENABLE_EXAMPLES"] = False
cmake.definitions["ENABLE_HDF4"] = self.options.with_hdf4
if self.options.with_hdf4:
cmake.definitions["ENABLE_HDF4_FILE_TESTS"] = False
cmake.definitions["ENABLE_NETCDF_4"] = self.options.netcdf4
cmake.definitions["ENABLE_LOGGING"] = False
cmake.definitions["ENABLE_SET_LOG_LEVEL_FUNC"] = True
cmake.definitions["ENABLE_STRICT_NULL_BYTE_HEADER_PADDING"] = False
cmake.definitions["ENABLE_RPC"] = False
cmake.definitions["USE_HDF5"] = self.options.with_hdf5
if self.options.with_hdf5:
cmake.definitions["NC_ENABLE_HDF_16_API"] = True
cmake.definitions["ENABLE_DAP"] = self.options.dap
cmake.definitions["ENABLE_BYTERANGE"] = False
cmake.definitions["ENABLE_DAP_LONG_TESTS"] = False
cmake.definitions["ENABLE_DAP_REMOTE_TESTS"] = False
cmake.definitions["ENABLE_EXTRA_TESTS"] = False
if self.settings.compiler == "Visual Studio":
cmake.definitions["ENABLE_XGETOPT"] = True
if self.settings.os != "Windows":
cmake.definitions["ENABLE_STDIO"] = False
cmake.definitions["ENABLE_FFIO"] = False
cmake.definitions["ENABLE_TESTS"] = False
cmake.definitions["ENABLE_EXTREME_NUMBERS"] = False
cmake.definitions["ENABLE_METADATA_PERF_TESTS"] = False
cmake.definitions["ENABLE_FSYNC"] = False # Option?
cmake.definitions["ENABLE_JNA"] = False
cmake.definitions["ENABLE_LARGE_FILE_SUPPORT"] = True # Option?
cmake.definitions["ENABLE_EXAMPLE_TESTS"] = False
cmake.definitions["ENABLE_PARALLEL4"] = self.options.parallel
cmake.definitions["ENABLE_PNETCDF"] = False
cmake.definitions["ENABLE_ERANGE_FILL"] = False
cmake.definitions["ENABLE_PARALLEL_TESTS"] = False
cmake.definitions["ENABLE_FILTER_TESTING"] = False
cmake.definitions["ENABLE_CLIENTSIDE_FILTERS"] = False
cmake.definitions["ENABLE_DOXYGEN"] = False
cmake.definitions["ENABLE_DISKLESS"] = True
if self.settings.compiler == "Visual Studio":
cmake.definitions["NC_MSVC_STACK_SIZE"] = 40000000 # Option?
cmake.definitions["ENABLE_CDF5"] = True
cmake.definitions["ENABLE_BASH_SCRIPT_TESTING"] = False
cmake.configure(build_folder=self._build_subfolder)
self._cmake = cmake
return self._cmake

def package(self):
self.copy("COPYRIGHT", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
cmake.install()
if self.options.build_utilities or (self.options.shared and self.settings.os == "Windows"):
os.remove(os.path.join(self.package_folder, "bin", "nc-config"))
else:
tools.rmdir(os.path.join(self.package_folder, "bin"))
tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
os.remove(os.path.join(self.package_folder, "lib", "libnetcdf.settings"))
tools.rmdir(os.path.join(self.package_folder, "share"))
if self.options.shared and self.settings.compiler == "Visual Studio":
for dll_pattern_to_remove in ["concrt*.dll", "msvcp*.dll", "vcruntime*.dll"]:
for dll_to_remove in glob.glob(os.path.join(self.package_folder, "bin", dll_pattern_to_remove)):
os.remove(dll_to_remove)

def package_info(self):
self.cpp_info.names["cmake_find_package"] = "netCDF"
self.cpp_info.names["cmake_find_package_multi"] = "netCDF"
self.cpp_info.names["pkg_config"] = "netcdf"
self.cpp_info.components["netcdf"].names["cmake_find_package"] = "netcdf"
self.cpp_info.components["netcdf"].names["cmake_find_package_multi"] = "netcdf"
self.cpp_info.components["netcdf"].names["pkg_config"] = "netcdf"
self.cpp_info.components["netcdf"].libs = ["netcdf"]
if self.options.with_hdf4:
self.cpp_info.components["netcdf"].requires.append("hdf4::hdf4")
if self.options.with_hdf5:
self.cpp_info.components["netcdf"].requires.append("hdf5::hdf5") # TODO: when components available in hdf5 recipe => requires.extend([hdf5::hl, hdf5::c])
if self.options.dap:
self.cpp_info.components["netcdf"].requires.append("libcurl::libcurl")
if self.options.parallel:
self.cpp_info.components["netcdf"].requires.append("openmpi::openmpi")
if self.settings.os == "Linux":
self.cpp_info.components["netcdf"].system_libs = ["m"]
if self.settings.os == "Windows" and self.options.shared:
self.cpp_info.components["netcdf"].defines.append("DLL_NETCDF")

if self.options.build_utilities:
bin_path = os.path.join(self.package_folder, "bin")
self.output.info("Appending PATH environment variable: {}".format(bin_path))
self.env_info.PATH.append(bin_path)
77 changes: 77 additions & 0 deletions recipes/netcdf-c/all/patches/fix-cmake.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -85,8 +85,7 @@ IF(MSVC)
ENDIF()

#Add custom CMake Module
-SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/"
- CACHE INTERNAL "Location of our custom CMake modules.")
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")

# auto-configure style checks, other CMake modules.
INCLUDE(CheckLibraryExists)
@@ -441,6 +440,11 @@ ENDIF()
OPTION(ENABLE_HDF4 "Build netCDF-4 with HDF4 read capability(HDF4, HDF5 and Zlib required)." OFF)
IF(ENABLE_HDF4)
SET(USE_HDF4 ON)
+ SET(HAVE_LIBMFHDF TRUE)
+ SET(HAVE_LIBJPEG ON)
+ link_libraries(CONAN_PKG::hdf4)
+ENDIF()
+IF(FALSE)
# Check for include files, libraries.

FIND_PATH(MFHDF_H_INCLUDE_DIR mfhdf.h)
@@ -576,13 +580,14 @@ OPTION(USE_HDF5 "Use HDF5." ${ENABLE_NETCDF_4})
IF(USE_HDF5 OR ENABLE_NETCDF_4)
SET(USE_HDF5 ON)
SET(USE_NETCDF4 ON)
+ link_libraries(CONAN_PKG::hdf5)
##
# Accommodate developers who have hdf5 libraries and
# headers on their system, but do not have a the hdf
# .cmake files. If this is the case, they should
# specify HDF5_HL_LIBRARY, HDF5_LIBRARY, HDF5_INCLUDE_DIR manually.
##
- IF(HDF5_C_LIBRARY AND HDF5_HL_LIBRARY AND HDF5_INCLUDE_DIR)
+ IF(TRUE)
SET(HDF5_LIBRARIES ${HDF5_C_LIBRARY} ${HDF5_HL_LIBRARY})
SET(HDF5_C_LIBRARIES ${HDF5_C_LIBRARY})
SET(HDF5_C_LIBRARY_hdf5 ${HDF5_C_LIBRARY})
@@ -717,6 +722,7 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)
# Use H5Pset_fapl_mpio and H5Pget_fapl_mpio, instead.
# CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Pget_fapl_mpiposix "" HDF5_IS_PARALLEL_MPIPOSIX)

+ SET(HDF5_C_LIBRARY_hdf5 ${CONAN_LIBS_HDF5})
CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Pget_fapl_mpio "" HDF5_IS_PARALLEL_MPIO)
IF(HDF5_IS_PARALLEL_MPIO)
SET(HDF5_PARALLEL ON)
@@ -754,6 +760,7 @@ IF(USE_HDF5 OR ENABLE_NETCDF_4)

# Check to see if this is hdf5-1.10.3 or later.
CHECK_LIBRARY_EXISTS(${HDF5_C_LIBRARY_hdf5} H5Dread_chunk "" HDF5_SUPPORTS_PAR_FILTERS)
+ SET(HDF5_C_LIBRARY_hdf5)

SET(H5_USE_16_API 1)
OPTION(NC_ENABLE_HDF_16_API "Enable HDF5 1.6.x Compatibility(Required)" ON)
@@ -789,8 +796,10 @@ ENDIF(USE_HDF5 OR ENABLE_NETCDF_4)

# See if we have libcurl
FIND_PACKAGE(CURL)
-ADD_DEFINITIONS(-DCURL_STATICLIB=1)
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
+if(ENABLE_DAP OR ENABLE_BYTERANGE)
+ link_libraries(CONAN_PKG::libcurl)
+endif()

# Check to see if CURLOPT_USERNAME is defined.
# It is present starting version 7.19.1.
@@ -854,7 +863,7 @@ ENDIF()
# Option to support byte-range reading of remote datasets
OPTION(ENABLE_BYTERANGE "Enable byte-range access to remote datasets.." OFF)

-IF(NOT CURL_LIBRARY)
+IF(NOT CURL_FOUND)
IF(ENABLE_BYTERANGE)
MESSAGE(FATAL_ERROR "Byte-range support specified, CURL libraries are not found.")
ENDIF()
10 changes: 10 additions & 0 deletions recipes/netcdf-c/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

find_package(netCDF REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} netCDF::netcdf)
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from conans import ConanFile, CMake, tools
import os


class NetcdfTestConan(ConanFile):
class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
generators = "cmake", "cmake_find_package_multi"

def build(self):
cmake = CMake(self)
Expand All @@ -13,5 +12,5 @@ def build(self):

def test(self):
if not tools.cross_building(self.settings):
bin_path = os.path.join("bin", "example")
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
9 changes: 9 additions & 0 deletions recipes/netcdf-c/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <netcdf.h>

#include <stdio.h>

int main() {
printf("NetCDF version: %s\n", nc_inq_libvers());
printf("*** SUCCESS!\n");
return 0;
}
File renamed without changes.
12 changes: 0 additions & 12 deletions recipes/netcdf/all/conandata.yml

This file was deleted.

Loading