diff --git a/CMakeLists.txt b/CMakeLists.txt index b7662035e..35c6f6230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,32 +7,33 @@ cmake_policy(VERSION 3.13) option( USE_NATIVE_ARCH "build for native cpu architecture" ON) -option( USE_GUI "build with GUI" ON ) -option( USE_PYTHON "build with python interface" ON ) -option( USE_MPI "enable mpi parallelization" OFF ) -option( USE_MPI4PY "enable mpi4py interface" ON ) -option( USE_OCC "build with OpenCascade geometry kernel interface" OFF) -option( USE_STLGEOM "build with STL geometry support" ON) -option( USE_CSG "build with CSG kernel" ON) -option( USE_INTERFACE "build nginterface" ON) -option( USE_GEOM2D "build 2d geometry kernels" ON) -option( USE_JPEG "enable snapshots using library libjpeg" OFF ) -option( USE_MPEG "enable video recording with FFmpeg, uses libavcodec" OFF ) -option( USE_CGNS "enable CGNS file read/write support" OFF ) -option( USE_NUMA "compile with NUMA-aware code") -option( INTEL_MIC "cross compile for intel xeon phi") +option( USE_GUI "build with GUI" ON ) +option( USE_PYTHON "build with python interface" ON ) +option( USE_MPI "enable mpi parallelization" OFF ) +option( USE_MPI4PY "enable mpi4py interface" ON ) +option( USE_OCC "build with OpenCascade geometry kernel interface" OFF) +option( USE_STLGEOM "build with STL geometry support" ON) +option( USE_CSG "build with CSG kernel" ON) +option( USE_INTERFACE "build nginterface" ON) +option( USE_GEOM2D "build 2d geometry kernels" ON) +option( USE_JPEG "enable snapshots using library libjpeg" OFF ) +option( USE_MPEG "enable video recording with FFmpeg, uses libavcodec" OFF ) +option( USE_CGNS "enable CGNS file read/write support" OFF ) +option( USE_NUMA "compile with NUMA-aware code" OFF ) +option( INTEL_MIC "cross compile for intel xeon phi" OFF ) option( INSTALL_PROFILES "install environment variable settings to /etc/profile.d" OFF ) -option( USE_CCACHE "use ccache") +option( USE_CCACHE "use ccache" OFF ) option( USE_INTERNAL_TCL "Compile tcl files into the code and don't install them" ON) -option( ENABLE_UNIT_TESTS "Enable Catch unit tests") +option( USE_INTERNAL_PYBIND11 "Use internally bundled version of Pybind11" ON) +option( ENABLE_UNIT_TESTS "Enable Catch unit tests" OFF) option( ENABLE_CPP_CORE_GUIDELINES_CHECK "Enable cpp core guideline checks on ngcore" OFF) -option( USE_SPDLOG "Enable spd log logging" OFF) -option( DEBUG_LOG "Enable more debug output (may increase computation time) - only works with USE_SPDLOG=ON" OFF) -option( CHECK_RANGE "Check array range access, automatically enabled if built in debug mode" OFF) +option( USE_SPDLOG "Enable spd log logging" OFF) +option( DEBUG_LOG "Enable more debug output (may increase computation time) - only works with USE_SPDLOG=ON" OFF) +option( CHECK_RANGE "Check array range access, automatically enabled if built in debug mode" OFF) option( BUILD_STUB_FILES "Build stub files for better autocompletion" ON) -option( BUILD_FOR_CONDA "Link python libraries only to executables" OFF) +option( BUILD_FOR_CONDA "Link python libraries only to executables" OFF) -option( USE_SUPERBUILD "build dependencies automatically" ON) +option( USE_SUPERBUILD "build dependencies automatically" ON) option( TRACE_MEMORY "Enable memory tracing" OFF) set(NG_COMPILE_FLAGS "" CACHE STRING "Additional compile flags") @@ -76,19 +77,20 @@ if (USE_SUPERBUILD) # execute the superbuild (this script will be invoked again without the # USE_SUPERBUILD option this time) include (cmake/SuperBuild.cmake) - return() # stop processing this file further -else() - project(Netgen) - if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${INSTALL_DIR_DEFAULT}" CACHE PATH "Install directory" FORCE) - endif() + return() # stop processing this file further endif() +# Versioning variables come in from the configuration include, need them now. set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include (${CMAKE_CURRENT_LIST_DIR}/cmake/generate_version_file.cmake) set(CPACK_PACKAGE_VERSION "${NETGEN_VERSION}") +set(PACKAGE_VERSION "${NETGEN_VERSION}") +project(Netgen VERSION "${NETGEN_VERSION_SHORT}") +if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${INSTALL_DIR_DEFAULT}" CACHE PATH "Install directory" FORCE) +endif() ####################################################################### if(USE_CCACHE) @@ -131,7 +133,7 @@ if(USE_PYTHON) file(TO_CMAKE_PATH ${PYTHON_PACKAGES_INSTALL_DIR} PYTHON_PACKAGES_INSTALL_DIR) endif(USE_PYTHON) -set(NG_INSTALL_SUFFIX netgen CACHE STRING "Suffix appended to install directories (project name)") +set(NG_INSTALL_SUFFIX netgen-mesher CACHE STRING "Suffix appended to install directories (project name)") if(APPLE) set(NG_INSTALL_DIR_BIN_DEFAULT Contents/MacOS) @@ -230,11 +232,20 @@ endif(WIN32) if(APPLE) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup") endif(APPLE) +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options(-Wno-deprecated -Wno-sign-compare -Wno-unused-variable -Wno-unused-but-set-variable) + add_compile_options(-Wno-cpp -Wno-unused -Wno-parentheses) + # Uncomment below to run sanitizers + #add_compile_options(-g3 -O0 -fno-inline -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -fno-common) + #add_link_options(-g3 -O0 -fno-inline -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -fno-common) +endif() ####################################################################### add_library(nglib ${NGLIB_LIBRARY_TYPE}) +set_target_properties(nglib PROPERTIES VERSION "${NETGEN_LIBRARY_VERSION}") if(USE_GUI) add_library(nggui ${NGGUI_LIBRARY_TYPE}) + set_target_properties(nggui PROPERTIES VERSION "${NETGEN_LIBRARY_VERSION}") if(WIN32) set_target_properties( nggui PROPERTIES OUTPUT_NAME "libnggui") endif(WIN32) @@ -302,7 +313,13 @@ else() endif() if (USE_PYTHON) - add_subdirectory(external_dependencies/pybind11) + if (USE_INTERNAL_PYBIND11) + message(STATUS "Checking for bundled Pybind11...") + add_subdirectory(external_dependencies/pybind11) + else() + message(STATUS "Looking for external Pybind11...") + include(cmake/pybind11Tools.cmake) + endif() find_path(PYBIND_INCLUDE_DIR pybind11/pybind11.h HINTS ${PYTHON_INCLUDE_DIR}) if( PYBIND_INCLUDE_DIR ) message(STATUS "Found Pybind11: ${PYBIND_INCLUDE_DIR}") @@ -427,11 +444,23 @@ if (USE_MPEG) endif (USE_MPEG) ####################################################################### -add_custom_target(ng_generate_version_file - ${CMAKE_COMMAND} +# When not building directly from git source, version will need to be +# set explicitly--- but still get it from git! +if (NETGEN_VERSION_GIT) + add_custom_target(ng_generate_version_file + ${CMAKE_COMMAND} + -DNETGEN_VERSION_GIT=${NETGEN_VERSION_GIT} -DBDIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_LIST_DIR}/cmake/generate_version_file.cmake ) +else() + add_custom_target(ng_generate_version_file + ${CMAKE_COMMAND} + -DBDIR=${CMAKE_CURRENT_BINARY_DIR} + -P ${CMAKE_CURRENT_LIST_DIR}/cmake/generate_version_file.cmake + ) +endif() + ####################################################################### if(INSTALL_PROFILES) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/netgen.sh "#!/bin/sh\n") diff --git a/cmake/cmake_modules/FindPythonLibsNew.cmake b/cmake/cmake_modules/FindPythonLibsNew.cmake new file mode 100644 index 000000000..e660c5f3e --- /dev/null +++ b/cmake/cmake_modules/FindPythonLibsNew.cmake @@ -0,0 +1,202 @@ +# - Find python libraries +# This module finds the libraries corresponding to the Python interpreter +# FindPythonInterp provides. +# This code sets the following variables: +# +# PYTHONLIBS_FOUND - have the Python libs been found +# PYTHON_PREFIX - path to the Python installation +# PYTHON_LIBRARIES - path to the python library +# PYTHON_INCLUDE_DIRS - path to where Python.h is found +# PYTHON_MODULE_EXTENSION - lib extension, e.g. '.so' or '.pyd' +# PYTHON_MODULE_PREFIX - lib name prefix: usually an empty string +# PYTHON_SITE_PACKAGES - path to installation site-packages +# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build +# +# Thanks to talljimbo for the patch adding the 'LDVERSION' config +# variable usage. + +#============================================================================= +# Copyright 2001-2009 Kitware, Inc. +# Copyright 2012 Continuum Analytics, Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Checking for the extension makes sure that `LibsNew` was found and not just `Libs`. +if(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION) + return() +endif() + +# Use the Python interpreter to find the libs. +if(PythonLibsNew_FIND_REQUIRED) + find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED) +else() + find_package(PythonInterp ${PythonLibsNew_FIND_VERSION}) +endif() + +if(NOT PYTHONINTERP_FOUND) + set(PYTHONLIBS_FOUND FALSE) + set(PythonLibsNew_FOUND FALSE) + return() +endif() + +# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter +# testing whether sys has the gettotalrefcount function is a reliable, cross-platform +# way to detect a CPython debug interpreter. +# +# The library suffix is from the config var LDVERSION sometimes, otherwise +# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows. +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "from distutils import sysconfig as s;import sys;import struct; +print('.'.join(str(v) for v in sys.version_info)); +print(sys.prefix); +print(s.get_python_inc(plat_specific=True)); +print(s.get_python_lib(plat_specific=True)); +print(s.get_config_var('SO')); +print(hasattr(sys, 'gettotalrefcount')+0); +print(struct.calcsize('@P')); +print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION')); +print(s.get_config_var('LIBDIR') or ''); +print(s.get_config_var('MULTIARCH') or ''); +" + RESULT_VARIABLE _PYTHON_SUCCESS + OUTPUT_VARIABLE _PYTHON_VALUES + ERROR_VARIABLE _PYTHON_ERROR_VALUE) + +if(NOT _PYTHON_SUCCESS MATCHES 0) + if(PythonLibsNew_FIND_REQUIRED) + message(FATAL_ERROR + "Python config failure:\n${_PYTHON_ERROR_VALUE}") + endif() + set(PYTHONLIBS_FOUND FALSE) + set(PythonLibsNew_FOUND FALSE) + return() +endif() + +# Convert the process output into a list +if(WIN32) + string(REGEX REPLACE "\\\\" "/" _PYTHON_VALUES ${_PYTHON_VALUES}) +endif() +string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES}) +string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES}) +list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST) +list(GET _PYTHON_VALUES 1 PYTHON_PREFIX) +list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR) +list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES) +list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION) +list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG) +list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P) +list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX) +list(GET _PYTHON_VALUES 8 PYTHON_LIBDIR) +list(GET _PYTHON_VALUES 9 PYTHON_MULTIARCH) + +# Make sure the Python has the same pointer-size as the chosen compiler +# Skip if CMAKE_SIZEOF_VOID_P is not defined +if(CMAKE_SIZEOF_VOID_P AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}")) + if(PythonLibsNew_FIND_REQUIRED) + math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8") + math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8") + message(FATAL_ERROR + "Python config failure: Python is ${_PYTHON_BITS}-bit, " + "chosen compiler is ${_CMAKE_BITS}-bit") + endif() + set(PYTHONLIBS_FOUND FALSE) + set(PythonLibsNew_FOUND FALSE) + return() +endif() + +# The built-in FindPython didn't always give the version numbers +string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST}) +list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR) +list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR) +list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH) + +# Make sure all directory separators are '/' +string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX}) +string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR}) +string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES}) + +if(CMAKE_HOST_WIN32 AND NOT (MSYS OR MINGW)) + set(PYTHON_LIBRARY + "${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") + + # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the + # original python installation. They may be found relative to PYTHON_INCLUDE_DIR. + if(NOT EXISTS "${PYTHON_LIBRARY}") + get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY) + set(PYTHON_LIBRARY + "${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") + endif() + + # raise an error if the python libs are still not found. + if(NOT EXISTS "${PYTHON_LIBRARY}") + message(FATAL_ERROR "Python libraries not found") + endif() + +else() + if(PYTHON_MULTIARCH) + set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}") + else() + set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}") + endif() + #message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}") + # Probably this needs to be more involved. It would be nice if the config + # information the python interpreter itself gave us were more complete. + find_library(PYTHON_LIBRARY + NAMES "python${PYTHON_LIBRARY_SUFFIX}" + PATHS ${_PYTHON_LIBS_SEARCH} + NO_DEFAULT_PATH) + + # If all else fails, just set the name/version and let the linker figure out the path. + if(NOT PYTHON_LIBRARY) + set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX}) + endif() +endif() + +MARK_AS_ADVANCED( + PYTHON_LIBRARY + PYTHON_INCLUDE_DIR +) + +# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the +# cache entries because they are meant to specify the location of a single +# library. We now set the variables listed by the documentation for this +# module. +SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") +SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") +SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}") + +find_package_message(PYTHON + "Found PythonLibs: ${PYTHON_LIBRARY}" + "${PYTHON_EXECUTABLE}${PYTHON_VERSION}") + +set(PYTHONLIBS_FOUND TRUE) +set(PythonLibsNew_FOUND TRUE) diff --git a/cmake/generate_version_file.cmake b/cmake/generate_version_file.cmake index c4a579d13..e8f092ea2 100644 --- a/cmake/generate_version_file.cmake +++ b/cmake/generate_version_file.cmake @@ -24,8 +24,8 @@ if(status AND NOT status EQUAL 0) string(REGEX REPLACE "^netgen(.*)" "\\1" git_version_string "${git_version_string}") endif() else() - MESSAGE(WARNING "Could not determine git-version from source code - assuming 6.2.0.0") - set(git_version_string "v6.2.0.0") + MESSAGE(WARNING "Could not determine git-version from source code - assuming 6.99.2200-0-0") + set(git_version_string "v6.99.2200-0-0") endif() endif() string(STRIP ${git_version_string} git_version_string) @@ -57,6 +57,7 @@ if(NOT NETGEN_VERSION_PYTHON) set(NETGEN_VERSION_PYTHON ${NETGEN_VERSION_TWEAK}) endif() +set(NETGEN_LIBRARY_VERSION "${NETGEN_VERSION_SHORT}") set(version_file ${BDIR}/netgen_version.hpp) set(new_version_file_string "\ diff --git a/cmake/pybind11Tools.cmake b/cmake/pybind11Tools.cmake new file mode 100644 index 000000000..c7156c020 --- /dev/null +++ b/cmake/pybind11Tools.cmake @@ -0,0 +1,227 @@ +# tools/pybind11Tools.cmake -- Build system for the pybind11 modules +# +# Copyright (c) 2015 Wenzel Jakob +# +# All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +cmake_minimum_required(VERSION 2.8.12) + +# Add a CMake parameter for choosing a desired Python version +if(NOT PYBIND11_PYTHON_VERSION) + set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules") +endif() + +set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4) +find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED) + +include(CheckCXXCompilerFlag) +include(CMakeParseArguments) + +if(NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD) + if(NOT MSVC) + check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG) + + if (HAS_CPP14_FLAG) + set(PYBIND11_CPP_STANDARD -std=c++14) + else() + check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG) + if (HAS_CPP11_FLAG) + set(PYBIND11_CPP_STANDARD -std=c++11) + else() + message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!") + endif() + endif() + elseif(MSVC) + set(PYBIND11_CPP_STANDARD /std:c++14) + endif() + + set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING + "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE) +endif() + +# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and +# linkerflags are lists of flags to use. The result variable is a unique variable name for each set +# of flags: the compilation result will be cached base on the result variable. If the flags work, +# sets them in cxxflags_out/linkerflags_out internal cache variables (in addition to ${result}). +function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out linkerflags_out) + set(CMAKE_REQUIRED_LIBRARIES ${linkerflags}) + check_cxx_compiler_flag("${cxxflags}" ${result}) + if (${result}) + set(${cxxflags_out} "${cxxflags}" CACHE INTERNAL "" FORCE) + set(${linkerflags_out} "${linkerflags}" CACHE INTERNAL "" FORCE) + endif() +endfunction() + +# Internal: find the appropriate link time optimization flags for this compiler +function(_pybind11_add_lto_flags target_name prefer_thin_lto) + if (NOT DEFINED PYBIND11_LTO_CXX_FLAGS) + set(PYBIND11_LTO_CXX_FLAGS "" CACHE INTERNAL "") + set(PYBIND11_LTO_LINKER_FLAGS "" CACHE INTERNAL "") + + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(cxx_append "") + set(linker_append "") + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE) + # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it + set(linker_append ";$<$:-O3>") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(cxx_append ";-fno-fat-lto-objects") + endif() + + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto) + _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO_THIN + "-flto=thin${cxx_append}" "-flto=thin${linker_append}" + PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) + endif() + + if (NOT HAS_FLTO_THIN) + _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO + "-flto${cxx_append}" "-flto${linker_append}" + PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) + endif() + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") + # Intel equivalent to LTO is called IPO + _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO + "-ipo" "-ipo" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) + elseif(MSVC) + # cmake only interprets libraries as linker flags when they start with a - (otherwise it + # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags + # with - instead of /, even if it is a bit non-standard: + _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG + "/GL" "-LTCG" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) + endif() + + if (PYBIND11_LTO_CXX_FLAGS) + message(STATUS "LTO enabled") + else() + message(STATUS "LTO disabled (not supported by the compiler and/or linker)") + endif() + endif() + + # Enable LTO flags if found, except for Debug builds + if (PYBIND11_LTO_CXX_FLAGS) + target_compile_options(${target_name} PRIVATE "$<$>:${PYBIND11_LTO_CXX_FLAGS}>") + endif() + if (PYBIND11_LTO_LINKER_FLAGS) + target_link_libraries(${target_name} PRIVATE "$<$>:${PYBIND11_LTO_LINKER_FLAGS}>") + endif() +endfunction() + +# Build a Python extension module: +# pybind11_add_module( [MODULE | SHARED] [EXCLUDE_FROM_ALL] +# [NO_EXTRAS] [SYSTEM] [THIN_LTO] source1 [source2 ...]) +# +function(pybind11_add_module target_name) + set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS SYSTEM THIN_LTO) + cmake_parse_arguments(ARG "${options}" "" "" ${ARGN}) + + if(ARG_MODULE AND ARG_SHARED) + message(FATAL_ERROR "Can't be both MODULE and SHARED") + elseif(ARG_SHARED) + set(lib_type SHARED) + else() + set(lib_type MODULE) + endif() + + if(ARG_EXCLUDE_FROM_ALL) + set(exclude_from_all EXCLUDE_FROM_ALL) + endif() + + add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS}) + + if(ARG_SYSTEM) + set(inc_isystem SYSTEM) + endif() + + target_include_directories(${target_name} ${inc_isystem} + PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt + PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config + PRIVATE ${PYTHON_INCLUDE_DIRS}) + + # Python debug libraries expose slightly different objects + # https://docs.python.org/3.6/c-api/intro.html#debugging-builds + # https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib + if(PYTHON_IS_DEBUG) + target_compile_definitions(${target_name} PRIVATE Py_DEBUG) + endif() + + # The prefix and extension are provided by FindPythonLibsNew.cmake + set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") + set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") + + # -fvisibility=hidden is required to allow multiple modules compiled against + # different pybind versions to work properly, and for some features (e.g. + # py::module_local). We force it on everything inside the `pybind11` + # namespace; also turning it on for a pybind module compilation here avoids + # potential warnings or issues from having mixed hidden/non-hidden types. + set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") + set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden") + + if(WIN32 OR CYGWIN) + # Link against the Python shared library on Windows + target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES}) + elseif(APPLE) + # It's quite common to have multiple copies of the same Python version + # installed on one's system. E.g.: one copy from the OS and another copy + # that's statically linked into an application like Blender or Maya. + # If we link our plugin library against the OS Python here and import it + # into Blender or Maya later on, this will cause segfaults when multiple + # conflicting Python instances are active at the same time (even when they + # are of the same version). + + # Windows is not affected by this issue since it handles DLL imports + # differently. The solution for Linux and Mac OS is simple: we just don't + # link against the Python library. The resulting shared library will have + # missing symbols, but that's perfectly fine -- they will be resolved at + # import time. + + target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") + + if(ARG_SHARED) + # Suppress CMake >= 3.0 warning for shared libraries + set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON) + endif() + endif() + + # Make sure C++11/14 are enabled + if(CMAKE_VERSION VERSION_LESS 3.3) + target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD}) + else() + target_compile_options(${target_name} PUBLIC $<$:${PYBIND11_CPP_STANDARD}>) + endif() + + if(ARG_NO_EXTRAS) + return() + endif() + + _pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO}) + + if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo) + # Strip unnecessary sections of the binary on Linux/Mac OS + if(CMAKE_STRIP) + if(APPLE) + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND ${CMAKE_STRIP} -x $) + else() + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND ${CMAKE_STRIP} $) + endif() + endif() + endif() + + if(MSVC) + # /MP enables multithreaded builds (relevant when there are many files), /bigobj is + # needed for bigger binding projects due to the limit to 64k addressable sections + target_compile_options(${target_name} PRIVATE /bigobj) + if(CMAKE_VERSION VERSION_LESS 3.11) + target_compile_options(${target_name} PRIVATE $<$>:/MP>) + else() + # Only set these options for C++ files. This is important so that, for + # instance, projects that include other types of source files like CUDA + # .cu files don't get these options propagated to nvcc since that would + # cause the build to fail. + target_compile_options(${target_name} PRIVATE $<$>:$<$:/MP>>) + endif() + endif() +endfunction() diff --git a/libsrc/core/CMakeLists.txt b/libsrc/core/CMakeLists.txt index ee89b4f67..7c550fb99 100644 --- a/libsrc/core/CMakeLists.txt +++ b/libsrc/core/CMakeLists.txt @@ -13,6 +13,7 @@ add_library(ngcore ${NGCORE_LIBRARY_TYPE} utils.cpp version.cpp ) +set_target_properties(ngcore PROPERTIES VERSION "${NETGEN_LIBRARY_VERSION}") target_compile_options(ngcore PUBLIC "${NG_COMPILE_FLAGS}") diff --git a/libsrc/core/archive.hpp b/libsrc/core/archive.hpp index 4271e7255..80ae99afd 100644 --- a/libsrc/core/archive.hpp +++ b/libsrc/core/archive.hpp @@ -225,7 +225,8 @@ namespace ngcore (*this) & size; if(Input()) v.resize(size); - Do(&v[0], size); + if(size > 0) // can't deref v[0] if it doesn't exist + Do(&v[0], size); return (*this); } diff --git a/libsrc/core/version.hpp b/libsrc/core/version.hpp index 3048ce5b9..9e3973d90 100644 --- a/libsrc/core/version.hpp +++ b/libsrc/core/version.hpp @@ -1,9 +1,10 @@ #ifndef NETGEN_CORE_VERSION_HPP #define NETGEN_CORE_VERSION_HPP -#include +#include #include #include +#include "exception.hpp" #include "ngcore_api.hpp" @@ -18,37 +19,44 @@ namespace ngcore VersionInfo() = default; VersionInfo(std::string vstring) { - minor_ = release = patch = 0; - git_hash = ""; - if(vstring.substr(0,1) == "v") - vstring = vstring.substr(1,vstring.size()-1); - auto dot = vstring.find('.'); - mayor_ = std::stoi(vstring.substr(0,dot)); - if(dot == size_t(-1)) vstring = ""; - else vstring = vstring.substr(dot+1, vstring.size()-dot-1); - if(!vstring.empty()) - { - dot = vstring.find('.'); - minor_ = std::stoi(vstring.substr(0,dot)); - if (dot == size_t(-1)) vstring = ""; - else vstring = vstring.substr(dot+1, vstring.size()-dot-1); - if(!vstring.empty()) - { - dot = vstring.find('-'); - release = std::stoi(vstring.substr(0,dot)); - if(dot == size_t(-1)) vstring = ""; - else vstring = vstring.substr(dot+1,vstring.size()-dot-1); - if(!vstring.empty()) - { - dot = vstring.find('-'); - patch = std::stoi(vstring.substr(0,dot)); - if(dot == size_t(-1)) vstring = ""; - else vstring = vstring.substr(dot+1, vstring.size()-dot-1); - if(!vstring.empty()) - git_hash = vstring; - } - } - } + std::string save = vstring; + try { + minor_ = release = patch = 0; + git_hash = ""; + if(vstring.substr(0,1) == "v") + vstring = vstring.substr(1,vstring.size()-1); + auto dot = vstring.find('.'); + mayor_ = std::stoi(vstring.substr(0,dot)); + if(dot == size_t(-1)) vstring = ""; + else vstring = vstring.substr(dot+1, vstring.size()-dot-1); + if(!vstring.empty()) + { + dot = vstring.find('.'); + minor_ = std::stoi(vstring.substr(0,dot)); + if (dot == size_t(-1)) vstring = ""; + else vstring = vstring.substr(dot+1, vstring.size()-dot-1); + if(!vstring.empty()) + { + dot = vstring.find('-'); + release = std::stoi(vstring.substr(0,dot)); + if(dot == size_t(-1)) vstring = ""; + else vstring = vstring.substr(dot+1,vstring.size()-dot-1); + if(!vstring.empty()) + { + dot = vstring.find('-'); + patch = std::stoi(vstring.substr(0,dot)); + if(dot == size_t(-1)) vstring = ""; + else vstring = vstring.substr(dot+1, vstring.size()-dot-1); + if(!vstring.empty()) + git_hash = vstring; + } + } + } + } catch(...) { + std::cerr << "Malformed NETGEN_VERSION (" << save <<"\n"; + std::cerr << "Micompiled/mispackaged Netgen library\n"; + abort(); + } } VersionInfo(const char* cstr) : VersionInfo(std::string(cstr)) { } diff --git a/libsrc/csg/python_csg.cpp b/libsrc/csg/python_csg.cpp index 676e249a0..92592f009 100644 --- a/libsrc/csg/python_csg.cpp +++ b/libsrc/csg/python_csg.cpp @@ -616,7 +616,7 @@ However, when r = 0, the top part becomes a point(tip) and meshing fails! trafo)); }), py::arg("solid1"), py::arg("solid2"), - py::arg("trafo")=Transformation<3>(Vec<3>(0,0,0)) + py::arg_v("trafo", Transformation<3>(Vec<3>(0,0,0)), "Transformation<3>(Vec<3>(0,0,0))") ) .def("NameEdge", [] (CSGeometry & self, shared_ptr s1, shared_ptr s2, string name) { diff --git a/libsrc/csg/surface.hpp b/libsrc/csg/surface.hpp index f09d8c51e..7cd31b274 100644 --- a/libsrc/csg/surface.hpp +++ b/libsrc/csg/surface.hpp @@ -19,7 +19,7 @@ namespace netgen This class is used for generation of surface meshes in NETGEN */ - class Surface + class DLL_HEADER Surface { protected: /// invert normal vector @@ -236,7 +236,7 @@ namespace netgen - class Primitive + class DLL_HEADER Primitive { protected: NgArray surfaceids; diff --git a/libsrc/general/ngarray.hpp b/libsrc/general/ngarray.hpp index 05639aead..1b16c46b9 100644 --- a/libsrc/general/ngarray.hpp +++ b/libsrc/general/ngarray.hpp @@ -295,8 +295,9 @@ namespace netgen /// if responsible, deletes memory ~NgArray() { - if (ownmem) - delete [] data; + if (data) + if (ownmem) + delete [] data; } /// Change logical size. If necessary, do reallocation. Keeps contents. @@ -374,8 +375,9 @@ namespace netgen /// Deallocate memory void DeleteAll () { - if (ownmem) - delete [] data; + if (data) + if (ownmem) + delete [] data; data = 0; size = allocsize = 0; } diff --git a/libsrc/general/table.cpp b/libsrc/general/table.cpp index 732d63c39..e39d671bb 100644 --- a/libsrc/general/table.cpp +++ b/libsrc/general/table.cpp @@ -108,14 +108,16 @@ namespace netgen if (line.size == line.maxsize) { void * p = new char [(line.maxsize+5) * elsize]; - - memcpy (p, line.col, line.maxsize * elsize); - delete [] (char*)line.col; + + if (line.size > 0 && line.col != NULL) { + memcpy (p, line.col, line.maxsize * elsize); + delete [] (char*)line.col; + } line.col = p; line.maxsize += 5; } - + line.size++; } diff --git a/libsrc/general/table.hpp b/libsrc/general/table.hpp index 535d02127..44c5f9fb5 100644 --- a/libsrc/general/table.hpp +++ b/libsrc/general/table.hpp @@ -120,7 +120,8 @@ class TABLE : public BASE_TABLE /// Creates fixed maximal element size table inline TABLE (const NgFlatArray & entrysizes) - : BASE_TABLE (NgFlatArray (entrysizes.Size(), const_cast(&entrysizes[BASE])), + : BASE_TABLE (NgFlatArray (entrysizes.Size(), + entrysizes.Size() > 0 ? const_cast(&entrysizes[BASE]) : 0), sizeof(T)) { ; } diff --git a/libsrc/geom2d/python_geom2d.cpp b/libsrc/geom2d/python_geom2d.cpp index ab232f132..16ece7b1b 100644 --- a/libsrc/geom2d/python_geom2d.cpp +++ b/libsrc/geom2d/python_geom2d.cpp @@ -202,7 +202,7 @@ NGCORE_API_EXPORT void ExportGeom2d(py::module &m) self.AppendSegment (spex); }, py::arg("func"), py::arg("leftdomain") = 1, py::arg("rightdomain") = py::int_(0), - py::arg("bc")=NGDummyArgument(), py::arg("maxh")=1e99, + py::arg_v("bc", NGDummyArgument(), "NGDummyArgument()"), py::arg("maxh")=1e99, "Curve is given as parametrization on the interval [0,1]") .def("SetMaterial", &SplineGeometry2d::SetMaterial) @@ -439,7 +439,7 @@ NGCORE_API_EXPORT void ExportGeom2d(py::module &m) .def("Move", &Solid2d::Move) .def("Scale", static_cast(&Solid2d::Scale)) .def("Scale", static_cast)>(&Solid2d::Scale)) - .def("Rotate", &Solid2d::RotateDeg, py::arg("angle"), py::arg("center")=Point<2>{0,0}) + .def("Rotate", &Solid2d::RotateDeg, py::arg("angle"), py::arg_v("center", Point<2>{0,0}, "Point<2>{0,0}")) ; diff --git a/libsrc/interface/rw_cgns.cpp b/libsrc/interface/rw_cgns.cpp index ad0869a7e..a64a484b2 100644 --- a/libsrc/interface/rw_cgns.cpp +++ b/libsrc/interface/rw_cgns.cpp @@ -215,7 +215,7 @@ namespace netgen::cg if(codim==2) name += mesh.GetCD2Name(index); int ne = 0; - Array data; + Array data; if(dim==3) for(const auto el : mesh.VolumeElements()) @@ -333,7 +333,7 @@ namespace netgen::cg ZoneType_t zone_type; int fn, base, zone; int first_index_1d, first_index_2d, first_index_3d; - int nv=0, ne_1d=0, ne_2d=0, ne_3d=0; + cgsize_t nv=0, ne_1d=0, ne_2d=0, ne_3d=0; Array names_1d, names_2d, names_3d; @@ -643,7 +643,7 @@ namespace netgen int n_vertices = 0; for (auto zi : Range(1, nzones+1)) { - int size[3]; + cgsize_t size[3]; char name[100]; cg_zone_read(fn,base,zi, name, size); n_vertices += size[0]; diff --git a/libsrc/meshing/python_mesh.cpp b/libsrc/meshing/python_mesh.cpp index 5f3908326..30e5da7d9 100644 --- a/libsrc/meshing/python_mesh.cpp +++ b/libsrc/meshing/python_mesh.cpp @@ -167,7 +167,47 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) py::implicitly_convertible(); #endif // NG_MPI4PY - + py::class_> (m, "Vec3d") + .def(py::init()) + .def(py::init([](py::tuple v) + { + return Vec<3> { v[0].cast(), v[1].cast(), + v[2].cast() }; + })) + .def ("__str__", &ToString>) + .def(py::self==py::self) + .def(py::self+py::self) + .def(py::self-py::self) + .def(-py::self) + .def(double()*py::self) + .def(py::self*double()) + .def("Norm", &Vec<3>::Length) + .def("__getitem__", [](Vec<3>& vec, int index) { return vec[index]; }) + .def("__len__", [](Vec<3>& /*unused*/) { return 3; }) + ; + + py::implicitly_convertible>(); + + py::class_> (m, "Vec2d") + .def(py::init()) + .def(py::init( [] (std::pair xy) + { + return Vec<2>{xy.first, xy.second}; + })) + .def ("__str__", &ToString>) + .def(py::self==py::self) + .def(py::self+py::self) + .def(py::self-py::self) + .def(-py::self) + .def(double()*py::self) + .def(py::self*double()) + .def("Norm", &Vec<2>::Length) + .def("__getitem__", [](Vec<2>& vec, int index) { return vec[index]; }) + .def("__len__", [](Vec<2>& /*unused*/) { return 2; }) + ; + + py::implicitly_convertible>(); + py::class_(m, "NGDummyArgument") .def("__bool__", []( NGDummyArgument &self ) { return false; } ) ; @@ -219,47 +259,6 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) np_array.at(2)))); }); - py::class_> (m, "Vec2d") - .def(py::init()) - .def(py::init( [] (std::pair xy) - { - return Vec<2>{xy.first, xy.second}; - })) - .def ("__str__", &ToString>) - .def(py::self==py::self) - .def(py::self+py::self) - .def(py::self-py::self) - .def(-py::self) - .def(double()*py::self) - .def(py::self*double()) - .def("Norm", &Vec<2>::Length) - .def("__getitem__", [](Vec<2>& vec, int index) { return vec[index]; }) - .def("__len__", [](Vec<2>& /*unused*/) { return 2; }) - ; - - py::implicitly_convertible>(); - - py::class_> (m, "Vec3d") - .def(py::init()) - .def(py::init([](py::tuple v) - { - return Vec<3> { v[0].cast(), v[1].cast(), - v[2].cast() }; - })) - .def ("__str__", &ToString>) - .def(py::self==py::self) - .def(py::self+py::self) - .def(py::self-py::self) - .def(-py::self) - .def(double()*py::self) - .def(py::self*double()) - .def("Norm", &Vec<3>::Length) - .def("__getitem__", [](Vec<3>& vec, int index) { return vec[index]; }) - .def("__len__", [](Vec<3>& /*unused*/) { return 3; }) - ; - - py::implicitly_convertible>(); - m.def ("Vec", FunctionPointer ([] (double x, double y, double z) { return global_trafo(Vec<3>(x,y,z)); })); m.def("Vec", [](py::array_t np_array) @@ -410,7 +409,7 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) newel->SetIndex(index); return newel; }), - py::arg("index")=1,py::arg("vertices"), + py::arg("index")=1,py::arg_v("vertices", std::vector(), "[]"), "create volume element" ) .def("__repr__", &ToString) @@ -470,7 +469,7 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) throw NgException("Inconsistent number of vertices in Element2D"); return newel; }), - py::arg("index")=1,py::arg("vertices"), + py::arg("index")=1,py::arg_v("vertices", std::vector(), "[]"), "create surface element" ) .def_property("index", &Element2d::GetIndex, &Element2d::SetIndex) @@ -651,6 +650,38 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) .def("RestrictH", &NetgenGeometry::RestrictH) ; + typedef MeshingParameters MP; + auto mp = py::class_ (m, "MeshingParameters") + .def(py::init<>()) + .def(py::init([](MeshingParameters* other, py::kwargs kwargs) + { + MeshingParameters mp; + if(other) mp = *other; + CreateMPfromKwargs(mp, kwargs, false); + return mp; + }), py::arg("mp")=nullptr, meshingparameter_description.c_str()) + .def("__str__", &ToString) + .def("RestrictH", [](MP & mp, double x, double y, double z, double h) + { + mp.meshsize_points.Append ( MeshingParameters::MeshSizePoint(Point<3> (x,y,z), h)); + }, py::arg("x"), py::arg("y"), py::arg("z"), py::arg("h") + ) + .def("RestrictH", [](MP & mp, const Point<3>& p, double h) + { + mp.meshsize_points.Append ({p, h}); + }, py::arg("p"), py::arg("h")) + .def("RestrictHLine", [](MP& mp, const Point<3>& p1, const Point<3>& p2, + double maxh) + { + int steps = int(Dist(p1, p2) / maxh) + 2; + auto v = p2 - p1; + for (int i = 0; i <= steps; i++) + { + mp.meshsize_points.Append({p1 + double(i)/steps * v, maxh}); + } + }, py::arg("p1"), py::arg("p2"), py::arg("maxh")) + ; + py::class_>(m, "Mesh") // .def(py::init<>("create empty mesh")) @@ -663,7 +694,7 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m) mesh -> SetGeometry (nullptr); return mesh; } ), - py::arg("dim")=3, py::arg("comm")=NgMPI_Comm{} + py::arg("dim")=3, py::arg_v("comm", NgMPI_Comm(), "NgMPI_Comm()") ) .def(NGSPickle()) .def_property_readonly("comm", [](const Mesh & amesh) -> NgMPI_Comm @@ -1449,38 +1480,6 @@ project_boundaries : Optional[str] = None .value("MESHVOLUME", MESHCONST_OPTVOLUME) ; - typedef MeshingParameters MP; - auto mp = py::class_ (m, "MeshingParameters") - .def(py::init<>()) - .def(py::init([](MeshingParameters* other, py::kwargs kwargs) - { - MeshingParameters mp; - if(other) mp = *other; - CreateMPfromKwargs(mp, kwargs, false); - return mp; - }), py::arg("mp")=nullptr, meshingparameter_description.c_str()) - .def("__str__", &ToString) - .def("RestrictH", [](MP & mp, double x, double y, double z, double h) - { - mp.meshsize_points.Append ( MeshingParameters::MeshSizePoint(Point<3> (x,y,z), h)); - }, py::arg("x"), py::arg("y"), py::arg("z"), py::arg("h") - ) - .def("RestrictH", [](MP & mp, const Point<3>& p, double h) - { - mp.meshsize_points.Append ({p, h}); - }, py::arg("p"), py::arg("h")) - .def("RestrictHLine", [](MP& mp, const Point<3>& p1, const Point<3>& p2, - double maxh) - { - int steps = int(Dist(p1, p2) / maxh) + 2; - auto v = p2 - p1; - for (int i = 0; i <= steps; i++) - { - mp.meshsize_points.Append({p1 + double(i)/steps * v, maxh}); - } - }, py::arg("p1"), py::arg("p2"), py::arg("maxh")) - ; - m.def("SetTestoutFile", FunctionPointer ([] (const string & filename) { delete testout; diff --git a/libsrc/occ/python_occ.cpp b/libsrc/occ/python_occ.cpp index e0b670310..0cc39c2e7 100644 --- a/libsrc/occ/python_occ.cpp +++ b/libsrc/occ/python_occ.cpp @@ -282,7 +282,7 @@ DLL_HEADER void ExportNgOCC(py::module &m) mesh->SendRecvMesh(); } return mesh; - }, py::arg("mp") = nullptr, py::arg("comm")=NgMPI_Comm{}, + }, py::arg("mp") = static_cast(nullptr), py::arg_v("comm", NgMPI_Comm(), "NgMPI_Comm()"), py::call_guard(), (meshingparameter_description + occparameter_description).c_str()) .def_property_readonly("shape", [](const OCCGeometry & self) { return self.GetShape(); }) @@ -356,7 +356,7 @@ DLL_HEADER void ExportNgOCC(py::module &m) cout << "IsMaterial = " << material_tool->IsMaterial(label) << endl; // cout << "IsVisMaterial = " << vismaterial_tool->IsMaterial(label) << endl; } - }, py::arg("shape")=TopoDS_Shape()); + }, py::arg_v("shape", TopoDS_Shape(), "TopoDS_Shape()")); } diff --git a/libsrc/occ/python_occ_basic.cpp b/libsrc/occ/python_occ_basic.cpp index 05fdb1ee0..87e63af51 100644 --- a/libsrc/occ/python_occ_basic.cpp +++ b/libsrc/occ/python_occ_basic.cpp @@ -21,6 +21,12 @@ using namespace netgen; DLL_HEADER void ExportNgOCCBasic(py::module &m) { + auto pyAx1 = py::class_(m, "Axis", "an OCC axis in 3d"); + auto pyAx2 = py::class_(m, "gp_Ax2"); + auto pyAx2d = py::class_(m, "gp_Ax2d", "2d OCC coordinate system"); + auto pyAx3 = py::class_(m, "Axes", "an OCC coordinate system in 3d"); + auto pyDirectionalInterval = py::class_ (m, "DirectionalInterval"); + py::class_(m, "gp_Pnt", "3d OCC point") .def(py::init([] (py::tuple pnt) { @@ -130,14 +136,12 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) return str.str(); }) ; - - py::class_(m, "Axis", "an OCC axis in 3d") - .def(py::init([](gp_Pnt p, gp_Dir d) { + + pyAx1.def(py::init([](gp_Pnt p, gp_Dir d) { return gp_Ax1(p,d); }), py::arg("p"), py::arg("d")) ; - py::class_(m, "gp_Ax2") - .def(py::init([](gp_Pnt p, gp_Dir d) { + pyAx2.def(py::init([](gp_Pnt p, gp_Dir d) { return gp_Ax2(p,d); })) .def(py::init([](const gp_Ax3 & ax3) { @@ -145,8 +149,7 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) })) ; - py::class_(m, "Axes", "an OCC coordinate system in 3d") - .def(py::init([](gp_Pnt p, gp_Dir N, gp_Dir Vx) { + pyAx3.def(py::init([](gp_Pnt p, gp_Dir N, gp_Dir Vx) { return gp_Ax3(p,N, Vx); }), py::arg("p")=gp_Pnt(0,0,0), py::arg("n")=gp_Vec(0,0,1), py::arg("h")=gp_Vec(1,0,0)) .def(py::init()) @@ -268,10 +271,9 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) - py::class_(m, "gp_Ax2d", "2d OCC coordinate system") - .def(py::init([](gp_Pnt2d p, gp_Dir2d d) { + pyAx2d.def(py::init([](gp_Pnt2d p, gp_Dir2d d) { return gp_Ax2d(p,d); - }), py::arg("p")=gp_Pnt2d(0,0), py::arg("d")=gp_Dir2d(1,0)) + }), py::arg("p")=gp_Pnt2d(0,0), py::arg_v("d", gp_Dir2d(1,0), "gp_Dir2d(1,0)"), "Create an axis in a plane") ; py::class_(m, "gp_GTrsf") @@ -330,8 +332,7 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) ; - py::class_ (m, "DirectionalInterval") - .def("__str__", [](DirectionalInterval self) + pyDirectionalInterval.def("__str__", [](DirectionalInterval self) { stringstream str; str << "(" << self.minval << ", " << self.maxval << ")"; diff --git a/libsrc/occ/python_occ_shapes.cpp b/libsrc/occ/python_occ_shapes.cpp index f29d4c618..bd67b0a2b 100644 --- a/libsrc/occ/python_occ_shapes.cpp +++ b/libsrc/occ/python_occ_shapes.cpp @@ -69,6 +69,8 @@ #include #include #include +#include +#include #include #include @@ -668,7 +670,10 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) .export_values() ; - + auto pyListOfShapes_Forward = py::class_ (m, "ListOfShapes"); + auto pyGeom2d_Curve_Forward = py::class_ (m, "Geom2d_Curve"); + py::class_,3>,size_t>>(m, "ArrayOfTriangles"); + py::class_ (m, "TopoDS_Shape") .def("__str__", [] (const TopoDS_Shape & shape) { @@ -1543,7 +1548,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) bool operator==(ListOfShapesIterator it2) const { return ptr == it2.ptr; } }; - py::class_ (m, "ListOfShapes") + pyListOfShapes_Forward .def("__iter__", [](ListOfShapes &s) { return py::make_iterator(ListOfShapesIterator(&*s.begin()), ListOfShapesIterator(&*s.end())); @@ -1715,7 +1720,8 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) { Identify(me, other, name, type, occ2ng(trafo)); }, py::arg("other"), py::arg("name"), - py::arg("type")=Identifications::PERIODIC, py::arg("trafo"), + py::arg("type")=Identifications::PERIODIC, + py::arg_v("trafo", gp_Trsf(), "gp_Trsf()"), "Identify shapes for periodic meshing") ; @@ -1731,7 +1737,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) - py::class_ (m, "Geom2d_Curve") + pyGeom2d_Curve_Forward .def("Trim", [](Handle(Geom2d_Curve) curve, double u1, double u2) -> Handle(Geom2d_Curve) { return new Geom2d_TrimmedCurve (curve, u1, u2); @@ -2434,7 +2440,7 @@ degen_tol : double }, py::arg("edges"), py::arg("tol")=1e-8, py::arg("shared")=true); py::class_> (m, "WorkPlane") - .def(py::init(), py::arg("axes")=gp_Ax3(), py::arg("pos")=gp_Ax2d()) + .def(py::init(), py::arg_v("axes", gp_Ax3(), "gp_Ax3()"), py::arg_v("pos", gp_Ax2d(), "gp_Ax2d()")) .def_property_readonly("cur_loc", &WorkPlane::CurrentLocation) .def_property_readonly("cur_dir", &WorkPlane::CurrentDirection) .def_property_readonly("start_pnt", &WorkPlane::StartPnt) diff --git a/libsrc/stlgeom/stltopology.hpp b/libsrc/stlgeom/stltopology.hpp index 101cde531..6f916bed9 100644 --- a/libsrc/stlgeom/stltopology.hpp +++ b/libsrc/stlgeom/stltopology.hpp @@ -276,7 +276,7 @@ ostream& operator<<(ostream& os, const STLTriangle& t); -class STLTopology +class DLL_HEADER STLTopology { protected: Array trias; diff --git a/ng/CMakeLists.txt b/ng/CMakeLists.txt index 3ad3d8be3..9320d2f30 100644 --- a/ng/CMakeLists.txt +++ b/ng/CMakeLists.txt @@ -20,6 +20,7 @@ if(USE_GUI) if(NOT BUILD_FOR_CONDA) add_executable(netgen ngappinit.cpp) + set_target_properties(netgen PROPERTIES OUTPUT_NAME netgen-mesher) if(WIN32) target_sources(netgen PRIVATE ../windows/netgen.rc) endif(WIN32) @@ -28,7 +29,7 @@ if(USE_GUI) if(APPLE) set_target_properties(netgen PROPERTIES OUTPUT_NAME netgen) endif(APPLE) - target_link_libraries( netgen ${PYTHON_LIBRARIES} ${TCL_LIBRARY} ${TK_LIBRARY}) + target_link_libraries( netgen ${PYTHON_LIBRARIES} ${TCL_LIBRARY} ${TK_LIBRARY} ${JPEG_LIBRARIES}) endif(NOT BUILD_FOR_CONDA) install(TARGETS nggui ${NG_INSTALL_DIR}) @@ -36,6 +37,7 @@ endif(USE_GUI) if(USE_PYTHON) add_library(ngpy SHARED netgenpy.cpp) + set_target_properties(ngpy PROPERTIES VERSION "${NETGEN_LIBRARY_VERSION}") target_link_libraries( ngpy PUBLIC nglib PRIVATE "$" ) if(APPLE) set_target_properties( ngpy PROPERTIES SUFFIX ".so") @@ -44,10 +46,11 @@ if(USE_PYTHON) set_target_properties( ngpy PROPERTIES OUTPUT_NAME "libngpy") endif() set_target_properties(ngpy PROPERTIES INSTALL_RPATH "${NG_RPATH_TOKEN}/../${NETGEN_PYTHON_RPATH}") - install(TARGETS ngpy DESTINATION ${NG_INSTALL_DIR_PYTHON}/${NG_INSTALL_SUFFIX} COMPONENT netgen) + install(TARGETS ngpy DESTINATION ${NG_INSTALL_DIR_PYTHON}/netgen COMPONENT netgen) if(USE_GUI) add_library(ngguipy SHARED ngguipy.cpp) + set_target_properties(ngguipy PROPERTIES VERSION "${NETGEN_LIBRARY_VERSION}") target_link_libraries( ngguipy PUBLIC nglib nggui PRIVATE "$" $) if(APPLE) set_target_properties( ngguipy PROPERTIES SUFFIX ".so") @@ -56,7 +59,7 @@ if(USE_PYTHON) set_target_properties( ngguipy PROPERTIES OUTPUT_NAME "libngguipy") endif() set_target_properties(ngguipy PROPERTIES INSTALL_RPATH "${NG_RPATH_TOKEN}/../${NETGEN_PYTHON_RPATH}") - install(TARGETS ngguipy DESTINATION ${NG_INSTALL_DIR_PYTHON}/${NG_INSTALL_SUFFIX} COMPONENT netgen) + install(TARGETS ngguipy DESTINATION ${NG_INSTALL_DIR_PYTHON}/netgen COMPONENT netgen) endif(USE_GUI) endif(USE_PYTHON) diff --git a/ng/ngtesting.tcl b/ng/ngtesting.tcl index 24b589834..a2c6f0ca9 100644 --- a/ng/ngtesting.tcl +++ b/ng/ngtesting.tcl @@ -64,7 +64,7 @@ proc ngtest { {t all} {f ""}} { } puts "\n ** testing in2d files in tutorials/ **" - set testdir "$::ngdir/../share/netgen" + set testdir "$::ngdir/../share/netgen-mesher" set in2dfiles { demo2d newin2d square v2in2d } foreach {tfile} $in2dfiles { if {$f != ""} { puts " * meshing file tutorials/$tfile.in2d..." } @@ -89,7 +89,7 @@ proc ngtest { {t all} {f ""}} { } puts "\n ** testing geo files in tutorials/ **" - set testdir "$::ngdir/../share/netgen" + set testdir "$::ngdir/../share/netgen-mesher" set geofiles { boxcyl cubemcyl extrusion revolution trafo circle_on_cube cubemsphere fichera sculpture twobricks cone cylinder lshape3d shaft twocubes diff --git a/package/fedora/netgen-mesher-bleed.spec b/package/fedora/netgen-mesher-bleed.spec new file mode 100644 index 000000000..798571675 --- /dev/null +++ b/package/fedora/netgen-mesher-bleed.spec @@ -0,0 +1,606 @@ +%{!?tcl_version: %global tcl_version %(echo 'puts $tcl_version' | tclsh)} +%{!?tcl_sitearch: %global tcl_sitearch %{_libdir}/tcl%{tcl_version}} + +# Don't abort on compilation errors of the example python snippets +%global _python_bytecompile_errors_terminate_build 0 + +%if 0%{?el6} + %ifarch ppc64 + %global build_mpich 0 + %else + %global build_mpich 1 + %endif +%else + %global build_mpich 1 +%endif +%global build_openmpi 1 + +%global save_PYTHONPATH %{getenv:PYTHONPATH} +%global save_LD_PRELOAD %{getenv:LD_PRELOAD} +%global save_ASAN_OPTIONS %{getenv:ASAN_OPTIONS} +%define name netgen-mesher + +Name: %{name} +Version: {{{git_last_tag}}}.bleed^{{{git_last_tag_commits}}}.{{{git_head_short}}} +Release: 1%{?dist} +Summary: Automatic mesh generation tool +License: LGPLv2 +URL: https://github.com/montylab3d/netgen +Source0: {{{ git_repo_pack }}} + +BuildRequires: cmake +BuildRequires: gcc-c++ +BuildRequires: tcl-devel +BuildRequires: tk-devel +BuildRequires: opencascade-devel +BuildRequires: libjpeg-turbo-devel +BuildRequires: metis-devel +BuildRequires: mesa-libGLU-devel +BuildRequires: libXmu-devel +BuildRequires: desktop-file-utils +BuildRequires: dos2unix +BuildRequires: python3-devel +BuildRequires: pybind11-devel +BuildRequires: git + +# Bundles a modified version of togl-2.1 +Provides: bundled(tcl-togl) = 2.1 + + +Requires: %{name}-common = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description +NETGEN is an automatic 3d tetrahedral mesh generator. It accepts input from +constructive solid geometry (CSG) or boundary representation (BRep) from STL +file format. The connection to a geometry kernel allows the handling of IGES +and STEP files. NETGEN contains modules for mesh optimization and hierarchical +mesh refinement. + +%package common +Summary: Common files for netgen +Requires: hicolor-icon-theme +Requires: tix +Requires: cgnslib + +BuildArch: noarch + +%description common +Common files for netgen. + +%package libs +Summary: Netgen libraries + +%description libs +Netgen libraries. + +%package devel +Summary: Development files for netgen +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: cgnslib-devel + +%description devel +Development files for netgen. + +%package devel-private +Summary: Private headers of netgen +Requires: %{name}-devel%{?_isa} = %{version}-%{release} + +%description devel-private +Private headers of netgen, needed to build certain netgen based software +packages. + +%package -n python3-%{name} +Summary: Python3 interface for netgen +%{?python_provide:%python_provide python3-netgen} +Requires: %{name}-openmpi-libs%{?_isa} = %{version}-%{release} + +%description -n python3-%{name} +Python3 interface for netgen. + +############################################################################### + +%if %{build_openmpi} +%package openmpi +Summary: Netgen compiled against openmpi +%description openmpi +Netgen compiled against openmpi. +BuildRequires: openmpi-devel +BuildRequires: python3-mpi4py-openmpi +BuildRequires: cgnslib-openmpi-devel +Requires: %{name}-common = %{version}-%{release} +Requires: %{name}-openmpi-libs%{?_isa} = %{version}-%{release} +Requires: cgnslib-openmpi + +%package openmpi-libs +Summary: Netgen libraries compiled against openmpi +%description openmpi-libs +Netgen libraries compiled against openmpi. + +%package openmpi-devel +Summary: Development files for Netgen compiled against openmpi +%description openmpi-devel +Development files for Netgen compiled against openmpi. +Requires: openmpi-devel +Requires: %{name}-openmpi%{?_isa} = %{version}-%{release} + +%package -n python3-%{name}-openmpi +Summary: Python3 interface for netgen compiled against openmpi +%{?python_provide:%python_provide python3-netgen-openmpi} +Requires: %{name}-openmpi-libs%{?_isa} = %{version}-%{release} +%description -n python3-%{name}-openmpi +Python3 interface for netgen compiled against openmpi. + +%endif + +############################################################################### + +%if %{build_mpich} +%package mpich +Summary: Netgen compiled against mpich +%description mpich +Netgen compiled against mpich. +BuildRequires: mpich-devel +BuildRequires: python3-mpi4py-mpich +BuildRequires: cgnslib-mpich-devel +Requires: %{name}-common = %{version}-%{release} +Requires: %{name}-mpich-libs%{?_isa} = %{version}-%{release} +Requires: cgnslib-mpich + +%package mpich-libs +Summary: Netgen libraries compiled against mpich +%description mpich-libs +Netgen libraries compiled against mpich. + +%package mpich-devel +Summary: Development files for Netgen compiled against mpich +%description mpich-devel +Development files for Netgen compiled against mpich. +Requires: mpich-devel +Requires: %{name}-mpich%{?_isa} = %{version}-%{release} + +%package -n python3-%{name}-mpich +Summary: Python3 interface for netgen compiled against mpich +%{?python_provide:%python_provide python3-netgen-mpich} +Requires: %{name}-openmpi-libs%{?_isa} = %{version}-%{release} +%description -n python3-%{name}-mpich +Python3 interface for netgen compiled against mpich. + +%endif + +############################################################################### + +%prep +%autosetup -p1 -n {{{git_repo_name}}} + +echo "RPM packeage build set up for %{name} version %{version}-%{release}" + +# Remove bundled pybind +rm -rf external_dependencies/pybind11 + +%build +### serial version ### +%define _vpath_builddir %{_target_platform} +%cmake \ + -DNETGEN_VERSION_GIT={{{git describe --tags --match "v[0-9]*" --long --dirty}}} \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DNG_INSTALL_SUFFIX=%{name} \ + -DUSE_NATIVE_ARCH=OFF \ + -DNG_INSTALL_DIR_INCLUDE=%{_includedir}/%{name} \ + -DNG_INSTALL_DIR_LIB=%{_libdir} \ + -DNG_INSTALL_DIR_CMAKE=%{_libdir}/cmake/%{name} \ + -DNG_INSTALL_DIR_PYTHON=%{python3_sitearch} \ + -DNETGEN_PYTHON_PACKAGE_NAME="netgen" \ + -DUSE_CGNS=1 \ + -DUSE_JPEG=1 \ + -DUSE_OCC=1 \ + -DOpenGL_GL_PREFERENCE=GLVND \ + -DUSE_INTERNAL_PYBIND11=OFF \ + -DUSE_INTERNAL_TCL=ON \ + -DUSE_SUPERBUILD=OFF \ + -DENABLE_UNIT_TESTS=ON \ + -DCHECK_RANGE=ON \ + -DTRACE_MEMORY=ON \ +%cmake_build + +### openmpi version ### +%if %{build_openmpi} +%define _vpath_builddir %{_target_platform}-openmpi +%{_openmpi_load} +export CXX=mpicxx +%cmake \ + -DNETGEN_VERSION_GIT={{{git describe --tags --match "v[0-9]*" --long --dirty}}} \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DNG_INSTALL_SUFFIX=%{name} \ + -DUSE_NATIVE_ARCH=OFF \ + -DNG_INSTALL_DIR_INCLUDE=%{_includedir}/openmpi/%{name} \ + -DNG_INSTALL_DIR_BIN=%{_libdir}/openmpi/bin/ \ + -DNG_INSTALL_DIR_LIB=%{_libdir}/openmpi/lib/ \ + -DNG_INSTALL_DIR_CMAKE=%{_libdir}/openmpi/lib/cmake/%{name} \ + -DNG_INSTALL_DIR_PYTHON=%{_libdir}/openmpi/python%{python3_version}/site-packages/ \ + -DNETGEN_PYTHON_PACKAGE_NAME="netgen" \ + -DUSE_CGNS=1 \ + -DUSE_JPEG=1 \ + -DUSE_OCC=1 \ + -DUSE_MPI=1 \ + -DOpenGL_GL_PREFERENCE=GLVND \ + -DUSE_INTERNAL_PYBIND11=OFF \ + -DUSE_INTERNAL_TCL=ON \ + -DUSE_SUPERBUILD=OFF \ +%cmake_build +%{_openmpi_unload} +%endif + +### mpich version ### +%if %{build_mpich} +%define _vpath_builddir %{_target_platform}-mpich +%{_mpich_load} +export CXX=mpicxx +%cmake \ + -DNETGEN_VERSION_GIT={{{git describe --tags --match "v[0-9]*" --long --dirty}}} \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DNG_INSTALL_SUFFIX=%{name} \ + -DUSE_NATIVE_ARCH=OFF \ + -DUSE_SUPERBUILD=OFF \ + -DNG_INSTALL_DIR_INCLUDE=%{_includedir}/mpich/%{name} \ + -DNG_INSTALL_DIR_BIN=%{_libdir}/mpich/bin/ \ + -DNG_INSTALL_DIR_LIB=%{_libdir}/mpich/lib/ \ + -DNG_INSTALL_DIR_CMAKE=%{_libdir}/mpich/lib/cmake/%{name} \ + -DNG_INSTALL_DIR_PYTHON=%{_libdir}/mpich/python%{python3_version}/site-packages/ \ + -DNETGEN_PYTHON_PACKAGE_NAME="netgen" \ + -DUSE_CGNS=1 \ + -DUSE_JPEG=1 \ + -DUSE_OCC=1 \ + -DUSE_MPI=1 \ + -DOpenGL_GL_PREFERENCE=GLVND \ + -DUSE_INTERNAL_PYBIND11=OFF \ + -DUSE_INTERNAL_TCL=ON \ + -DUSE_SUPERBUILD=OFF \ +%cmake_build +%{_mpich_unload} +%endif + + +%install +%define writepkgconfig() \ +install -d -m 0755 %{buildroot}/$MPI_LIB/pkgconfig; \ +cat > %{buildroot}/$MPI_LIB/pkgconfig/%{name}.pc << EOF\ +prefix=%{_prefix}\ +exec_prefix=${prefix}\ +libdir=$MPI_LIB\ +includedir=$MPI_INCLUDE/%{name}\ +\ +Name: %{name}\ +Description: %{summary}\ +Version: %{version}\ +Libs: -L\\\${libdir} -lnglib\ +Libs.private: -lngcgs -lnggeom2d -lngmesh -lngocc -lngstl\ +Cflags: -I\\\${includedir}\ +EOF\ +%{nil} + +### openmpi version ### +%if %{build_openmpi} +%define _vpath_builddir %{_target_platform}-openmpi +%{_openmpi_load} +export PYTHONPATH=.:%{buildroot}%{_libdir}/openmpi/python%{python3_version}/site-packages/ \ +%cmake_install +export PYTHONPATH=%{save_PYTHONPATH} +%writepkgconfig +%{_openmpi_unload} +%endif + +### mpich version ### +%if %{build_mpich} +%define _vpath_builddir %{_target_platform}-mpich +%{_mpich_load} +export PYTHONPATH=.:%{buildroot}%{_libdir}/mpich/python%{python3_version}/site-packages/ \ +%cmake_install +export PYTHONPATH=%{save_PYTHONPATH} +%writepkgconfig +%{_mpich_unload} +%endif + +### serial version ### +%define _vpath_builddir %{_target_platform} +export PYTHONPATH=.:%{buildroot}%{python3_sitearch} +#export LD_PRELOAD=libasan.so.6 +#export ASAN_OPTIONS=detect_odr_violation=0:detect_leaks=0 +%cmake_install +export PYTHONPATH=%{save_PYTHONPATH} +#export LD_PRELOAD=%{save_LD_PRELOAD} +#export ASAN_OPTIONS=${save_ASAN_OPTIONS} +export MPI_LIB=%{_libdir} +export MPI_INCLUDE=%{_includedir} +%writepkgconfig + +# Install icon and desktop file +install -Dpm 0644 package/fedora/%{name}.png %{buildroot}%{_datadir}/icons/hicolor/48x48/apps/%{name}.png +desktop-file-install --dir %{buildroot}/%{_datadir}/applications/ package/fedora/%{name}.desktop + +# Delete the doc folder, the files are in %%doc below +rm -rf %{buildroot}/%{_prefix}/doc + +# Install private headers +( +cd libsrc +find \( -name *.hpp -or -name *.hxx -or -name *.h -or -name *.ixx -or -name *.jxx \) -exec install -Dpm 0644 {} %{buildroot}%{_includedir}/%{name}/private/{} \; +) + +# Install the nglib.h header +install -Dpm 0644 nglib/nglib.h %{buildroot}%{_includedir}/%{name}/nglib.h + +%files common +%doc AUTHORS doc/ng4.pdf +%license LICENSE +%{_datadir}/%{name}/ +%{_datadir}/icons/hicolor/48x48/apps/%{name}.png +%{_datadir}/applications/%{name}.desktop + +%files +%{_bindir}/* + +%files libs +%{_libdir}/*.so.* + +%files devel +%{_includedir}/%{name} +%exclude %{_includedir}/%{name}/private +%{_libdir}/*.so +%{_libdir}/*.a +%{_libdir}/pkgconfig/%{name}.pc +%{_libdir}/cmake/%{name}/* + +%files devel-private +%{_includedir}/%{name}/private + +%files -n python3-%{name} +%{python3_sitearch}/pyngcore/ +%{python3_sitearch}/netgen/ + +%if %{build_openmpi} +%files openmpi +%{_libdir}/openmpi/bin/* + +%files openmpi-libs +%{_libdir}/openmpi/lib/*.so.* + +%files openmpi-devel +%{_includedir}/openmpi*/%{name} +%{_libdir}/openmpi/lib/*.so +%{_libdir}/openmpi/lib/*.a +%{_libdir}/openmpi/lib/pkgconfig/%{name}.pc +%{_libdir}/openmpi/lib/cmake/%{name}/* + +%files -n python3-%{name}-openmpi +%{_libdir}/openmpi/python%{python3_version}/site-packages/pyngcore/ +%{_libdir}/openmpi/python%{python3_version}/site-packages/netgen/ +%endif + +%if %{build_mpich} +%files mpich +%{_libdir}/mpich/bin/* + +%files mpich-libs +%{_libdir}/mpich/lib/*.so.* + +%files mpich-devel +%{_includedir}/mpich*/%{name} +%{_libdir}/mpich/lib/*.so +%{_libdir}/mpich/lib/*.a +%{_libdir}/mpich/lib/pkgconfig/%{name}.pc +%{_libdir}/mpich/lib/cmake/%{name}/* + +%files -n python3-%{name}-mpich +%{_libdir}/mpich/python%{python3_version}/site-packages/pyngcore/ +%{_libdir}/mpich/python%{python3_version}/site-packages/netgen/ +%endif + +%check +%define _vpath_builddir %{_target_platform} +export PYTHONPATH=.:%{buildroot}%{python3_sitearch} +#export LD_PRELOAD=libasan.so.6 +#export ASAN_OPTIONS=detect_odr_violation=0:detect_leaks=0 +%ctest +export PYTHONPATH=%{save_PYTHONPATH} +#export LD_PRELOAD=%{save_LD_PRELOAD} +#export ASAN_OPTIONS=${save_ASAN_OPTIONS} + +%changelog +* Fri Apr 08 2022 Monty - 6.2.dev-master +- Build ongoing fixes from master + +* Mon Mar 14 2022 Sandro Mani - 6.2.2202-1 +- Update to 6.2.2202 + +* Sat Mar 05 2022 Sandro Mani - 6.2.2201-1 +- Update to 6.2.2201 + +* Mon Jan 24 2022 Sandro Mani - 6.2.2105-3 +- Fix packaging of python files + +* Thu Jan 20 2022 Fedora Release Engineering - 6.2.2105-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Mon Oct 04 2021 Sandro Mani - 6.2.2105-1 +- Update to 6.2.2105 + +* Fri Sep 03 2021 Sandro Mani - 6.2.2104-1 +- Update to 6.2.2104 + +* Thu Jul 22 2021 Fedora Release Engineering - 6.2.2103-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Mon Jun 07 2021 Python Maint - 6.2.2103-2 +- Rebuilt for Python 3.10 + +* Mon Jun 07 2021 Sandro Mani - 6.2.2103-1 +- Update to 6.2.2103 + +* Fri Jun 04 2021 Python Maint - 6.2.2102-2 +- Rebuilt for Python 3.10 + +* Wed Mar 24 2021 Sandro Mani - 6.2.2102-1 +- Update to 6.2.2102 + +* Tue Jan 26 2021 Fedora Release Engineering - 6.2.2101-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Sun Jan 24 2021 Sandro Mani - 6.2.2101-1 +- Update to 6.2.2101 + +* Thu Nov 26 2020 Richard Shaw - 6.2.2009-2 +- Rebuild for OCC 7.5.0 side-tag. + +* Thu Nov 12 2020 Sandro Mani - 6.2.2009-1 +- Update to 6.2.2009 + +* Sun Nov 08 2020 Richard Shaw - 6.2.2008-2 +- Rebuild for OpenCASCADE 7.5.0. + +* Thu Sep 17 2020 Sandro Mani - 6.2.2008-1 +- Update to 6.2.2008 + +* Tue Jul 28 2020 Fedora Release Engineering - 6.2.2007-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu Jul 23 2020 Sandro Mani - 6.2.2007-1 +- Update to 6.2.2007 + +* Fri Jun 19 2020 Sandro Mani - 6.2.2006-1 +- Update to 6.2.2006 + +* Sun Jun 14 2020 Sandro Mani - 6.2.2005-1 +- Update to 6.2.2005 + +* Tue May 26 2020 Miro Hrončok - 6.2.2004-2 +- Rebuilt for Python 3.9 + +* Sat Apr 18 2020 Sandro Mani - 6.2.2004-1 +- Update to 6.2.2004 + +* Mon Feb 03 2020 Sandro Mani - 6.2.1910-1 +- Update to 6.2.1910 + +* Wed Jan 29 2020 Fedora Release Engineering - 6.2.1810-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + + +* Thu Oct 03 2019 Miro Hrončok - 6.2.1810-4 +- Rebuilt for Python 3.8.0rc1 (#1748018) + +* Mon Aug 19 2019 Miro Hrončok - 6.2.1810-3 +- Rebuilt for Python 3.8 + +* Thu Jul 25 2019 Fedora Release Engineering - 6.2.1810-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Jun 28 2019 Sandro Mani - 6.2.1810-1 +- Update to 6.2.1810 + +* Thu Feb 14 2019 Orion Poplawski - 6.2-0.9.git94fd571 +- Rebuild for openmpi 3.1.3 + +* Fri Feb 01 2019 Fedora Release Engineering - 6.2-0.8.git94fd571 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Fri Jul 13 2018 Fedora Release Engineering - 6.2-0.7.git94fd571 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jun 19 2018 Miro Hrončok - 6.2-0.6.git94fd571 +- Rebuilt for Python 3.7 + +* Wed May 02 2018 Sandro Mani - 6.2-0.5.git94fd571 +- Rename netgen binary at CMake level to prevent breaking cmake config module (#1573330) + +* Thu Feb 08 2018 Fedora Release Engineering - 6.2-0.4.git94fd571 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 6.2-0.3.git94fd571 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Thu May 11 2017 Sandro Mani - 6.2.0-0.2.git94fd571 +- Install the nglib.h header + +* Thu May 11 2017 Sandro Mani - 6.2.0-0.1.git94fd571 +- Update to 6.2.0 snapshot + +* Fri Feb 10 2017 Fedora Release Engineering - 5.3.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Oct 21 2016 Orion Poplawski - 5.3.1-12 +- Rebuild for openmpi 2.0 + +* Thu Apr 7 2016 Richard Shaw - 5.3.1-11 +- Rebuild for updated OCE. + +* Thu Feb 04 2016 Fedora Release Engineering - 5.3.1-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Sep 15 2015 Orion Poplawski - 5.3.1-9 +- Rebuild for openmpi 1.10.0 + +* Sat Aug 15 2015 Zbigniew Jędrzejewski-Szmek - 5.3.1-8 +- Rebuild for MPI provides + +* Sun Jul 26 2015 Sandro Mani - 5.3.1-7 +- Rebuild for RPM MPI Requires Provides Change + +* Wed Jun 17 2015 Fedora Release Engineering - 5.3.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat May 02 2015 Kalev Lember - 5.3.1-5 +- Rebuilt for GCC 5 C++11 ABI change + +* Thu Mar 12 2015 Sandro Mani - 5.3.1-4 +- Rebuild (GCC5 ABI change) + +* Sat Dec 13 2014 Sandro Mani - 5.3.1-3 +- Fix library in -devel package + +* Tue Oct 07 2014 Sandro Mani - 5.3.1-2 +- Fix soname, use -release instead of -version-info + +* Mon Oct 06 2014 Sandro Mani - 5.3.1-1 +- Update to 5.3.1 + +* Mon Sep 01 2014 Sandro Mani - 5.3.0-1 +- Update to 5.3.0 + +* Sun Aug 17 2014 Fedora Release Engineering - 5.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 29 2014 Sandro Mani - 5.1-10 +- Rebuild (OCE) + +* Thu Jun 19 2014 Sandro Mani - 5.1-9 +- Add missing mpich-devel BR + +* Thu Jun 19 2014 Sandro Mani - 5.1-8 +- Fix escaping of pkg-config variables + +* Sat Jun 14 2014 Sandro Mani - 5.1-7 +- Rename subpackage private -> devel-private + +* Sat Jun 14 2014 Sandro Mani - 5.1-6 +- Add netgen-5.1_relative-includes.patch + +* Sat Jun 14 2014 Sandro Mani - 5.1-5 +- Add subpackage for private headers +- Add patches from salome +- Make common package noarch +- Add missing %%{?_isa} + +* Fri Jun 13 2014 Sandro Mani - 5.1-4 +- Update netgen-5.1_build.patch +- Add netgen-5.1_msc-ver.patch + +* Thu Jun 12 2014 Sandro Mani - 5.1-3 +- Fix libgnlib soname + +* Thu Jun 12 2014 Sandro Mani - 5.1-2 +- Split off libraries in libs subpackages +- Rename shared libraries to less generic names + +* Thu Jun 12 2014 Sandro Mani - 5.1-1 +- Initial package diff --git a/package/fedora/netgen-mesher.desktop b/package/fedora/netgen-mesher.desktop new file mode 100644 index 000000000..e0a234155 --- /dev/null +++ b/package/fedora/netgen-mesher.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=Netgen +GenericName=Mesh Generator +Comment=3D finite element mesh generator +Exec=netgen-mesher +Icon=netgen-mesher +Type=Application +Terminal=false +Categories=Science;Engineering; diff --git a/package/fedora/netgen-mesher.png b/package/fedora/netgen-mesher.png new file mode 100644 index 000000000..9adbf7c8d Binary files /dev/null and b/package/fedora/netgen-mesher.png differ diff --git a/package/fedora/rpkg.conf b/package/fedora/rpkg.conf new file mode 100644 index 000000000..4cc144e0a --- /dev/null +++ b/package/fedora/rpkg.conf @@ -0,0 +1,3 @@ +[rpkg] +auto_pack = False +user_macros = "${git_props:root}/package/fedora/rpkg.macros" \ No newline at end of file diff --git a/package/fedora/rpkg.macros b/package/fedora/rpkg.macros new file mode 100644 index 000000000..7fca834cd --- /dev/null +++ b/package/fedora/rpkg.macros @@ -0,0 +1,15 @@ +function git_last_tag_raw { + git describe --tags --abbrev=0 +} + +function git_last_tag { + git_last_tag_raw | + sed -e 's/^[^0-9]*//g' | + sed -e 's/[.!@#$%^&*_+=-]*\(pre\|rc\|alpha\|beta\|test\)/~\1/g' | + sed -e 's/[!@#$%^&*_+=-]*\(post\|fix\|patch\|pl\|update\)/.\1/g' | + sed -e 's/[^A-Za-z0-9._~-]/_/g' +} + +function git_last_tag_commits { + echo -n $(git rev-list --count $(git_last_tag_raw)..HEAD) +} diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index b4f468663..6a2fd84e4 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -14,7 +14,7 @@ install(FILES meshing.py csg.py geom2d.py stl.py gui.py NgOCC.py occ.py read_gmsh.py read_meshio.py webgui.py - DESTINATION ${NG_INSTALL_DIR_PYTHON}/${NG_INSTALL_SUFFIX} + DESTINATION ${NG_INSTALL_DIR_PYTHON}/netgen COMPONENT netgen ) @@ -26,13 +26,15 @@ install(FILES # build stub files for pybind11 packages if(BUILD_STUB_FILES) -execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pybind11_stubgen; print(pybind11_stubgen.__file__)" OUTPUT_VARIABLE stubgen_path RESULT_VARIABLE pybind11_stubgen) -if(pybind11_stubgen AND NOT ${pybind11_stubgen} EQUAL 0) - message(WARNING "pybind11-stubgen not found, if you want to create stub files -for better autocompletion support install it with pip.") -else() - message("-- Found pybind11-stubgen: ${stubgen_path}") - install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pybind11_stubgen --no-setup-py netgen)") - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../stubs/netgen-stubs/ DESTINATION ${NG_INSTALL_DIR_PYTHON}/netgen/ COMPONENT netgen) -endif() + message(STATUS "Building Python stub files...") + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pybind11_stubgen; print(pybind11_stubgen.__file__)" OUTPUT_VARIABLE stubgen_path RESULT_VARIABLE pybind11_stubgen) + if(pybind11_stubgen AND NOT ${pybind11_stubgen} EQUAL 0) + message(WARNING "pybind11-stubgen not found. If you want to create stub files for better autocompletion support, + install pybind11-stubgen with pip.") + else() + message("-- Found pybind11-stubgen: ${stubgen_path}") + set(env{PYTHONPATH} ".:${CMAKE_INSTALL_PREFIX}/${PYTHON_PACKAGES_INSTALL_DIR}") + install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pybind11_stubgen -o ${CMAKE_BINARY_DIR}/stubs --no-setup-py netgen)") + install(DIRECTORY ${CMAKE_BINARY_DIR}/stubs/netgen-stubs/ DESTINATION ${NG_INSTALL_DIR_PYTHON}/netgen COMPONENT netgen) + endif() endif(BUILD_STUB_FILES) diff --git a/python/__init__.py b/python/__init__.py index ed61a3207..91d48fd6b 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -2,8 +2,8 @@ import sys from . import config -_netgen_bin_dir=os.path.realpath(os.path.join(os.path.dirname(__file__),'..',config.NETGEN_PYTHON_RPATH_BIN)) -_netgen_lib_dir=os.path.realpath(os.path.join(os.path.dirname(__file__),'..',config.NETGEN_PYTHON_RPATH)) +_netgen_bin_dir=os.path.realpath(os.path.join(config.NG_INSTALL_DIR_PYTHON,config.NETGEN_PYTHON_RPATH_BIN)) +_netgen_lib_dir=os.path.realpath(os.path.join(config.NG_INSTALL_DIR_PYTHON,config.NETGEN_PYTHON_RPATH)) if sys.platform.startswith('win'): if sys.version >= '3.8': diff --git a/setup.py b/setup.py index 0ed33a6dc..e6b48cfc3 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ def _patched_parse_manifests(self): py_install_dir = get_python_lib(1,0,'').replace('\\','/') -name = "netgen-mesher" +name = "netgen" arch = None cmake_args = [ f'-DNETGEN_VERSION_GIT={git_version}', diff --git a/tests/pytest/CMakeLists.txt b/tests/pytest/CMakeLists.txt index 26c7d22fe..4f7e1c5bb 100644 --- a/tests/pytest/CMakeLists.txt +++ b/tests/pytest/CMakeLists.txt @@ -1,8 +1,28 @@ if(USE_PYTHON) - add_test(NAME pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - add_custom_target(pytest ${PYTHON_EXECUTABLE} -m pytest WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - set_tests_properties ( pytest PROPERTIES TIMEOUT 1800 ) - if(USE_MPI AND USE_MPI4PY) - add_test(NAME pytest-mpi COMMAND ${MPIEXEC_EXECUTABLE} --allow-run-as-root -np 4 ${PYTHON_EXECUTABLE} -m pytest --with-mpi test_mpi4py.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - endif(USE_MPI AND USE_MPI4PY) + if(ENABLE_UNIT_TESTS) + set(PYTHON_UNIT_TESTS TRUE) + # check for prerequisite modules + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pytest; print(pytest.__file__)" + OUTPUT_VARIABLE pytest_path RESULT_VARIABLE pytest_result) + if(NOT ${pytest_result} EQUAL 0) + message(WARNING "python module 'pytest' not found.") + set(PYTHON_UNIT_TESTS FALSE) + endif() + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pytest_check; print(pytest_check.__file__)" + OUTPUT_VARIABLE pycheck_path RESULT_VARIABLE pycheck_result) + if(NOT ${pytest_result} EQUAL 0) + message(WARNING "python module 'pytest_check' not found.") + set(PYTHON_UNIT_TESTS FALSE) + endif() + if(PYTHON_UNIT_TESTS) + add_test(NAME pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + add_custom_target(pytest ${PYTHON_EXECUTABLE} -m pytest WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_tests_properties ( pytest PROPERTIES TIMEOUT 18000 ) + if(USE_MPI AND USE_MPI4PY) + add_test(NAME pytest-mpi COMMAND ${MPIEXEC_EXECUTABLE} --allow-run-as-root -np 4 ${PYTHON_EXECUTABLE} -m pytest --with-mpi test_mpi4py.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + endif(USE_MPI AND USE_MPI4PY) + else() + message(WARNING "Unable to perform unit tests on netgen python modules.") + endif() + endif() endif(USE_PYTHON)