Skip to content
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

Wheels #59

Draft
wants to merge 20 commits into
base: new-pynest
Choose a base branch
from
Draft
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ conda/
_build/
install/
reports/
_skbuild/
*.egg-info/
wheelhouse/

# compilation artefacts
pynest/pynestkernel.cxx
Expand Down Expand Up @@ -36,7 +39,6 @@ bin/nest-config
bin/nest_vars.sh
libnestutil/config.h
nest/static_modules.h
pynest/setup.py

# installation artefacts
install_manifest.txt
Expand Down
38 changes: 15 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ project( nest CXX C )

set( CMAKE_CXX_STANDARD 20 )
set( CMAKE_CXX_STANDARD_REQUIRED True )
set( NEST_WHEELBUILD DEFINED ENV{NEST_CMAKE_BUILDWHEEL} )
if ( NEST_WHEELBUILD )
# Big warning that the wheel build reserves the right to destroy everything, as it
# should only run on throwaway containers.
message(WARNING "RUNNING WHEEL BUILD, DO NOT RUN ON LOCAL MACHINE, MAY CAUSE IRREVERSIBLE CHANGES!")
endif ()
if ( with-openmp )
if ( "${with-openmp}" STREQUAL "ON" )
# This should be called from cmake/ProcessOptions.cmake:NEST_PROCESS_WITH_OPENMP
# but alas, on some unknown combination of newer versions not all compiler flags are
# found there, yet magically, are correctly found when we make the call here.
find_package( OpenMP REQUIRED )
endif ()
endif ()

set( NEST_USER_EMAIL "users@nest-simulator.org" )

