diff --git a/CMake/coreneuron-config.cmake.in b/CMake/coreneuron-config.cmake.in index c34993977..29f67c92f 100644 --- a/CMake/coreneuron-config.cmake.in +++ b/CMake/coreneuron-config.cmake.in @@ -1,5 +1,5 @@ # ============================================================================= -# Copyright (C) 2016-2021 Blue Brain Project +# Copyright (C) 2016-2022 Blue Brain Project # # See top-level LICENSE file for details. # ============================================================================= @@ -8,6 +8,9 @@ get_filename_component(CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH) +set(CORENRN_VERSION_MAJOR @PROJECT_VERSION_MAJOR@) +set(CORENRN_VERSION_MINOR @PROJECT_VERSION_MINOR@) +set(CORENRN_VERSION_PATCH @PROJECT_VERSION_PATCH@) set(CORENRN_ENABLE_GPU @CORENRN_ENABLE_GPU@) set(CORENRN_ENABLE_NMODL @CORENRN_ENABLE_NMODL@) set(CORENRN_ENABLE_REPORTING @CORENRN_ENABLE_REPORTING@) diff --git a/CMakeLists.txt b/CMakeLists.txt index 677bef690..e0ab6ee7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,13 @@ # See top-level LICENSE file for details. # ============================================================================= cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +# CoreNEURON's version jumped from 1.0 to 8.2.0 with the introduction of the NRN_VERSION_* macros +# for use in VERBATIM blocks. Starting from this version, the NEURON and CoreNEURON versions are +# locked together. A version has to be hardcoded here to handle the case that CoreNEURON is built +# standalone. project( coreneuron - VERSION 1.0 + VERSION 8.2.0 LANGUAGES CXX) # ~~~ @@ -36,11 +40,40 @@ endif() # ============================================================================= # Settings to enable project as submodule # ============================================================================= +set(CORENEURON_PROJECT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(CORENEURON_PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(CORENEURON_AS_SUBPROJECT OFF) if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(CORENEURON_AS_SUBPROJECT ON) -endif() + # Make these visible to the parent project (NEURON) so it can do some sanity checking. + set_property(GLOBAL PROPERTY CORENRN_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) + set_property(GLOBAL PROPERTY CORENRN_VERSION_MINOR ${PROJECT_VERSION_MINOR}) + set_property(GLOBAL PROPERTY CORENRN_VERSION_PATCH ${PROJECT_VERSION_PATCH}) +endif() +if(NOT DEFINED NRN_VERSION_MAJOR + OR NOT DEFINED NRN_VERSION_MINOR + OR NOT DEFINED NRN_VERSION_PATCH) + if(CORENEURON_AS_SUBPROJECT) + set(level WARNING) + else() + set(level STATUS) + endif() + # Typically in this case CoreNEURON is being built standalone. In this case NRN_VERSION_* macros + # resolve to the CoreNEURON version, which is supposed to be moving in lockstep with the NEURON + # version. + set(NRN_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) + set(NRN_VERSION_MINOR ${PROJECT_VERSION_MINOR}) + set(NRN_VERSION_PATCH ${PROJECT_VERSION_PATCH}) + message(${level} "CoreNEURON could not determine the NEURON version, using the hardcoded " + "${NRN_VERSION_MAJOR}.${NRN_VERSION_MINOR}.${NRN_VERSION_PATCH}") +endif() +# Regardless of whether we are being built as a submodule of NEURON, NRN_VERSION_{MAJOR,MINOR,PATCH} +# are now set to the version that we should claim compatibility with when compiling translated MOD +# files. Generate a header under a special `generated` prefix in the build directory, so that +# -I/path/to/src -I/path/to/build/generated is safe (headers from the source prefix are copied +# elsewhere under the build prefix, so there is scope for confusion) +configure_file(coreneuron/config/neuron_version.hpp.in + generated/coreneuron/config/neuron_version.hpp) # ============================================================================= # Include cmake modules path diff --git a/coreneuron/CMakeLists.txt b/coreneuron/CMakeLists.txt index ffbd7fa45..55f5b9a5e 100644 --- a/coreneuron/CMakeLists.txt +++ b/coreneuron/CMakeLists.txt @@ -187,9 +187,8 @@ set(CORENRN_MPI_LIB_NAME if(CORENRN_ENABLE_MPI AND NOT CORENRN_ENABLE_MPI_DYNAMIC) add_library(${CORENRN_MPI_LIB_NAME} OBJECT ${MPI_LIB_FILES}) target_include_directories( - ${CORENRN_MPI_LIB_NAME} - PRIVATE ${MPI_INCLUDE_PATH} - PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR}) + ${CORENRN_MPI_LIB_NAME} PRIVATE ${MPI_INCLUDE_PATH} ${CORENEURON_PROJECT_SOURCE_DIR} + ${CORENEURON_PROJECT_BINARY_DIR}/generated) set_property(TARGET ${CORENRN_MPI_LIB_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) set(CORENRN_MPI_OBJ $) endif() @@ -206,7 +205,8 @@ add_library( ${MPI_CORE_FILES} ${CORENRN_MPI_OBJ}) -target_include_directories(coreneuron PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR}) +target_include_directories(coreneuron PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR} + ${CORENEURON_PROJECT_BINARY_DIR}/generated) # we can link to MPI libraries in non-dynamic-mpi build if(CORENRN_ENABLE_MPI AND NOT CORENRN_ENABLE_MPI_DYNAMIC) target_link_libraries(coreneuron ${MPI_CXX_LIBRARIES}) @@ -234,9 +234,8 @@ if(CORENRN_ENABLE_MPI AND CORENRN_ENABLE_MPI_DYNAMIC) add_library(${CORENRN_MPI_LIB_NAME} SHARED ${MPI_LIB_FILES}) target_link_libraries(${CORENRN_MPI_LIB_NAME} ${MPI_CXX_LIBRARIES}) target_include_directories( - ${CORENRN_MPI_LIB_NAME} - PRIVATE ${MPI_INCLUDE_PATH} - PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR}) + ${CORENRN_MPI_LIB_NAME} PRIVATE ${MPI_INCLUDE_PATH} ${CORENEURON_PROJECT_SOURCE_DIR} + ${CORENEURON_PROJECT_BINARY_DIR}/generated) set_property(TARGET ${CORENRN_MPI_LIB_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) list(APPEND corenrn_mpi_targets ${CORENRN_MPI_LIB_NAME}) else() @@ -259,7 +258,7 @@ if(CORENRN_ENABLE_MPI AND CORENRN_ENABLE_MPI_DYNAMIC) target_include_directories( core${libname}_lib PUBLIC ${include} - PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR}) + PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR} ${CORENEURON_PROJECT_BINARY_DIR}/generated) # ~~~ # TODO: somehow mingw requires explicit linking. This needs to be verified @@ -295,7 +294,8 @@ add_dependencies(coreneuron kin_deriv_header nrnivmodl-core) # scopmath is created separately for nrnivmodl-core workflow add_library(scopmath STATIC ${CORENEURON_HEADER_FILES} ${SCOPMATH_CODE_FILES}) -target_include_directories(scopmath PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR}) +target_include_directories(scopmath PRIVATE ${CORENEURON_PROJECT_SOURCE_DIR} + ${CORENEURON_PROJECT_BINARY_DIR}/generated) target_link_libraries(coreneuron ${reportinglib_LIBRARY} ${sonatareport_LIBRARY} ${CALIPER_LIB} ${likwid_LIBRARIES}) @@ -374,6 +374,8 @@ file( RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.h *.hpp *.ispc) +configure_file("${CORENEURON_PROJECT_BINARY_DIR}/generated/coreneuron/config/neuron_version.hpp" + "${CMAKE_BINARY_DIR}/include/coreneuron/config/neuron_version.hpp" COPYONLY) foreach(header ${main_headers}) configure_file("${header}" "${CMAKE_BINARY_DIR}/include/coreneuron/${header}" COPYONLY) endforeach() diff --git a/coreneuron/config/neuron_version.hpp.in b/coreneuron/config/neuron_version.hpp.in new file mode 100644 index 000000000..cedb514af --- /dev/null +++ b/coreneuron/config/neuron_version.hpp.in @@ -0,0 +1,14 @@ +/* +# ============================================================================= +# Copyright (c) 2022 Blue Brain Project/EPFL +# +# See top-level LICENSE file for details. +# ============================================================================= +*/ +#pragma once + +// This is the CoreNEURON analogue of nrnsemanticversion.h in NEURON. Hopefully +// the duplication can go away soon. +#define NRN_VERSION_MAJOR @NRN_VERSION_MAJOR@ +#define NRN_VERSION_MINOR @NRN_VERSION_MINOR@ +#define NRN_VERSION_PATCH @NRN_VERSION_PATCH@ diff --git a/coreneuron/config/version_macros.hpp b/coreneuron/config/version_macros.hpp new file mode 100644 index 000000000..8aa2cab65 --- /dev/null +++ b/coreneuron/config/version_macros.hpp @@ -0,0 +1,29 @@ +/* +# ============================================================================= +# Copyright (c) 2022 Blue Brain Project/EPFL +# +# See top-level LICENSE file for details. +# ============================================================================= +*/ +#pragma once + +// This is the CoreNEURON analogue of nrnversionmacros.h in NEURON. Hopefully +// the duplication can go away soon. +#include "coreneuron/config/neuron_version.hpp" +#define NRN_VERSION_INT(maj, min, pat) (10000 * maj + 100 * min + pat) +#define NRN_VERSION NRN_VERSION_INT(NRN_VERSION_MAJOR, NRN_VERSION_MINOR, NRN_VERSION_PATCH) +#define NRN_VERSION_EQ(maj, min, pat) (NRN_VERSION == NRN_VERSION_INT(maj, min, pat)) +#define NRN_VERSION_NE(maj, min, pat) (NRN_VERSION != NRN_VERSION_INT(maj, min, pat)) +#define NRN_VERSION_GT(maj, min, pat) (NRN_VERSION > NRN_VERSION_INT(maj, min, pat)) +#define NRN_VERSION_LT(maj, min, pat) (NRN_VERSION < NRN_VERSION_INT(maj, min, pat)) +#define NRN_VERSION_GTEQ(maj, min, pat) (NRN_VERSION >= NRN_VERSION_INT(maj, min, pat)) +#define NRN_VERSION_LTEQ(maj, min, pat) (NRN_VERSION <= NRN_VERSION_INT(maj, min, pat)) + +// 8.2.0 is significant because all versions >=8.2.0 should contain definitions +// of these macros, and doing #ifndef NRN_VERSION_GTEQ_8_2_0 is a more +// descriptive way of writing #if defined(NRN_VERSION_GTEQ). Testing for 8.2.0 +// is likely to be a common pattern when adapting MOD file VERBATIM blocks for +// C++ compatibility. +#if NRN_VERSION_GTEQ(8, 2, 0) +#define NRN_VERSION_GTEQ_8_2_0 +#endif diff --git a/coreneuron/nrnconf.h b/coreneuron/nrnconf.h index 1135846ed..b25a2764a 100644 --- a/coreneuron/nrnconf.h +++ b/coreneuron/nrnconf.h @@ -1,13 +1,13 @@ /* # ============================================================================= -# Copyright (c) 2016 - 2021 Blue Brain Project/EPFL +# Copyright (c) 2016 - 2022 Blue Brain Project/EPFL # # See top-level LICENSE file for details. # =============================================================================. */ - #pragma once +#include "coreneuron/config/version_macros.hpp" #include "coreneuron/utils/offload.hpp" #include diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2fc45cb7c..3d6b212fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,7 +6,8 @@ include(TestHelpers) -include_directories(${CORENEURON_PROJECT_SOURCE_DIR} ${Boost_INCLUDE_DIRS}) +include_directories(${CORENEURON_PROJECT_SOURCE_DIR} ${CORENEURON_PROJECT_BINARY_DIR}/generated + ${Boost_INCLUDE_DIRS}) if(NOT Boost_USE_STATIC_LIBS) add_definitions(-DBOOST_TEST_DYN_LINK=TRUE)