Expand Down Expand Up @@ -132,6 +146,7 @@ get_target_triple( NEST_TARGET_TRIPLE NEST_TARGET_ARCH NEST_TARGET_VENDOR NEST_T
nest_process_with_python()
include( GNUInstallDirs )
nest_post_process_with_python()
message( STATUS "DID WE FIND UTILITY_PYTHON? ${UTILITY_PYTHON}")
nest_process_with_intel_compiler_flags()
nest_process_with_warning()
nest_process_with_libraries()
Expand Down Expand Up @@ -222,15 +237,12 @@ add_custom_target( installcheck
################## Define Subdirectories here ##################
################################################################################

add_subdirectory( doc )
add_subdirectory( bin )
add_subdirectory( examples )
add_subdirectory( build_support )
add_subdirectory( libnestutil )
add_subdirectory( models )
add_subdirectory( nestkernel )
add_subdirectory( thirdparty )
add_subdirectory( testsuite )
if ( HAVE_PYTHON )
add_subdirectory( pynest )
endif ()
Expand Down Expand Up @@ -320,11 +332,6 @@ configure_file(
"${PROJECT_BINARY_DIR}/libnestutil/config.h" @ONLY
)

configure_file(
"${PROJECT_SOURCE_DIR}/pynest/setup.py.in"
"${PROJECT_BINARY_DIR}/pynest/setup.py" @ONLY
)

configure_file(
"${PROJECT_SOURCE_DIR}/bin/nest-config.in"
"${PROJECT_BINARY_DIR}/bin/nest-config" @ONLY
Expand All @@ -335,17 +342,6 @@ configure_file(
"${PROJECT_BINARY_DIR}/bin/nest_vars.sh" @ONLY
)

configure_file(
"${PROJECT_SOURCE_DIR}/doc/fulldoc.conf.in"
"${PROJECT_BINARY_DIR}/doc/fulldoc.conf" @ONLY
)

configure_file(
"${PROJECT_SOURCE_DIR}/pynest/nest/versionchecker.py.in"
"${PROJECT_BINARY_DIR}/pynest/nest/versionchecker.py" @ONLY
)


################################################################################
################## Install Extra Files ##################
################################################################################
Expand All @@ -354,8 +350,4 @@ install( FILES LICENSE README.md
DESTINATION ${CMAKE_INSTALL_DOCDIR}
)

install( DIRECTORY examples/
DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples
)

nest_print_config_summary()
92 changes: 92 additions & 0 deletions build_support/prepare_wheel_container.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import subprocess
import os

# This file exists as a Python script because running a Linux docker on Windows CI
# runners messes with the keyboard mapping of bash commands which affects symbols like
# -?/\ and makes writing commands impossible. Somehow, if we use .py files instead of
# .sh files, we can shell out from here with correct keyboard mapping.

BOOST_VERSION = [1, 79, 0]
GSL_VERSION = [2, 7, 1]


def main():
print("Installing libgomp...")
install_omp()
print("Done.")
# Containers run multiple builds, so check if a previous build has installed the
# dependency already
if not os.path.exists("/boost"):
print(f"Installing Boost {version(BOOST_VERSION)}...")
install_boost()
print("Done.")
if not os.path.exists("/gsl"):
print(f"Installing GSL {version(BOOST_VERSION)}...")
install_gsl()
print("Done.")
strip_wheel_bulk()
print("Container preparation complete.")
print()


def run_sequence(seq):
"""Run a sequence of shell commands"""
for command in seq:
subprocess.run(command, shell=True, check=True)


def version(ver, delim="."):
"""Format list of semver parts into a string"""
return delim.join(str(v) for v in ver)


def install_boost():
"""Download, unpack, and move Boost to `/boost`"""
boost_ver = version(BOOST_VERSION)
boost_ver_uscore = version(BOOST_VERSION, delim="_")
install_seq = (
(
"curl -L https://boostorg.jfrog.io/artifactory/main/release/"
+ f"{boost_ver}/source/boost_{boost_ver_uscore}.tar.gz"
+ " -o boost.tar.gz"
),
"tar -xzf boost.tar.gz",
f"mv boost_{boost_ver_uscore} /boost",
)
run_sequence(install_seq)


def install_gsl():
"""Download, unpack, configure and make install GSL to `/gsl`"""
gsl_ver = version(GSL_VERSION)
install_seq = (
f"curl -L https://mirror.ibcp.fr/pub/gnu/gsl/gsl-{gsl_ver}.tar.gz -o gsl.tar.gz",
"tar -xzf gsl.tar.gz",
"mkdir /gsl",
f"cd gsl-{gsl_ver} && ./configure --prefix=/gsl && make && make install",
)
run_sequence(install_seq)


def install_omp():
"""Use the yum package manager of CentOS to install OpemMP libraries"""
install_seq = ("yum install libgomp",)
run_sequence(install_seq)


def strip_wheel_bulk():
from shutil import rmtree, move
from os import makedirs

move("/project/doc/copyright_header.cpp", "/project")
move("/project/doc/copyright_header.py", "/project")

rmtree("/project/doc")
rmtree("/project/examples")
makedirs("/project/doc")

move("/project/copyright_header.cpp", "/project/doc")
move("/project/copyright_header.py", "/project/doc")


main()
6 changes: 4 additions & 2 deletions cmake/CheckExtraCompilerFeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ function( NEST_CHECK_EXITCODE_ABORT )
RESULT_VARIABLE RETURN_VALUE
ERROR_QUIET OUTPUT_QUIET
)
set( RETURN_VALUE 255 )
if ( NOT RETURN_VALUE EQUAL 0 )
set( ABORT_ERR ${RETURN_VALUE} )
endif ()
Expand All @@ -50,7 +51,7 @@ function( NEST_CHECK_EXITCODE_ABORT )
endif ()
endif ()
printInfo( "Check the abort exitcode. ${ABORT_ERR}" )
set( NEST_EXITCODE_ABORT ${ABORT_ERR} PARENT_SCOPE )
set( NEST_EXITCODE_ABORT 255 PARENT_SCOPE )
endfunction()

####### NEST_EXITCODE_SEGFAULT ########
Expand All @@ -70,6 +71,7 @@ function( NEST_CHECK_EXITCODE_SEGFAULT )
RESULT_VARIABLE RETURN_VALUE
ERROR_QUIET OUTPUT_QUIET
)
set( SEG_ERR 255 )
if ( NOT RETURN_VALUE EQUAL 0 )
set( SEG_ERR ${RETURN_VALUE} )
endif ()
Expand All @@ -78,7 +80,7 @@ function( NEST_CHECK_EXITCODE_SEGFAULT )
endif ()
endif ()
printInfo( "Check the segmentation fault exitcode. ${SEG_ERR}" )
set( NEST_EXITCODE_SEGFAULT ${SEG_ERR} PARENT_SCOPE )
set( NEST_EXITCODE_SEGFAULT 255 PARENT_SCOPE )
endfunction()

####### HAVE_CMATH_MAKROS_IGNORED ########
Expand Down
111 changes: 64 additions & 47 deletions cmake/FindCython.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
# Find the Cython compiler.
#.rst:
#
# This code sets the following variables:
# Find ``cython`` executable.
#
# CYTHON_EXECUTABLE
# This module will set the following variables in your project:
#
# ``CYTHON_EXECUTABLE``
# path to the ``cython`` program
#
# ``CYTHON_VERSION``
# version of ``cython``
#
# ``CYTHON_FOUND``
# true if the program was found
#
# For more information on the Cython project, see https://cython.org/.
#
# *Cython is a language that makes writing C extensions for the Python language
# as easy as Python itself.*
#
# See also UseCython.cmake

#=============================================================================
# Copyright 2011 Kitware, Inc.
#
Expand All @@ -22,51 +34,56 @@
# limitations under the License.
#=============================================================================

# Modifications copyright (C) 2004 The NEST Initiative

# Using the Cython executable that lives next to the Python executable
# Use the Cython executable that lives next to the Python executable
# if it is a local installation.
if ( Python_FOUND )
get_filename_component( _python_path ${Python_EXECUTABLE} PATH )
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
HINTS ${_python_path}
)
else ()
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
)
endif ()
if(Python_EXECUTABLE)
get_filename_component(_python_path ${Python_EXECUTABLE} PATH)
elseif(Python3_EXECUTABLE)
get_filename_component(_python_path ${Python3_EXECUTABLE} PATH)
elseif(DEFINED PYTHON_EXECUTABLE)
get_filename_component(_python_path ${PYTHON_EXECUTABLE} PATH)
endif()

if(DEFINED _python_path)
find_program(CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
HINTS ${_python_path}
DOC "path to the cython executable")
else()
find_program(CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
DOC "path to the cython executable")
endif()

if(CYTHON_EXECUTABLE)
set(CYTHON_version_command "${CYTHON_EXECUTABLE} --version")

execute_process(COMMAND ${CYTHON_EXECUTABLE} --version
OUTPUT_VARIABLE CYTHON_version_output
ERROR_VARIABLE CYTHON_version_error
RESULT_VARIABLE CYTHON_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE)

if ( NOT CYTHON_EXECUTABLE STREQUAL "CYTHON_EXECUTABLE-NOTFOUND" )
execute_process(
COMMAND ${CYTHON_EXECUTABLE} --version
RESULT_VARIABLE RESULT
OUTPUT_VARIABLE CYTHON_VAR_OUTPUT
ERROR_VARIABLE CYTHON_ERR_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if ( RESULT EQUAL 0 )
if ( "${CYTHON_VAR_OUTPUT}" STREQUAL "" )
# In cython v0.29.3 the version string is written to stderr and not to stdout, as one would expect.
set( CYTHON_VAR_OUTPUT "${CYTHON_ERR_OUTPUT}" )
if(NOT ${CYTHON_version_result} EQUAL 0)
cmake_path(GET CYTHON_EXECUTABLE PARENT_PATH result)
set(_error_msg "Command \"${CYTHON_version_command}\" failed with")
set(_error_msg "${_error_msg} output:\n${CYTHON_version_error}${CYTHON_version_result}${CYTHON_version_output}")
message(SEND_ERROR "${_error_msg}")
else()
if("${CYTHON_version_output}" MATCHES "^[Cc]ython version ([^,]+)")
set(CYTHON_VERSION "${CMAKE_MATCH_1}")
else()
if("${CYTHON_version_error}" MATCHES "^[Cc]ython version ([^,]+)")
set(CYTHON_VERSION "${CMAKE_MATCH_1}")
endif()
endif()
string( REGEX REPLACE ".* ([0-9]+\\.[0-9]+(\\.[0-9]+)?).*" "\\1"
CYTHON_VERSION "${CYTHON_VAR_OUTPUT}" )
else ()
printError( "Cython error: ${CYTHON_ERR_OUTPUT}\nat ${CYTHON_EXECUTABLE}")
endif ()
endif()
endif()

endif ()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cython REQUIRED_VARS CYTHON_EXECUTABLE)

include( FindPackageHandleStandardArgs )
find_package_handle_standard_args( Cython
FOUND_VAR
CYTHON_FOUND
REQUIRED_VARS
CYTHON_EXECUTABLE
VERSION_VAR
CYTHON_VERSION
)
mark_as_advanced(CYTHON_EXECUTABLE)

mark_as_advanced( CYTHON_EXECUTABLE )
include(UseCython)
Loading
Loading