From 744864a80e4a31c8233e209c32a37e4fca9f9485 Mon Sep 17 00:00:00 2001 From: Matthias Wolf Date: Sat, 17 Feb 2024 20:10:00 +0100 Subject: [PATCH 01/63] cmake: export targets, allow to build models via CMake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR aims to allow dependent projects to build their models via CMake rather than a combination of shell scripts and Makefiles. In the long term, this may help facilitate building natively on Windows. To try: ``` git clone -b imported-main https://github.com/BlueBrain/neurodamus-models.git cd neurodamus-models ``` Create a `CMakeLists.txt` with contents like: ```cmake cmake_minimum_required(VERSION 3.28) project(newrodamus) find_package(neuron REQUIRED) create_libnrnmech(MOD_FILES neocortex/mod/v6/CaDynamics_DC0.mod neocortex/mod/v6/Ca_HVA2.mod neocortex/mod/v6/Ca_LVAst.mod neocortex/mod/v6/DetAMPANMDA.mod neocortex/mod/v6/DetGABAAB.mod neocortex/mod/v6/GluSynapse.mod neocortex/mod/v6/Ih.mod neocortex/mod/v6/K_Pst.mod neocortex/mod/v6/K_Tst.mod neocortex/mod/v6/KdShu2007.mod neocortex/mod/v6/NaTg.mod neocortex/mod/v6/Nap_Et2.mod neocortex/mod/v6/ProbAMPANMDA_EMS.mod neocortex/mod/v6/ProbGABAAB_EMS.mod neocortex/mod/v6/SK_E2.mod neocortex/mod/v6/SKv3_1.mod neocortex/mod/v6/StochKv3.mod neocortex/mod/v6/TTXDynamicsSwitch.mod neocortex/mod/v6/VecStim.mod neocortex/mod/v6/gap.mod neocortex/mod/v6/netstim_inhpoisson.mod ) ``` Then build and install: ``` cmake -B build -S . -GNinja -DCMAKE_INSTALL_PREFIX=x86_64 cmake --build build cmake --install build ``` To be continued  --- CMakeLists.txt | 22 ++++++ cmake/mod_reg_corenrn.cpp.in | 16 +++++ cmake/mod_reg_nrn.cpp.in | 16 +++++ cmake/neuronConfig.cmake.in | 25 +++++++ cmake/neuronMechMaker.cmake | 131 ++++++++++++++++++++++++++++++++++ src/coreneuron/CMakeLists.txt | 15 ++++ src/ivoc/nrnmain.cpp | 2 +- src/nrniv/CMakeLists.txt | 47 ++++++------ src/nrnoc/hh.mod | 4 +- src/nrnpython/CMakeLists.txt | 4 ++ 10 files changed, 258 insertions(+), 24 deletions(-) create mode 100644 cmake/mod_reg_corenrn.cpp.in create mode 100644 cmake/mod_reg_nrn.cpp.in create mode 100644 cmake/neuronConfig.cmake.in create mode 100644 cmake/neuronMechMaker.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b74dbc9a4..1b0735c166 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -495,6 +495,9 @@ endif() # initialize CLI11 submodule cpp_cc_git_submodule(CLI11 BUILD PACKAGE CLI11 REQUIRED) +# coreneuron targets will get propagated down from the subdirectory +set(NRN_INSTALL_TARGETS nrniv_lib nocmodl) + # ============================================================================= # Enable CoreNEURON support # ============================================================================= @@ -904,6 +907,25 @@ if(NRN_MACOS_BUILD) nrn_macos_after_install() endif() +# ============================================================================= +# Install CMake glue +# ============================================================================= +install(TARGETS ${NRN_INSTALL_TARGETS} ${CORENRN_INSTALL_TARGETS} EXPORT NeuronTargets) +install( + EXPORT NeuronTargets + FILE neuronTargets.cmake + NAMESPACE neuron:: + DESTINATION lib/cmake/neuron) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/neuronConfig.cmake @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/neuronConfig.cmake DESTINATION lib/cmake/neuron) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake DESTINATION lib/cmake/neuron) + +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_nrn.cpp.in + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_corenrn.cpp.in DESTINATION share/nrn) + # ============================================================================= # Copy bash executable for windows # ============================================================================= diff --git a/cmake/mod_reg_corenrn.cpp.in b/cmake/mod_reg_corenrn.cpp.in new file mode 100644 index 0000000000..ff71d4e6c8 --- /dev/null +++ b/cmake/mod_reg_corenrn.cpp.in @@ -0,0 +1,16 @@ +#include +namespace coreneuron { +extern int nrnmpi_myid; +extern int nrn_nobanner_; + +@MECH_DECLARE@ + +void modl_reg() { + if (!nrn_nobanner_) if (nrnmpi_myid < 1) { + fprintf(stderr, " Additional mechanisms from files\n"); + @MECH_PRINT@ + fprintf(stderr, "\n\n"); + } + @MECH_REGISTRE@ +} +} //namespace coreneuron diff --git a/cmake/mod_reg_nrn.cpp.in b/cmake/mod_reg_nrn.cpp.in new file mode 100644 index 0000000000..ae9fda03d4 --- /dev/null +++ b/cmake/mod_reg_nrn.cpp.in @@ -0,0 +1,16 @@ +#include +#include "hocdec.h" +extern int nrnmpi_myid; +extern int nrn_nobanner_; + +@MECH_DECLARE@ + +extern "C" void modl_reg() { + if (!nrn_nobanner_) if (nrnmpi_myid < 1) { + fprintf(stderr, "Additional mechanisms from files\n"); + @MECH_PRINT@ + fprintf(stderr, "\n"); + } + @MECH_REGISTRE@ +} + diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in new file mode 100644 index 0000000000..2375f0d608 --- /dev/null +++ b/cmake/neuronConfig.cmake.in @@ -0,0 +1,25 @@ +include(CMakeFindDependencyMacro) + +find_dependency(Threads) + +include("${CMAKE_CURRENT_LIST_DIR}/neuronTargets.cmake") + +get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(_prefix "${_dir}/../../.." ABSOLUTE) + +set(NRN_ENABLE_CORENEURON @NRN_ENABLE_CORENEURON@) + +set(_NEURON_MAIN "${_prefix}/share/nrn/nrnmain.cpp") +set(_NEURON_MAIN_INCLUDE_DIR "${_prefix}/include/nrncvode") +set(_NEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_nrn.cpp.in") + +set(_CORENEURON_BASE_MOD "${_prefix}/share/modfile") +set(_CORENEURON_MAIN "${_prefix}/share/coreneuron/coreneuron.cpp") +set(_CORENEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_corenrn.cpp.in") +set(_CORENEURON_MECH_ENG "${_prefix}/share/coreneuron/enginemech.cpp") +set(_CORENEURON_RANDOM_INCLUDE "${_prefix}/include/coreneuron/utils/randoms") +set(_CORENEURON_FLAGS @CORENRN_CXX_FLAGS@) + +find_program(NMODL nmodl REQUIRED) + +include(${CMAKE_CURRENT_LIST_DIR}/neuronMechMaker.cmake) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake new file mode 100644 index 0000000000..a0897eb41a --- /dev/null +++ b/cmake/neuronMechMaker.cmake @@ -0,0 +1,131 @@ +# ~~~ +# +function(create_nrnmech) + set(options CORENEURON INSTALL_CPP INSTALL_MOD SPECIAL) + set(oneValueArgs MECHANISM_NAME) + cmake_parse_arguments(NRN_MECH "${options}" "${oneValueArgs}" "MOD_FILES" ${ARGN}) + + if(NRN_MECH_CORENEURON) + if(NOT NRN_ENABLE_CORENEURON) + message(FATAL_ERROR "CoreNEURON support not enabled") + endif() + endif() + + if(NOT MECHANISM_NAME) + set(MECHANISM_NAME neuron) + endif() + + set(LIBNAME "nrnmech") + set(EXENAME "special") + + foreach(MOD_FILE IN LISTS NRN_MECH_MOD_FILES) + get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + list(APPEND INPUT_STUBS "${MOD_STUB}") + list(APPEND MOD_FILES "${MOD_FILE}") + endforeach() + + foreach(MOD_FILE IN LISTS MOD_FILES) + get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + set(CPP_FILE "cpp/${MOD_STUB}.cpp") + file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_FILE}") + + list(APPEND L_MECH_DECLARE "extern \"C\" void _${MOD_STUB}_reg(void)\;") + list(APPEND L_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") + list(APPEND L_MECH_REGISTRE "_${MOD_STUB}_reg()\;") + + add_custom_command( + COMMAND neuron::nocmodl -o "${CMAKE_CURRENT_BINARY_DIR}/cpp" "${MOD_FILE}" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}" + DEPENDS neuron::nocmodl) + + list(APPEND L_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}") + endforeach() + + if(NRN_MECH_CORENEURON) + # CoreNEURON requires additional mod files. Only append them to the input list if similar named + # mods are _not yet present_ + file(GLOB BASE_MOD_FILES "${_CORENEURON_BASE_MOD}/*.mod") + foreach(MOD_FILE IN LISTS BASE_MOD_FILES) + get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + if("${MOD_STUB}" IN_LIST INPUT_STUBS) + + else() + list(APPEND MOD_FILES "${MOD_FILE}") + endif() + endforeach() + + foreach(MOD_FILE IN LISTS MOD_FILES) + get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + set(CPP_FILE "cpp_core/${MOD_STUB}.cpp") + file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_FILE}") + + list(APPEND L_CORE_MECH_DECLARE "extern int void _${MOD_STUB}_reg(void)\;") + list(APPEND L_CORE_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") + list(APPEND L_CORE_MECH_REGISTRE "_${MOD_STUB}_reg()\;") + + add_custom_command( + COMMAND "${NMODL}" -o "${CMAKE_CURRENT_BINARY_DIR}/cpp_core" "${MOD_FILE}" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}" + DEPENDS "${NMODL}") + + list(APPEND L_CORE_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}") + endforeach() + endif() + + add_library(${LIBNAME} SHARED ${L_SOURCES}) + target_link_libraries(${LIBNAME} PUBLIC neuron::nrniv) + # set_target_properties(${LIBNAME} PROPERTIES OUTPUT_NAME + # "${LIBNAME}$<$:_${NRN_MECH_MECHANISM_NAME}>") + install(TARGETS ${LIBNAME} DESTINATION lib) + + if(NRN_MECH_CORENEURON) + add_library(core${LIBNAME} SHARED ${_CORENEURON_MECH_ENG} ${L_CORE_SOURCES}) + target_include_directories(core${LIBNAME} PRIVATE ${_CORENEURON_RANDOM_INCLUDE}) + target_compile_options(core${LIBNAME} PRIVATE ${_CORENEURON_FLAGS}) + target_link_libraries(core${LIBNAME} PUBLIC neuron::corenrn) + # set_target_properties(${LIBNAME} PROPERTIES OUTPUT_NAME + # "${LIBNAME}$<$:_${NRN_MECH_MECHANISM_NAME}>") + install(TARGETS core${LIBNAME} DESTINATION lib) + endif() + + if(NRN_MECH_INSTALL_CPP) + install(FILES ${L_SOURCES} DESTINATION "share/${NRN_MECH_MECHANISM_NAME}/cpp") + if(NRN_ENABLE_CORENEURON) + install(FILES ${L_CORE_SOURCES} DESTINATION "share/${NRN_MECH_MECHANISM_NAME}/cpp_core") + endif() + endif() + + if(NRN_MECH_INSTALL_MOD) + install(FILES ${MOD_FILES} DESTINATION "share/${NRN_MECH_MECHANISM_NAME}/mod") + endif() + + if(NRN_MECH_SPECIAL) + list(JOIN L_MECH_DECLARE "\n" MECH_DECLARE) + list(JOIN L_MECH_PRINT " \n" MECH_PRINT) + list(JOIN L_MECH_REGISTRE " \n" MECH_REGISTRE) + + get_filename_component(MECH_REG "${_NEURON_MECH_REG}" NAME_WLE) + configure_file(${_NEURON_MECH_REG} ${MECH_REG} @ONLY) + + add_executable(${EXENAME} ${_NEURON_MAIN} ${MECH_REG}) + target_include_directories(${EXENAME} PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) + target_link_libraries(${EXENAME} ${LIBNAME}) + set_target_properties(${EXENAME} PROPERTIES OUTPUT_NAME "special") + install(TARGETS ${EXENAME} DESTINATION bin) + + if(NRN_MECH_CORENEURON) + list(JOIN L_CORE_MECH_DECLARE "\n" MECH_DECLARE) + list(JOIN L_CORE_MECH_PRINT " \n" MECH_PRINT) + list(JOIN L_CORE_MECH_REGISTRE " \n" MECH_REGISTRE) + + get_filename_component(CORE_MECH_REG "${_NEURON_COREMECH_REG}" NAME_WLE) + configure_file(${_NEURON_MECH_REG} core${CORE_MECH_REG} @ONLY) + + add_executable(core${EXENAME} ${_CORENEURON_MAIN} core${CORE_MECH_REG}) + target_include_directories(core${EXENAME} PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) + target_link_libraries(core${EXENAME} core${LIBNAME}) + set_target_properties(core${EXENAME} PROPERTIES OUTPUT_NAME "special-core") + install(TARGETS core${EXENAME} DESTINATION bin) + endif() + endif() +endfunction() diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index cf4fdf4903..56bf4b6018 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -444,10 +444,19 @@ endif() # https://forums.developer.nvidia.com/t/cannot-dynamically-load-a-shared-library-containing-both-openacc-and-cuda-code/210972 add_library(coreneuron-core STATIC ${CORENEURON_CODE_FILES} ${CORENRN_MPI_OBJ}) add_dependencies(coreneuron-core coreneuron-copy-nrnivmodl-core-dependencies) +set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) +set(CORENRN_INSTALL_TARGETS + coreneuron-core + PARENT_SCOPE) if(CORENRN_ENABLE_GPU) set(coreneuron_cuda_target coreneuron-cuda) add_library(coreneuron-cuda ${COMPILE_LIBRARY_TYPE} ${CORENEURON_CUDA_FILES}) + set_target_properties(coreneuron-cuda PROPERTIES EXPORT_NAME corenrn-cuda) target_link_libraries(coreneuron-core PUBLIC coreneuron-cuda) + # list() commands don't propagate to parent scope + set(CORENRN_INSTALL_TARGETS + "coreneuron-core;coreneuron-cuda" + PARENT_SCOPE) endif() foreach(target coreneuron-core ${coreneuron_cuda_target}) @@ -526,6 +535,9 @@ endif() target_compile_options(coreneuron-core PRIVATE ${CORENEURON_CXX_WARNING_SUPPRESSIONS}) target_link_libraries(coreneuron-core PUBLIC ${sonatareport_LIBRARY} ${CORENRN_CALIPER_LIB} ${CORENRN_LIKWID_LIB}) +set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) +target_compile_features(coreneuron-core PUBLIC cxx_std_17) +target_include_directories(coreneuron-core INTERFACE $) # TODO: fix adding a dependency of coreneuron-core on CLI11::CLI11 when CLI11 is a submodule. Right # now this doesn't work because the CLI11 targets are not exported/installed but coreneuron-core is. @@ -626,6 +638,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/profile/profiler_interface.h # CORENRN_LIB_LINK_FLAGS, which contains the arguments that must be added to the link line for # `special` to link against `libcorenrnmech_internal.{a,so}` include(MakefileBuildOptions) +set(CORENRN_CXX_FLAGS + "${CORENRN_CXX_FLAGS}" + PARENT_SCOPE) # ============================================================================= # CoreNEURON related configuration diff --git a/src/ivoc/nrnmain.cpp b/src/ivoc/nrnmain.cpp index 153e9d4559..4e734e6a85 100644 --- a/src/ivoc/nrnmain.cpp +++ b/src/ivoc/nrnmain.cpp @@ -1,6 +1,6 @@ #include "nrnconf.h" #include "nrnmpi.h" -#include "../nrncvode/nrnneosm.h" +#include "nrnneosm.h" #include #include diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index 07aa0a7624..b010afa138 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -399,44 +399,49 @@ include_directories(${NRN_INCLUDE_DIRS}) # All source directories to include # ============================================================================= add_library(nrniv_lib ${NRN_LIBRARY_TYPE} ${NRN_NRNIV_LIB_SRC_FILES}) -target_link_libraries(nrniv_lib nrngnu) -target_link_libraries(nrniv_lib sparse13) -target_link_libraries(nrniv_lib fmt::fmt) -target_include_directories(nrniv_lib SYSTEM PUBLIC ${PROJECT_SOURCE_DIR}/${NRN_3RDPARTY_DIR}/eigen) +target_link_libraries(nrniv_lib PRIVATE nrngnu) +target_link_libraries(nrniv_lib PRIVATE sparse13) +target_link_libraries(nrniv_lib PRIVATE fmt::fmt) +# We feel at liberty to include across various subdirectories without clear interfaces, thus this +# should be public at _build_ time, but not at install time. +target_include_directories( + nrniv_lib SYSTEM PUBLIC $) cpp_cc_configure_sanitizers(TARGET nrniv_lib) # Source-directory .cpp needs to find generated .hpp. -target_include_directories(nrniv_lib PUBLIC "${NRN_OC_GEN}") +target_include_directories(nrniv_lib PUBLIC $) +target_include_directories(nrniv_lib INTERFACE $) if(NRN_ENABLE_PYTHON AND NOT NRN_ENABLE_PYTHON_DYNAMIC) - target_link_libraries(nrniv_lib nrnpython) + target_link_libraries(nrniv_lib PRIVATE nrnpython) endif() if(NRN_ENABLE_THREADS) - target_link_libraries(nrniv_lib Threads::Threads) + target_link_libraries(nrniv_lib PUBLIC Threads::Threads) endif() if(NRN_WINDOWS_BUILD) - target_link_libraries(nrniv_lib ${TERMCAP_LIBRARIES} ${Readline_LIBRARY}) + target_link_libraries(nrniv_lib PUBLIC ${TERMCAP_LIBRARIES} ${Readline_LIBRARY}) else() if(READLINE_FOUND) - target_link_libraries(nrniv_lib ${Readline_LIBRARY}) + target_link_libraries(nrniv_lib PUBLIC ${Readline_LIBRARY}) else() - target_link_libraries(nrniv_lib readline) + target_link_libraries(nrniv_lib PUBLIC readline) endif() if(CURSES_FOUND) - target_link_libraries(nrniv_lib ${CURSES_LIBRARIES}) + target_link_libraries(nrniv_lib PUBLIC ${CURSES_LIBRARIES}) elseif(TERMCAP_FOUND) - target_link_libraries(nrniv_lib ${TERMCAP_LIBRARIES}) + target_link_libraries(nrniv_lib PUBLIC ${TERMCAP_LIBRARIES}) endif() endif() if(NRN_ENABLE_MUSIC AND NOT NRN_ENABLE_MPI_DYNAMIC) - target_link_libraries(nrniv_lib ${MUSIC_LIBRARY}) + target_link_libraries(nrniv_lib PUBLIC ${MUSIC_LIBRARY}) endif() if(NRN_ENABLE_PROFILING) - target_link_libraries(nrniv_lib ${likwid_LIBRARIES} ${CALIPER_LIB} ${LIKWID_LIB}) + target_link_libraries(nrniv_lib PUBLIC ${likwid_LIBRARIES} ${CALIPER_LIB} ${LIKWID_LIB}) endif() -set_property(TARGET nrniv_lib PROPERTY OUTPUT_NAME nrniv) +set_target_properties(nrniv_lib PROPERTIES EXPORT_NAME nrniv OUTPUT_NAME nrniv) +target_compile_features(nrniv_lib PUBLIC cxx_std_17) # ============================================================================= # Link with backward-cpp if enabled @@ -482,16 +487,16 @@ if(NRN_ENABLE_MPI) install(TARGETS ${libnrnmusic}_lib DESTINATION ${NRN_INSTALL_SHARE_LIB_DIR}) endif() else() - target_link_libraries(nrniv_lib ${MPI_C_LIBRARIES}) + target_link_libraries(nrniv_lib PUBLIC ${MPI_C_LIBRARIES}) target_include_directories(nrniv_lib PUBLIC ${MPI_INCLUDE_PATH}) endif() endif() if(NRN_ENABLE_INTERVIEWS) include_directories(${IV_INCLUDE_DIR}) - target_link_libraries(nrniv_lib interviews) + target_link_libraries(nrniv_lib PRIVATE interviews) else() - target_include_directories(nrniv_lib PUBLIC ${NRN_IVOS_SRC_DIR}) + target_include_directories(nrniv_lib PUBLIC $) endif() if(IV_ENABLE_X11_DYNAMIC) @@ -522,11 +527,11 @@ if(IV_ENABLE_X11_DYNAMIC) ${PROJECT_BINARY_DIR}/lib/${LIBIVX11DYNAM_NAME}) endif() else() - target_link_libraries(nrniv_lib ${X11_LIBRARIES}) + target_link_libraries(nrniv_lib PRIVATE ${X11_LIBRARIES}) endif() if(NRN_COVERAGE_FILES) - target_link_libraries(nrniv_lib ${NRN_COVERAGE_LIB}) + target_link_libraries(nrniv_lib PRIVATE ${NRN_COVERAGE_LIB}) target_link_libraries(modlunit ${NRN_COVERAGE_LIB}) target_link_libraries(nocmodl ${NRN_COVERAGE_LIB}) endif() @@ -544,7 +549,7 @@ if(NRN_ENABLE_THREADS) target_link_libraries(nrniv Threads::Threads) endif() if(NOT MINGW) - target_link_libraries(nrniv_lib ${CMAKE_DL_LIBS}) + target_link_libraries(nrniv_lib PUBLIC ${CMAKE_DL_LIBS}) endif() # TODO: unset in top level CMake is not working diff --git a/src/nrnoc/hh.mod b/src/nrnoc/hh.mod index 0c7305ee1b..12c22f0aab 100644 --- a/src/nrnoc/hh.mod +++ b/src/nrnoc/hh.mod @@ -30,7 +30,7 @@ NEURON { NONSPECIFIC_CURRENT il RANGE gnabar, gkbar, gl, el, gna, gk : `GLOBAL minf` will be replaced with `RANGE minf` if CoreNEURON enabled - GLOBAL minf, hinf, ninf, mtau, htau, ntau + RANGE minf, hinf, ninf, mtau, htau, ntau THREADSAFE : assigned GLOBALs will be per thread } @@ -94,7 +94,7 @@ PROCEDURE rates(v(mV)) { :Computes rate and other constants at current v. :Call once from HOC to initialize inf at resting v. LOCAL alpha, beta, sum, q10 : `TABLE minf` will be replaced with `:TABLE minf` if CoreNEURON enabled) - TABLE minf, mtau, hinf, htau, ninf, ntau DEPEND celsius FROM -100 TO 100 WITH 200 + :TABLE minf, mtau, hinf, htau, ninf, ntau DEPEND celsius FROM -100 TO 100 WITH 200 UNITSOFF q10 = 3^((celsius - 6.3)/10) diff --git a/src/nrnpython/CMakeLists.txt b/src/nrnpython/CMakeLists.txt index c1e16afbff..5bd8e8a278 100644 --- a/src/nrnpython/CMakeLists.txt +++ b/src/nrnpython/CMakeLists.txt @@ -45,6 +45,10 @@ endif() # user has selected dynamic python support (could be multiple versions) if(NRN_ENABLE_PYTHON_DYNAMIC) + # set(INCLUDE_DIRS . .. ../oc ../nrnoc ../ivoc ../nrniv ../gnu ../nrnmpi + # ${PROJECT_BINARY_DIR}/src/nrnpython ${PROJECT_BINARY_DIR}/src/ivos ${PROJECT_BINARY_DIR}/src/oc + # ${NRN_OC_GENERATED_SOURCES}) if(NRN_ENABLE_INTERVIEWS) list(APPEND INCLUDE_DIRS + # ${IV_INCLUDE_DIR}) else() list(APPEND INCLUDE_DIRS ../ivos) endif() foreach(val RANGE ${NRN_PYTHON_ITERATION_LIMIT}) list(GET NRN_PYTHON_VERSIONS ${val} pyver) list(GET NRN_PYTHON_INCLUDES ${val} pyinc) From 2df21034aa195459d5d59a49345e15da2c4f2ed0 Mon Sep 17 00:00:00 2001 From: Matthias Wolf Date: Thu, 15 Aug 2024 11:04:45 +0200 Subject: [PATCH 02/63] Bump stuff. --- cmake/coreneuron/packages/Findnmodl.cmake | 42 ----------------------- external/nmodl | 2 +- src/coreneuron/CMakeLists.txt | 14 ++++---- 3 files changed, 8 insertions(+), 50 deletions(-) delete mode 100644 cmake/coreneuron/packages/Findnmodl.cmake diff --git a/cmake/coreneuron/packages/Findnmodl.cmake b/cmake/coreneuron/packages/Findnmodl.cmake deleted file mode 100644 index aa483c889e..0000000000 --- a/cmake/coreneuron/packages/Findnmodl.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# ============================================================================= -# Copyright (C) 2016-2021 Blue Brain Project -# -# See top-level LICENSE file for details. -# ============================================================================= - -# ~~~ -# Findnmodl -# ------------- -# -# Find nmodl -# -# Find the nmodl Blue Brain HPC utils library -# -# Using nmodl: -# -# :: -# set(CORENRN_NMODL_DIR "" CACHE PATH "Path to nmodl source-to-source compiler installation") -# find_package(nmodl REQUIRED) -# target_link_libraries(foo ${nmodl_LIBRARIES}) -# -# This module sets the following variables: -# -# :: -# -# nmodl_FOUND - set to true if the library is found -# nmodl_BINARY - the nmodl binary -# ~~~ - -# UNIX paths are standard, no need to write. -find_program( - nmodl_BINARY - NAMES nmodl${CMAKE_EXECUTABLE_SUFFIX} - HINTS "${CORENRN_NMODL_DIR}/bin" QUIET) - -# Checks 'REQUIRED', 'QUIET' and versions. -include(FindPackageHandleStandardArgs) - -find_package_handle_standard_args( - nmodl - FOUND_VAR nmodl_FOUND - REQUIRED_VARS nmodl_BINARY) diff --git a/external/nmodl b/external/nmodl index 7910146791..08735d544b 160000 --- a/external/nmodl +++ b/external/nmodl @@ -1 +1 @@ -Subproject commit 79101467912f9690b6c40a1d3eed7315e3ea9bc4 +Subproject commit 08735d544b68aee54016e88231e2706dc71762b0 diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index 56bf4b6018..cf7d6ad748 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -255,13 +255,13 @@ endif() if(nmodl_FOUND) set(CORENRN_NMODL_BINARY ${nmodl_BINARY}) else() + message(FATAL_ERROR "BLARGH") set(NMODL_ENABLE_PYTHON_BINDINGS OFF CACHE BOOL "Enable NMODL python bindings") nrn_add_external_project(nmodl DISABLE_ADD) add_subdirectory(${PROJECT_SOURCE_DIR}/external/nmodl ${CMAKE_BINARY_DIR}/external/nmodl) set(CORENRN_NMODL_BINARY ${CMAKE_BINARY_DIR}/bin/nmodl${CMAKE_EXECUTABLE_SUFFIX}) - set(NMODL_TARGET_TO_DEPEND nmodl) set(NMODL_PROJECT_BINARY_DIR ${CMAKE_BINARY_DIR}/external/nmodl) # install nrnunits.lib and libpywrapper.so from external/nmodl install( @@ -576,7 +576,7 @@ set(output_binaries "${nrniv_core_prefix}/special-core" "${corenrn_mech_library} add_custom_command( OUTPUT ${output_binaries} - DEPENDS coreneuron-core ${NMODL_TARGET_TO_DEPEND} ${CORENEURON_BUILTIN_MODFILES} + DEPENDS coreneuron-core nmodl::nmodl ${CORENEURON_BUILTIN_MODFILES} COMMAND ${CMAKE_COMMAND} -E env NMODLHOME=${NMODL_PROJECT_BINARY_DIR} ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core -b ${COMPILE_LIBRARY_TYPE} -m ${CORENRN_NMODL_BINARY} -n @@ -600,7 +600,7 @@ endif() # tests will depend on this, so it must in turn depend on everything that is needed to run nrnivmodl # -coreneuron. add_custom_target(coreneuron-for-tests) -add_dependencies(coreneuron-for-tests coreneuron-core ${NMODL_TARGET_TO_DEPEND}) +add_dependencies(coreneuron-for-tests coreneuron-core nmodl::nmodl) # Create an extra target for internal use that unit tests and so on can depend on. # ${corenrn_mech_library} is libcorenrnmech_internal.{a,so}, which contains both the compiled # default mechanisms and the content of libcoreneuron-core.a. @@ -653,13 +653,13 @@ configure_file(${PROJECT_SOURCE_DIR}/bin/nrnivmodl_core_makefile.in ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile @ONLY) configure_file(${PROJECT_SOURCE_DIR}/bin/nrnivmodl-core.in ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core @ONLY) -# nrnivmodl-core depends on the building of NMODL_TARGET_TO_DEPEND and the configuration of the -# nrnivmodl-core and nrnivmodl_core_makefile this doesn't imply that whenever there is a change in -# one of those files then the prebuilt mod files are going to be rebuilt +# nrnivmodl-core depends on the building of nmodl::nmodl and the configuration of the +# nrnivmodl-core and nrnivmodl_core_makefile this doesn't imply that whenever there is a +# change in one of those files then the prebuilt mod files are going to be rebuilt add_custom_target( nrnivmodl-core ALL DEPENDS ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core - ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile ${NMODL_TARGET_TO_DEPEND}) + ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile nmodl::nmodl) if(CORENRN_ENABLE_UNIT_TESTS) add_subdirectory(${PROJECT_SOURCE_DIR}/test/coreneuron/unit From 87cc65bf89123ee62008beea797c8b2b143c8ca3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:07:53 +0000 Subject: [PATCH 03/63] Fix formatting --- src/coreneuron/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index cf7d6ad748..c32a8dda7b 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -653,9 +653,9 @@ configure_file(${PROJECT_SOURCE_DIR}/bin/nrnivmodl_core_makefile.in ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile @ONLY) configure_file(${PROJECT_SOURCE_DIR}/bin/nrnivmodl-core.in ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core @ONLY) -# nrnivmodl-core depends on the building of nmodl::nmodl and the configuration of the -# nrnivmodl-core and nrnivmodl_core_makefile this doesn't imply that whenever there is a -# change in one of those files then the prebuilt mod files are going to be rebuilt +# nrnivmodl-core depends on the building of nmodl::nmodl and the configuration of the nrnivmodl-core +# and nrnivmodl_core_makefile this doesn't imply that whenever there is a change in one of those +# files then the prebuilt mod files are going to be rebuilt add_custom_target( nrnivmodl-core ALL DEPENDS ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core From 489c39021fcf71852fbaf70a2bdc1d14e289f7b1 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 16 Jan 2025 14:46:58 +0100 Subject: [PATCH 04/63] Add fmt to linked libs for testing --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6555a87b23..2e5572c1a0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,7 +34,7 @@ if(NRN_ENABLE_THREADS) endif() foreach(target ${catch2_targets}) cpp_cc_configure_sanitizers(TARGET ${target}) - target_link_libraries(${target} Catch2::Catch2 nrniv_lib) + target_link_libraries(${target} Catch2::Catch2 fmt::fmt nrniv_lib) if(NOT MINGW) target_link_libraries(${target} ${CMAKE_DL_LIBS}) endif() From 65fc1ee57b57e220749f7e219ca2e6d9beb7e656 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 16 Jan 2025 15:13:16 +0100 Subject: [PATCH 05/63] Also link fmt in Python build --- src/nrnpython/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrnpython/CMakeLists.txt b/src/nrnpython/CMakeLists.txt index 613ed3b038..4f508301da 100644 --- a/src/nrnpython/CMakeLists.txt +++ b/src/nrnpython/CMakeLists.txt @@ -60,7 +60,7 @@ if(NRN_ENABLE_PYTHON_DYNAMIC) add_library(nrnpython${pyver} SHARED ${NRNPYTHON_FILES_LIST}) target_include_directories(nrnpython${pyver} BEFORE PUBLIC ${pyinc} ${INCLUDE_DIRS}) target_link_libraries(nrnpython${pyver} PUBLIC nrniv_lib) - target_link_libraries(nrnpython${pyver} PRIVATE ${Readline_LIBRARY} ${nanobind_target}) + target_link_libraries(nrnpython${pyver} PRIVATE fmt::fmt ${Readline_LIBRARY} ${nanobind_target}) if(NRN_LINK_AGAINST_PYTHON) target_link_libraries(nrnpython${pyver} PUBLIC ${pylib}) endif() From 047732db2fa12657a09f8f29db0854045027638f Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 16 Jan 2025 16:00:15 +0100 Subject: [PATCH 06/63] Put back the original `hh.mod` --- src/nrnoc/hh.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nrnoc/hh.mod b/src/nrnoc/hh.mod index 12c22f0aab..0c7305ee1b 100644 --- a/src/nrnoc/hh.mod +++ b/src/nrnoc/hh.mod @@ -30,7 +30,7 @@ NEURON { NONSPECIFIC_CURRENT il RANGE gnabar, gkbar, gl, el, gna, gk : `GLOBAL minf` will be replaced with `RANGE minf` if CoreNEURON enabled - RANGE minf, hinf, ninf, mtau, htau, ntau + GLOBAL minf, hinf, ninf, mtau, htau, ntau THREADSAFE : assigned GLOBALs will be per thread } @@ -94,7 +94,7 @@ PROCEDURE rates(v(mV)) { :Computes rate and other constants at current v. :Call once from HOC to initialize inf at resting v. LOCAL alpha, beta, sum, q10 : `TABLE minf` will be replaced with `:TABLE minf` if CoreNEURON enabled) - :TABLE minf, mtau, hinf, htau, ninf, ntau DEPEND celsius FROM -100 TO 100 WITH 200 + TABLE minf, mtau, hinf, htau, ninf, ntau DEPEND celsius FROM -100 TO 100 WITH 200 UNITSOFF q10 = 3^((celsius - 6.3)/10) From 86895cbeb9a35284cabc7f70bc214d37a6b13381 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Mon, 20 Jan 2025 20:48:33 +0100 Subject: [PATCH 07/63] Fix issue with corenrn target --- src/coreneuron/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index 3f938742d2..04f6cc626d 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -421,6 +421,11 @@ if(CORENRN_ENABLE_GPU) set(CORENRN_INSTALL_TARGETS "coreneuron-core;coreneuron-cuda" PARENT_SCOPE) +else() + set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) + set(CORENRN_INSTALL_TARGETS + coreneuron-core + PARENT_SCOPE) endif() foreach(target coreneuron-core ${coreneuron_cuda_target}) From 6a8c83b2cee2c67e4e7a808a54cf01a509f3d985 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 17 Apr 2025 15:55:53 +0200 Subject: [PATCH 08/63] Fix issues with paths Always use resolved absolute paths in CMake since nocmodl has some trouble with symlinks. --- cmake/neuronMechMaker.cmake | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index a0897eb41a..f8a310e3dc 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -26,15 +26,17 @@ function(create_nrnmech) foreach(MOD_FILE IN LISTS MOD_FILES) get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + # nocmodl has trouble with symlinks, so we always use the real path + get_filename_component(MOD_ABSPATH "${MOD_FILE}" REALPATH) set(CPP_FILE "cpp/${MOD_STUB}.cpp") - file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_FILE}") + file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_ABSPATH}") list(APPEND L_MECH_DECLARE "extern \"C\" void _${MOD_STUB}_reg(void)\;") list(APPEND L_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") list(APPEND L_MECH_REGISTRE "_${MOD_STUB}_reg()\;") add_custom_command( - COMMAND neuron::nocmodl -o "${CMAKE_CURRENT_BINARY_DIR}/cpp" "${MOD_FILE}" + COMMAND neuron::nocmodl -o "${CMAKE_CURRENT_BINARY_DIR}/cpp" "${MOD_ABSPATH}" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}" DEPENDS neuron::nocmodl) @@ -56,15 +58,17 @@ function(create_nrnmech) foreach(MOD_FILE IN LISTS MOD_FILES) get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + # nmodl _may_ have trouble with symlinks, so we always use the real path + get_filename_component(MOD_ABSPATH "${MOD_FILE}" REALPATH) set(CPP_FILE "cpp_core/${MOD_STUB}.cpp") - file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_FILE}") + file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_ABSPATH}") list(APPEND L_CORE_MECH_DECLARE "extern int void _${MOD_STUB}_reg(void)\;") list(APPEND L_CORE_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") list(APPEND L_CORE_MECH_REGISTRE "_${MOD_STUB}_reg()\;") add_custom_command( - COMMAND "${NMODL}" -o "${CMAKE_CURRENT_BINARY_DIR}/cpp_core" "${MOD_FILE}" + COMMAND "${NMODL}" -o "${CMAKE_CURRENT_BINARY_DIR}/cpp_core" "${MOD_ABSPATH}" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}" DEPENDS "${NMODL}") From 046649620a5be72f3a81655db40889c4d744705e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 15 May 2025 11:29:59 +0200 Subject: [PATCH 09/63] Fix NMODL line numbers in parser --- src/nmodl/lexer/CMakeLists.txt | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/nmodl/lexer/CMakeLists.txt b/src/nmodl/lexer/CMakeLists.txt index ded00ae123..58267c194e 100644 --- a/src/nmodl/lexer/CMakeLists.txt +++ b/src/nmodl/lexer/CMakeLists.txt @@ -73,7 +73,8 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/nmodl/position.hh" "${NMODL_PARSER_BINARY_DIR}/nmodl/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} ARGS -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M + "${NMODL_YY_FROM_PARSER_BINARY_DIR}=../${NMODL_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/nmodl.yy" pyastgen COMMENT "-- NMODL : GENERATING NMODL_CORE PARSER WITH BISON! --") @@ -84,7 +85,7 @@ add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/verbatim_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/verbatim_parser.hpp" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} ARGS -d -o verbatim_parser.cpp "${VERBATIM_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} -d -o verbatim_parser.cpp "${VERBATIM_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/verbatim.yy" COMMENT "-- NMODL : GENERATING VERBATIM PARSER WITH BISON! --") @@ -96,8 +97,8 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/diffeq/diffeq_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/diffeq/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} ARGS -d -o diffeq/diffeq_parser.cpp - "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} -d -o diffeq/diffeq_parser.cpp "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" + -M "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}=../${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/diffeq.yy" "${NMODL_PARSER_SOURCE_DIR}/diffeq_context.hpp" "${NMODL_PARSER_SOURCE_DIR}/diffeq_context.cpp" "${NMODL_PARSER_SOURCE_DIR}/diffeq_helper.hpp" @@ -110,7 +111,8 @@ add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/c/c11_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/c/c11_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/c/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} ARGS -d -o c/c11_parser.cpp "${C11_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} -d -o c/c11_parser.cpp "${C11_YY_FROM_PARSER_BINARY_DIR}" -M + "${C11_YY_FROM_PARSER_BINARY_DIR}=../${C11_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/c11.yy" COMMENT "-- NMODL : GENERATING C (11) PARSER WITH BISON! --") @@ -122,7 +124,8 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/unit/unit_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/unit/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} ARGS -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M + "${UNIT_YY_FROM_PARSER_BINARY_DIR}=../${UNIT_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/unit.yy" COMMENT "-- NMODL : GENERATING UNIT PARSER WITH BISON! --") @@ -132,7 +135,7 @@ file(RELATIVE_PATH NMODL_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/nmodl_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/nmodl_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} ARGS "${NMODL_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} "${NMODL_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/nmodl.ll ${CMAKE_CURRENT_SOURCE_DIR}/nmodl_utils.hpp COMMENT "-- NMODL : GENERATING NMODL LEXER WITH FLEX! --") @@ -143,7 +146,7 @@ file(RELATIVE_PATH VERBATIM_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/verbatim_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/verbatim_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} ARGS "${VERBATIM_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} "${VERBATIM_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/verbatim.l COMMENT "-- NMODL : GENERATING VERBATIM LEXER WITH FLEX! --") @@ -154,7 +157,7 @@ file(RELATIVE_PATH DIFFEQ_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/diffeq_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/diffeq_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} ARGS "${DIFFEQ_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} "${DIFFEQ_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/diffeq.ll COMMENT "-- NMODL : GENERATING DIFFERENTIAL EQUATION LEXER WITH FLEX! --") @@ -165,7 +168,7 @@ file(RELATIVE_PATH C11_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/c11_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/c11_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} ARGS "${C11_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} "${C11_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/c11.ll COMMENT "-- NMODL : GENERATING C(11) LEXER WITH FLEX! --") @@ -176,7 +179,7 @@ file(RELATIVE_PATH UNIT_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/unit_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/unit_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} ARGS "${UNIT_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} "${UNIT_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/unit.ll COMMENT "-- NMODL : GENERATING UNIT LEXER WITH FLEX! --") From b833b1df5f880527d39c9fc465e9b61cc243d568 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 15 May 2025 12:10:39 +0200 Subject: [PATCH 10/63] Add newer version of Bison to Docker image --- CMakeLists.txt | 2 +- packaging/python/Dockerfile | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99d1d35ce1..1300a7e030 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -336,7 +336,7 @@ endif() # ============================================================================= # Find required packages # ============================================================================= -find_package(BISON REQUIRED) +find_package(BISON 3.7 REQUIRED) find_package(FLEX 2.6 REQUIRED) # When shipping the wheels we want to link readline libs statically. diff --git a/packaging/python/Dockerfile b/packaging/python/Dockerfile index d50bb54f6c..3d5db1abdb 100644 --- a/packaging/python/Dockerfile +++ b/packaging/python/Dockerfile @@ -83,6 +83,14 @@ RUN curl -L -o Python-3.10.0.tar.gz https://www.python.org/ftp/python/3.10.0/Pyt RUN yum -y install epel-release libX11-devel libXcomposite-devel vim-enhanced && yum -y clean all && rm -rf /var/cache RUN yum -y remove ncurses-devel +# install newer version of Bison +RUN yum -y remove bison +RUN curl -L -o bison-3.7.tar.gz https://ftp.gnu.org/gnu/bison/bison-3.7.tar.gz \ + && tar -xvzf bison-3.7.tar.gz \ + && cd bison-3.7 \ + && ./configure && make && make install \ + && cd .. && rm -fr bison-3.7 bison-3.7.tar.gz + # build wheels from there WORKDIR /root From bce4aecbeb895dca8cf53dd92069b609f2aae24c Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 15 May 2025 13:42:00 +0200 Subject: [PATCH 11/63] Fix additional NMODL paths lcov was complaining --- src/nmodl/lexer/CMakeLists.txt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/nmodl/lexer/CMakeLists.txt b/src/nmodl/lexer/CMakeLists.txt index 58267c194e..efce5272fb 100644 --- a/src/nmodl/lexer/CMakeLists.txt +++ b/src/nmodl/lexer/CMakeLists.txt @@ -73,8 +73,11 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/nmodl/position.hh" "${NMODL_PARSER_BINARY_DIR}/nmodl/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M - "${NMODL_YY_FROM_PARSER_BINARY_DIR}=../${NMODL_YY_FROM_PARSER_BINARY_DIR}" + COMMAND + ${BISON_EXECUTABLE} -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M + "${NMODL_YY_FROM_PARSER_BINARY_DIR}=../${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M + "nmodl/location.hh=src/nmodl/parser/nmodl/location.hh" -M + "nmodl/nmodl_parser.hpp=src/nmodl/parser/nmodl/nmodl_parser.hpp" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/nmodl.yy" pyastgen COMMENT "-- NMODL : GENERATING NMODL_CORE PARSER WITH BISON! --") @@ -124,8 +127,10 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/unit/unit_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/unit/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M - "${UNIT_YY_FROM_PARSER_BINARY_DIR}=../${UNIT_YY_FROM_PARSER_BINARY_DIR}" + COMMAND + ${BISON_EXECUTABLE} -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M + "${UNIT_YY_FROM_PARSER_BINARY_DIR}=../${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M + "unit/unit_parser.hpp=src/nmodl/parser/unit/unit_parser.hpp" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/unit.yy" COMMENT "-- NMODL : GENERATING UNIT PARSER WITH BISON! --") From cbef7cedd6b81b50ed26a2878403b28fa0815d2d Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 28 May 2025 13:50:06 +0200 Subject: [PATCH 12/63] Update to lcov 2 --- .github/workflows/coverage.yml | 4 ++-- cmake/Coverage.cmake | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 473b36ef6b..0f54ae5a20 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -33,7 +33,7 @@ env: jobs: coverage: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 name: Code Coverage @@ -49,7 +49,7 @@ jobs: - name: Install apt packages run: | - sudo apt-get install xfonts-100dpi build-essential doxygen lcov libboost-all-dev libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin gpg ninja-build flex bison libfl-dev + sudo apt-get install xfonts-100dpi build-essential doxygen lcov libboost-all-dev libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin gpg ninja-build flex bison libfl-dev libreadline-dev shell: bash - name: Install a new ccache diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index e2df7cdd36..d7f1b0b942 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -102,13 +102,18 @@ if(NRN_ENABLE_COVERAGE) set(cover_clean_command find "${PROJECT_BINARY_DIR}" "-name" "*.gcda" "-type" "f" "-delete") set(cover_baseline_command "${LCOV}" "--capture" "--initial" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" - "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-base.info") + "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-base.info" --ignore-errors + mismatch --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) set(cover_collect_command "${LCOV}" "--capture" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" "--directory" - "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info") - set(cover_combine_command "${LCOV}" "--add-tracefile" "coverage-base.info" "--add-tracefile" - "coverage-run.info" "--output-file" "coverage-combined.info") - set(cover_html_command genhtml "coverage-combined.info" "--output-directory" html) + "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info" --ignore-errors mismatch + --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) + set(cover_combine_command + "${LCOV}" "--add-tracefile" "coverage-base.info" "--add-tracefile" "coverage-run.info" + "--output-file" "coverage-combined.info" --ignore-errors mismatch --parallel + ${CMAKE_BUILD_PARALLEL_LEVEL}) + set(cover_html_command genhtml "coverage-combined.info" "--output-directory" html --parallel + ${CMAKE_BUILD_PARALLEL_LEVEL}) add_custom_target( cover_clean COMMAND ${cover_clean_command} From 2e2d1de1f96cc0adf3e4b1083a67d1a8a4856624 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 28 May 2025 16:20:26 +0200 Subject: [PATCH 13/63] Alternative fix with flexible bison Only report a warning (not an error) if Bison < 3.7 and using lcov --- CMakeLists.txt | 8 ++++++- packaging/python/Dockerfile | 8 ------- src/nmodl/lexer/CMakeLists.txt | 44 ++++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a675f4bfa6..ae9e17d632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,9 +353,15 @@ endif() # ============================================================================= # Find required packages # ============================================================================= -find_package(BISON 3.7 REQUIRED) +find_package(BISON REQUIRED) find_package(FLEX 2.6 REQUIRED) +# lcov >= 2 and bison < 3.7 do not play nicely +if(NRN_ENABLE_COVERAGE AND BISON_VERSION VERSION_LESS "3.7") + message(WARNING "Bison 3.7 or above is recommended with NRN_ENABLE_COVERAGE=ON;" + " if using lcov 2 or above, you may experience errors!") +endif() + # When shipping the wheels we want to link readline libs statically. if(NRN_WHEEL_STATIC_READLINE) # CMake will prefer dynamic libraries over static ones. With the following construct we make sure diff --git a/packaging/python/Dockerfile b/packaging/python/Dockerfile index 3d5db1abdb..d50bb54f6c 100644 --- a/packaging/python/Dockerfile +++ b/packaging/python/Dockerfile @@ -83,14 +83,6 @@ RUN curl -L -o Python-3.10.0.tar.gz https://www.python.org/ftp/python/3.10.0/Pyt RUN yum -y install epel-release libX11-devel libXcomposite-devel vim-enhanced && yum -y clean all && rm -rf /var/cache RUN yum -y remove ncurses-devel -# install newer version of Bison -RUN yum -y remove bison -RUN curl -L -o bison-3.7.tar.gz https://ftp.gnu.org/gnu/bison/bison-3.7.tar.gz \ - && tar -xvzf bison-3.7.tar.gz \ - && cd bison-3.7 \ - && ./configure && make && make install \ - && cd .. && rm -fr bison-3.7 bison-3.7.tar.gz - # build wheels from there WORKDIR /root diff --git a/src/nmodl/lexer/CMakeLists.txt b/src/nmodl/lexer/CMakeLists.txt index efce5272fb..cf07d2fee3 100644 --- a/src/nmodl/lexer/CMakeLists.txt +++ b/src/nmodl/lexer/CMakeLists.txt @@ -43,6 +43,22 @@ set(LEXER_SOURCE_FILES ${C_DRIVER_FILES} ${UNIT_DRIVER_FILES}) +# ~~~ +# modify invocation of bison (use -M flag if version 3.7 or above) +# ~~~ +function(compose_bison_command OUT_VAR) + cmake_parse_arguments(ARG "" "" "PATHS" ${ARGN}) + set(BISON_CMD ${BISON_EXECUTABLE}) + if(BISON_VERSION VERSION_GREATER_EQUAL "3.7") + foreach(path IN LISTS ARG_PATHS) + list(APPEND BISON_CMD -M "${path}") + endforeach() + endif() + set(${OUT_VAR} + "${BISON_CMD}" + PARENT_SCOPE) +endfunction() + if(NMODL_PGI_COMPILER) # "verbatim_lexer.cpp", warning #550-D: variable "..." was set but never used set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/verbatim_lexer.cpp @@ -66,6 +82,10 @@ file(MAKE_DIRECTORY ${NMODL_PARSER_BINARY_DIR}/nmodl ${NMODL_PARSER_BINARY_DIR}/ # prefix changes (e.g. GitLab CI). file(RELATIVE_PATH NMODL_YY_FROM_PARSER_BINARY_DIR "${NMODL_PARSER_BINARY_DIR}" "${NMODL_PARSER_SOURCE_DIR}/nmodl.yy") +compose_bison_command( + BISON_CMD PATHS "${NMODL_YY_FROM_PARSER_BINARY_DIR}=../${NMODL_YY_FROM_PARSER_BINARY_DIR}" + "nmodl/location.hh=src/nmodl/parser/nmodl/location.hh" + "nmodl/nmodl_parser.hpp=src/nmodl/parser/nmodl/nmodl_parser.hpp") add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/nmodl/location.hh" "${NMODL_PARSER_BINARY_DIR}/nmodl/nmodl_parser.cpp" @@ -73,11 +93,7 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/nmodl/position.hh" "${NMODL_PARSER_BINARY_DIR}/nmodl/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND - ${BISON_EXECUTABLE} -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M - "${NMODL_YY_FROM_PARSER_BINARY_DIR}=../${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M - "nmodl/location.hh=src/nmodl/parser/nmodl/location.hh" -M - "nmodl/nmodl_parser.hpp=src/nmodl/parser/nmodl/nmodl_parser.hpp" + COMMAND ${BISON_CMD} -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/nmodl.yy" pyastgen COMMENT "-- NMODL : GENERATING NMODL_CORE PARSER WITH BISON! --") @@ -95,13 +111,14 @@ add_custom_command( # Command to generate differential equation parser. See comment above about absolute paths. file(RELATIVE_PATH DIFFEQ_YY_FROM_PARSER_BINARY_DIR "${NMODL_PARSER_BINARY_DIR}" "${NMODL_PARSER_SOURCE_DIR}/diffeq.yy") +compose_bison_command(BISON_CMD PATHS + "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}=../${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}") add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/diffeq/diffeq_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/diffeq/diffeq_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/diffeq/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o diffeq/diffeq_parser.cpp "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" - -M "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}=../${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_CMD} -d -o diffeq/diffeq_parser.cpp "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/diffeq.yy" "${NMODL_PARSER_SOURCE_DIR}/diffeq_context.hpp" "${NMODL_PARSER_SOURCE_DIR}/diffeq_context.cpp" "${NMODL_PARSER_SOURCE_DIR}/diffeq_helper.hpp" @@ -110,27 +127,28 @@ add_custom_command( # Command to generate C (11) parser. See comment above about absolute paths. file(RELATIVE_PATH C11_YY_FROM_PARSER_BINARY_DIR "${NMODL_PARSER_BINARY_DIR}" "${NMODL_PARSER_SOURCE_DIR}/c11.yy") +compose_bison_command(BISON_CMD PATHS + "${C11_YY_FROM_PARSER_BINARY_DIR}=../${C11_YY_FROM_PARSER_BINARY_DIR}") add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/c/c11_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/c/c11_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/c/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o c/c11_parser.cpp "${C11_YY_FROM_PARSER_BINARY_DIR}" -M - "${C11_YY_FROM_PARSER_BINARY_DIR}=../${C11_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_CMD} -d -o c/c11_parser.cpp "${C11_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/c11.yy" COMMENT "-- NMODL : GENERATING C (11) PARSER WITH BISON! --") # Command to generate Units parser. See comment above about absolute paths. file(RELATIVE_PATH UNIT_YY_FROM_PARSER_BINARY_DIR "${NMODL_PARSER_BINARY_DIR}" "${NMODL_PARSER_SOURCE_DIR}/unit.yy") +compose_bison_command( + BISON_CMD PATHS "${UNIT_YY_FROM_PARSER_BINARY_DIR}=../${UNIT_YY_FROM_PARSER_BINARY_DIR}" + "unit/unit_parser.hpp=src/nmodl/parser/unit/unit_parser.hpp") add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/unit/unit_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/unit/unit_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/unit/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND - ${BISON_EXECUTABLE} -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M - "${UNIT_YY_FROM_PARSER_BINARY_DIR}=../${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M - "unit/unit_parser.hpp=src/nmodl/parser/unit/unit_parser.hpp" + COMMAND ${BISON_CMD} -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/unit.yy" COMMENT "-- NMODL : GENERATING UNIT PARSER WITH BISON! --") From 94c568d8cf467ad78dc7488daa06ed2d61c4fe3b Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 28 May 2025 16:45:59 +0200 Subject: [PATCH 14/63] Extract version of lcov --- CMakeLists.txt | 11 ++++++++--- cmake/Coverage.cmake | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae9e17d632..a4eb12e560 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -357,9 +357,14 @@ find_package(BISON REQUIRED) find_package(FLEX 2.6 REQUIRED) # lcov >= 2 and bison < 3.7 do not play nicely -if(NRN_ENABLE_COVERAGE AND BISON_VERSION VERSION_LESS "3.7") - message(WARNING "Bison 3.7 or above is recommended with NRN_ENABLE_COVERAGE=ON;" - " if using lcov 2 or above, you may experience errors!") +if(NRN_ENABLE_COVERAGE + AND BISON_VERSION VERSION_LESS "3.7" + AND LCOV_VERSION VERSION_GREATER_EQUAL "2.0") + message( + WARNING + "Bison ${BISON_VERSION} detected;" + " Bison 3.7 or above is recommended with NRN_ENABLE_COVERAGE=ON and lcov ${LCOV_VERSION}," + " you may experience errors!") endif() # When shipping the wheels we want to link readline libs statically. diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index e2df7cdd36..d86a02bca0 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -25,11 +25,26 @@ # All created files (folders) are relative to PROJECT_BINARY_DIR. # ~~~ +# find the version of lcov +function(extract_version var) + execute_process( + COMMAND ${LCOV} --version + OUTPUT_VARIABLE LCOV_VERSION_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "([0-9]+\\.[0-9]+(\\.[0-9]+)?)" _ "${LCOV_VERSION_OUTPUT}") + set(${var} + "${CMAKE_MATCH_1}" + PARENT_SCOPE) +endfunction() + if(NRN_ENABLE_COVERAGE) find_program(LCOV lcov) if(LCOV STREQUAL "LCOV-NOTFOUND") message(ERROR "lcov is required with NRN_ENABLE_COVERAGE=ON and it was not found.") endif() + + extract_version(LCOV_VERSION) + string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE_UPPER) if(NOT BUILD_TYPE_UPPER STREQUAL "DEBUG") message(WARNING "Using CMAKE_BUILD_TYPE=Debug is recommended with NRN_ENABLE_COVERAGE") From be489a0c65ab584bb557d0cbba1fa2889355b9fa Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 28 May 2025 16:52:52 +0200 Subject: [PATCH 15/63] Set launcher command based on lcov version --- CMakeLists.txt | 2 +- cmake/Coverage.cmake | 22 ++++++++++++---------- packaging/python/Dockerfile | 8 -------- src/nmodl/lexer/CMakeLists.txt | 30 +++++++++++------------------- 4 files changed, 24 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a675f4bfa6..1a04d45695 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,7 +353,7 @@ endif() # ============================================================================= # Find required packages # ============================================================================= -find_package(BISON 3.7 REQUIRED) +find_package(BISON REQUIRED) find_package(FLEX 2.6 REQUIRED) # When shipping the wheels we want to link readline libs statically. diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index d7f1b0b942..bbe42dba79 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -99,21 +99,23 @@ macro(nrn_enable_coverage_files) endmacro() if(NRN_ENABLE_COVERAGE) + if(LCOV_VERSION GREATER_EQUAL "2.0") + set(LCOV_LAUNCHER ${LCOV} --parallel ${CMAKE_BUILD_PARALLEL_LEVEL} --ignore-errors-mismatch) + set(GENHTML_LAUNCHER genhtml --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) + else() + set(LCOV_LAUNCHER ${LCOV}) + set(GENHTML_LAUNCHER genhtml) + endif() set(cover_clean_command find "${PROJECT_BINARY_DIR}" "-name" "*.gcda" "-type" "f" "-delete") set(cover_baseline_command "${LCOV}" "--capture" "--initial" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" - "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-base.info" --ignore-errors - mismatch --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) + "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-base.info") set(cover_collect_command "${LCOV}" "--capture" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" "--directory" - "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info" --ignore-errors mismatch - --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) - set(cover_combine_command - "${LCOV}" "--add-tracefile" "coverage-base.info" "--add-tracefile" "coverage-run.info" - "--output-file" "coverage-combined.info" --ignore-errors mismatch --parallel - ${CMAKE_BUILD_PARALLEL_LEVEL}) - set(cover_html_command genhtml "coverage-combined.info" "--output-directory" html --parallel - ${CMAKE_BUILD_PARALLEL_LEVEL}) + "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info") + set(cover_combine_command "${LCOV}" "--add-tracefile" "coverage-base.info" "--add-tracefile" + "coverage-run.info" "--output-file" "coverage-combined.info") + set(cover_html_command ${GENHTML_LAUNCHER} "coverage-combined.info" "--output-directory" html) add_custom_target( cover_clean COMMAND ${cover_clean_command} diff --git a/packaging/python/Dockerfile b/packaging/python/Dockerfile index 3d5db1abdb..d50bb54f6c 100644 --- a/packaging/python/Dockerfile +++ b/packaging/python/Dockerfile @@ -83,14 +83,6 @@ RUN curl -L -o Python-3.10.0.tar.gz https://www.python.org/ftp/python/3.10.0/Pyt RUN yum -y install epel-release libX11-devel libXcomposite-devel vim-enhanced && yum -y clean all && rm -rf /var/cache RUN yum -y remove ncurses-devel -# install newer version of Bison -RUN yum -y remove bison -RUN curl -L -o bison-3.7.tar.gz https://ftp.gnu.org/gnu/bison/bison-3.7.tar.gz \ - && tar -xvzf bison-3.7.tar.gz \ - && cd bison-3.7 \ - && ./configure && make && make install \ - && cd .. && rm -fr bison-3.7 bison-3.7.tar.gz - # build wheels from there WORKDIR /root diff --git a/src/nmodl/lexer/CMakeLists.txt b/src/nmodl/lexer/CMakeLists.txt index efce5272fb..ded00ae123 100644 --- a/src/nmodl/lexer/CMakeLists.txt +++ b/src/nmodl/lexer/CMakeLists.txt @@ -73,11 +73,7 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/nmodl/position.hh" "${NMODL_PARSER_BINARY_DIR}/nmodl/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND - ${BISON_EXECUTABLE} -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M - "${NMODL_YY_FROM_PARSER_BINARY_DIR}=../${NMODL_YY_FROM_PARSER_BINARY_DIR}" -M - "nmodl/location.hh=src/nmodl/parser/nmodl/location.hh" -M - "nmodl/nmodl_parser.hpp=src/nmodl/parser/nmodl/nmodl_parser.hpp" + COMMAND ${BISON_EXECUTABLE} ARGS -d -o nmodl/nmodl_parser.cpp "${NMODL_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/nmodl.yy" pyastgen COMMENT "-- NMODL : GENERATING NMODL_CORE PARSER WITH BISON! --") @@ -88,7 +84,7 @@ add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/verbatim_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/verbatim_parser.hpp" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o verbatim_parser.cpp "${VERBATIM_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} ARGS -d -o verbatim_parser.cpp "${VERBATIM_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/verbatim.yy" COMMENT "-- NMODL : GENERATING VERBATIM PARSER WITH BISON! --") @@ -100,8 +96,8 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/diffeq/diffeq_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/diffeq/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o diffeq/diffeq_parser.cpp "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" - -M "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}=../${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} ARGS -d -o diffeq/diffeq_parser.cpp + "${DIFFEQ_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/diffeq.yy" "${NMODL_PARSER_SOURCE_DIR}/diffeq_context.hpp" "${NMODL_PARSER_SOURCE_DIR}/diffeq_context.cpp" "${NMODL_PARSER_SOURCE_DIR}/diffeq_helper.hpp" @@ -114,8 +110,7 @@ add_custom_command( OUTPUT "${NMODL_PARSER_BINARY_DIR}/c/c11_parser.cpp" "${NMODL_PARSER_BINARY_DIR}/c/c11_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/c/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND ${BISON_EXECUTABLE} -d -o c/c11_parser.cpp "${C11_YY_FROM_PARSER_BINARY_DIR}" -M - "${C11_YY_FROM_PARSER_BINARY_DIR}=../${C11_YY_FROM_PARSER_BINARY_DIR}" + COMMAND ${BISON_EXECUTABLE} ARGS -d -o c/c11_parser.cpp "${C11_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/c11.yy" COMMENT "-- NMODL : GENERATING C (11) PARSER WITH BISON! --") @@ -127,10 +122,7 @@ add_custom_command( "${NMODL_PARSER_BINARY_DIR}/unit/unit_parser.hpp" "${NMODL_PARSER_BINARY_DIR}/unit/stack.hh" WORKING_DIRECTORY "${NMODL_PARSER_BINARY_DIR}" - COMMAND - ${BISON_EXECUTABLE} -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M - "${UNIT_YY_FROM_PARSER_BINARY_DIR}=../${UNIT_YY_FROM_PARSER_BINARY_DIR}" -M - "unit/unit_parser.hpp=src/nmodl/parser/unit/unit_parser.hpp" + COMMAND ${BISON_EXECUTABLE} ARGS -d -o unit/unit_parser.cpp "${UNIT_YY_FROM_PARSER_BINARY_DIR}" DEPENDS "${NMODL_PARSER_SOURCE_DIR}/unit.yy" COMMENT "-- NMODL : GENERATING UNIT PARSER WITH BISON! --") @@ -140,7 +132,7 @@ file(RELATIVE_PATH NMODL_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/nmodl_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/nmodl_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} "${NMODL_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} ARGS "${NMODL_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/nmodl.ll ${CMAKE_CURRENT_SOURCE_DIR}/nmodl_utils.hpp COMMENT "-- NMODL : GENERATING NMODL LEXER WITH FLEX! --") @@ -151,7 +143,7 @@ file(RELATIVE_PATH VERBATIM_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/verbatim_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/verbatim_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} "${VERBATIM_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} ARGS "${VERBATIM_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/verbatim.l COMMENT "-- NMODL : GENERATING VERBATIM LEXER WITH FLEX! --") @@ -162,7 +154,7 @@ file(RELATIVE_PATH DIFFEQ_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/diffeq_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/diffeq_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} "${DIFFEQ_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} ARGS "${DIFFEQ_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/diffeq.ll COMMENT "-- NMODL : GENERATING DIFFERENTIAL EQUATION LEXER WITH FLEX! --") @@ -173,7 +165,7 @@ file(RELATIVE_PATH C11_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/c11_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/c11_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} "${C11_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} ARGS "${C11_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/c11.ll COMMENT "-- NMODL : GENERATING C(11) LEXER WITH FLEX! --") @@ -184,7 +176,7 @@ file(RELATIVE_PATH UNIT_LL_FROM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/unit_base_lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/unit_base_lexer.hpp - COMMAND ${FLEX_EXECUTABLE} "${UNIT_LL_FROM_BINARY_DIR}" + COMMAND ${FLEX_EXECUTABLE} ARGS "${UNIT_LL_FROM_BINARY_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/unit.ll COMMENT "-- NMODL : GENERATING UNIT LEXER WITH FLEX! --") From d6831405eb469dd9f702dc791f334b1d06a6ae6e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 28 May 2025 16:57:58 +0200 Subject: [PATCH 16/63] Set lcov launcher flags based on version --- cmake/Coverage.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index d8d34ff796..7189f1f7e3 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -115,7 +115,7 @@ endmacro() if(NRN_ENABLE_COVERAGE) if(LCOV_VERSION GREATER_EQUAL "2.0") - set(LCOV_LAUNCHER ${LCOV} --parallel ${CMAKE_BUILD_PARALLEL_LEVEL} --ignore-errors-mismatch) + set(LCOV_LAUNCHER ${LCOV} --parallel ${CMAKE_BUILD_PARALLEL_LEVEL} --ignore-errors mismatch) set(GENHTML_LAUNCHER genhtml --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) else() set(LCOV_LAUNCHER ${LCOV}) @@ -123,13 +123,15 @@ if(NRN_ENABLE_COVERAGE) endif() set(cover_clean_command find "${PROJECT_BINARY_DIR}" "-name" "*.gcda" "-type" "f" "-delete") set(cover_baseline_command - "${LCOV}" "--capture" "--initial" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" - "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-base.info") + "${LCOV_LAUNCHER}" "--capture" "--initial" "--no-external" "--directory" + "${PROJECT_SOURCE_DIR}" "--directory" "${PROJECT_BINARY_DIR}" "--output-file" + "coverage-base.info") set(cover_collect_command - "${LCOV}" "--capture" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" "--directory" - "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info") - set(cover_combine_command "${LCOV}" "--add-tracefile" "coverage-base.info" "--add-tracefile" - "coverage-run.info" "--output-file" "coverage-combined.info") + "${LCOV_LAUNCHER}" "--capture" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" + "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info") + set(cover_combine_command + "${LCOV_LAUNCHER}" "--add-tracefile" "coverage-base.info" "--add-tracefile" + "coverage-run.info" "--output-file" "coverage-combined.info") set(cover_html_command ${GENHTML_LAUNCHER} "coverage-combined.info" "--output-directory" html) add_custom_target( cover_clean From 5e38569975a1804044f988fb4449340ecaa11e1c Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 28 May 2025 16:58:28 +0200 Subject: [PATCH 17/63] Revert to ubuntu 22.04 to see if it works --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0f54ae5a20..2d68bf202a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -33,7 +33,7 @@ env: jobs: coverage: - runs-on: ubuntu-24.04 + runs-on: ubuntu-22.04 name: Code Coverage From 58a380f5a7128ad55a0732088333338a302617ad Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 3 Jun 2025 16:37:36 +0200 Subject: [PATCH 18/63] Update create_nrnmech * add docs and various args --- cmake/neuronMechMaker.cmake | 366 ++++++++++++++++++++++++++++-------- 1 file changed, 285 insertions(+), 81 deletions(-) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index f8a310e3dc..6e41878e5c 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -1,9 +1,79 @@ # ~~~ +# Helper functions for generating (core)NEURON mechanism libraries directly in CMake +# The basic idea is to replicate all of the previous functionality of the Makefiles, +# but without having to deal with reading Makefiles or having to worry about dependencies. +# What `nrnivmodl` and `nrnivmodl -coreneuron` were doing was essentially: +# - create a subdir equivalent to `CMAKE_HOST_SYSTEM_PROCESSOR` in the current working directory +# - translate a given list of mod files to cpp files (using either NOCMODL or NMODL) +# - create a file `mod_func.cpp` which dynamically (that is, upon running `nrniv` or similar) registers the mechanisms in NEURON +# - create a `nrnmech` library in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from all of the above listed cpp files +# - create a `special` executable in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from the `nrnmain.cpp` file +# - link the above executable to the `nrnmech` library +# In case the `-coreneuron` option is given, it additionally does the following: +# - create a `corenrnmech` library in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from all of the above listed cpp files, except with a different `mod_func.cpp` which correctly registers it under the `coreneuron` cpp namespace +# - create a `special-core` executable in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from the `coreneuron.cpp` file +# - link the above executable to the `corenrnmech` library +# Note that any other files created are basically noise. +# create_nrnmech( +# [NEURON] +# [CORENEURON] +# [SPECIAL] +# [NMODL_NEURON_CODEGEN] +# [TARGET_LIBRARY_NAME lib_tgt] +# [TARGET_EXECUTABLE_NAME exe_tgt] +# [LIBRARY_OUTPUT_DIR lib_outdir] +# [EXECUTABLE_OUTPUT_DIR exe_outdir] +# [ARTIFACTS_OUTPUT_DIR art_outdir] +# [LIBRARY_TYPE type] +# [NOCMODL_EXECUTABLE path/to/nocmodl] +# [NMODL_EXECUTABLE path/to/nmodl] +# [MOD_FILES mod1 mod2 ...] +# [NMODL_EXTRA_ARGS arg1 arg2 ...] +# [EXTRA_ENV KEY1=VAL1 KEY2=VAL2 ...] +# ) # +# Create a suitable mechanism for loading into NEURON. +# +# NEURON - (optional) whether a library compatible with NEURON should be created. +# CORENEURON - (optional) whether a library compatible with coreNEURON should be created. At least one of NEURON or CORENEURON must be specified. +# SPECIAL - (optional) whether a `special` (or `special-core` in case of coreNEURON) executable should be created. +# NMODL_NEURON_CODEGEN - (optional) whether to use NMODL to generate files compatible with NEURON. +# TARGET_LIBRARY_NAME - (optional, default: nrnmech) the name of the CMake target for the library. Note that `core` is prepended to the coreNEURON target. +# TARGET_EXECUTABLE_NAME - (optional, default: special) the name of the CMake target for the executable. Note that `-core` is appended to the coreNEURON target. +# ARTIFACTS_OUTPUT_DIR - (optional) the path where the CPP files will be placed at build-time. +# NOCMODL_EXECUTABLE - (optional) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. +# NMODL_EXECUTABLE - (optional) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. +# MOD_FILES - list of mod files to convert. +# NMODL_EXTRA_ARGS - (optional, default: None) list of additional arguments to pass to NMODL. +# EXTRA_ENV - (optional, default: None) list of additional environmental variables to pass when building the targets. +# TODO figure out why we get missing symbols when testing +# ~~~ function(create_nrnmech) - set(options CORENEURON INSTALL_CPP INSTALL_MOD SPECIAL) - set(oneValueArgs MECHANISM_NAME) - cmake_parse_arguments(NRN_MECH "${options}" "${oneValueArgs}" "MOD_FILES" ${ARGN}) + set(options NEURON CORENEURON SPECIAL NMODL_NEURON_CODEGEN) + set(oneValueArgs + MECHANISM_NAME + TARGET_LIBRARY_NAME + TARGET_EXECUTABLE_NAME + LIBRARY_OUTPUT_DIR + EXECUTABLE_OUTPUT_DIR + ARTIFACTS_OUTPUT_DIR + LIBRARY_TYPE + NOCMODL_EXECUTABLE + NMODL_EXECUTABLE) + set(multiValueArgs MOD_FILES NMODL_EXTRA_ARGS EXTRA_ENV) + cmake_parse_arguments(NRN_MECH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # The name of the output library + set(LIBNAME "nrnmech") + # The name of the output executable + set(EXENAME "special") + # The default type of the output library. Note that `nrnmech` and `corenrnmech` are actually + # module libraries (since they are loaded via `dlopen`-like functionality), but a module library + # cannot be linked to, and since `special` must link to `nrnmech`, so to avoid having to compile + # the source files twice, we use a shared library instead. + set(DEFAULT_LIBRARY_TYPE "SHARED") + # The default name of the mechanism + set(DEFAULT_MECHANISM_NAME "neuron") if(NRN_MECH_CORENEURON) if(NOT NRN_ENABLE_CORENEURON) @@ -11,51 +81,204 @@ function(create_nrnmech) endif() endif() - if(NOT MECHANISM_NAME) - set(MECHANISM_NAME neuron) + if(NOT NRN_MECH_NEURON AND NOT NRN_MECH_CORENEURON) + message( + FATAL_ERROR + "No output specified for mod files, please specify at least one of `NEURON` or `CORENEURON` outputs" + ) endif() - set(LIBNAME "nrnmech") - set(EXENAME "special") + if(NOT NRN_MECH_MOD_FILES) + message(FATAL_ERROR "No input mod files specified!") + endif() + + if(NRN_MECH_MECHANISM_NAME) + set(MECHANISM_NAME "${NRN_MECH_MECHANISM_NAME}") + else() + set(MECHANISM_NAME "${DEFAULT_MECHANISM_NAME}") + endif() + + # the `nmodl` and `nocmodl` executables are usually found through `find_program` on the user's + # system, but we allow overrides (for testing purposes only) + if(NRN_MECH_NMODL_EXECUTABLE) + set(NMODL_EXECUTABLE "${NRN_MECH_NMODL_EXECUTABLE}") + else() + set(NMODL_EXECUTABLE "${NMODL}") + endif() + + if(NRN_MECH_NOCMODL_EXECUTABLE) + set(NOCMODL_EXECUTABLE "${NRN_MECH_NOCMODL_EXECUTABLE}") + else() + set(NOCMODL_EXECUTABLE $) + endif() + + # the option `CORENRN_ENABLE_SHARED` toggles the kind of library we want to build, so we respect + # it here + if(NRN_MECH_LIBRARY_TYPE) + set(LIBRARY_TYPE "${NRN_MECH_LIBRARY_TYPE}") + else() + set(LIBRARY_TYPE "${DEFAULT_LIBRARY_TYPE}") + endif() + + # nmodl by default generates code for coreNEURON, so we toggle this via an option + if(NRN_MECH_NMODL_NEURON_CODEGEN) + set(NEURON_TRANSPILER_LAUNCHER ${NMODL_EXECUTABLE} --neuron) + else() + set(NEURON_TRANSPILER_LAUNCHER ${NOCMODL_EXECUTABLE}) + endif() + + # raise warning that NMODL extra args will be ignored if we use NEURON codegen with NOCMODL + if(NRN_MECH_NEURON + AND NOT NRN_MECH_NMODL_NEURON_CODEGEN + AND NRN_MECH_NMODL_EXTRA_ARGS) + message( + WARNING + "create_nrmech: requested NEURON library with NOCMODL codegen, but NMODL_EXTRA_ARGS is not empty; " + "will ignore NMODL_EXTRA_ARGS when building NEURON library.\n" + "Hint: if you want to use NMODL for codegen, add the NMODL_NEURON_CODEGEN option when calling this function." + ) + set(NRN_MECH_NMODL_EXTRA_ARGS) + endif() + + # any extra environment variables that need to be passed (for testing purposes only). Because + # CMake likes to escape and quote things, we need to do it the roundabout way... + if(NRN_MECH_EXTRA_ENV) + set(ENV_COMMAND "${CMAKE_COMMAND}" -E env ${NRN_MECH_EXTRA_ENV}) + else() + set(ENV_COMMAND) + endif() + + # Override the _target_ name, but not the library name. This is useful when we are using this + # function for building NEURON components, since we may experience collisions in the target names + if(NRN_MECH_TARGET_LIBRARY_NAME) + set(TARGET_LIBRARY_NAME "${NRN_MECH_TARGET_LIBRARY_NAME}") + else() + set(TARGET_LIBRARY_NAME "${LIBNAME}") + endif() + + # Override the _target_ name, but not the executable name. This is useful when we are using this + # function for building NEURON components, since we may experience collisions in the target names + if(NRN_MECH_TARGET_EXECUTABLE_NAME) + set(TARGET_EXECUTABLE_NAME "${NRN_MECH_TARGET_EXECUTABLE_NAME}") + else() + set(TARGET_EXECUTABLE_NAME "${EXENAME}") + endif() + + # Where to output the library (during build) + if(NRN_MECH_LIBRARY_OUTPUT_DIR) + set(LIBRARY_OUTPUT_DIR "${NRN_MECH_LIBRARY_OUTPUT_DIR}") + else() + set(LIBRARY_OUTPUT_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + endif() + + # Where to output the executable (during build) + if(NRN_MECH_EXECUTABLE_OUTPUT_DIR) + set(EXECUTABLE_OUTPUT_DIR "${NRN_MECH_EXECUTABLE_OUTPUT_DIR}") + else() + set(EXECUTABLE_OUTPUT_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + endif() + + # Where the intermediate CPP files will be placed + if(NRN_MECH_ARTIFACTS_OUTPUT_DIR) + set(ARTIFACTS_OUTPUT_DIR "${NRN_MECH_ARTIFACTS_OUTPUT_DIR}") + else() + set(ARTIFACTS_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + # Collect mod files, output any warnings + set(MOD_FILES "") foreach(MOD_FILE IN LISTS NRN_MECH_MOD_FILES) + if(NOT MOD_FILE MATCHES ".*mod$") + message(WARNING "File ${MOD_FILE} has an extension that is not .mod, compilation may fail") + endif() get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) list(APPEND INPUT_STUBS "${MOD_STUB}") list(APPEND MOD_FILES "${MOD_FILE}") endforeach() - foreach(MOD_FILE IN LISTS MOD_FILES) - get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) - # nocmodl has trouble with symlinks, so we always use the real path - get_filename_component(MOD_ABSPATH "${MOD_FILE}" REALPATH) - set(CPP_FILE "cpp/${MOD_STUB}.cpp") - file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_ABSPATH}") + # We later include the directories where the mod files in case people add headers in VERBATIM + # blocks + set(MOD_DIRECTORIES) - list(APPEND L_MECH_DECLARE "extern \"C\" void _${MOD_STUB}_reg(void)\;") - list(APPEND L_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") - list(APPEND L_MECH_REGISTRE "_${MOD_STUB}_reg()\;") + # Convert mod files for use with NEURON + if(NRN_MECH_NEURON) + # Convert to CPP files + foreach(MOD_FILE IN LISTS MOD_FILES) + get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) + # nocmodl has trouble with symlinks, so we always use the real path + get_filename_component(MOD_ABSPATH "${MOD_FILE}" REALPATH) + get_filename_component(MOD_DIRECTORY "${MOD_ABSPATH}" DIRECTORY) + if(NOT MOD_DIRECTORY IN_LIST MOD_DIRECTORIES) + list(APPEND MOD_DIRECTORIES "${MOD_DIRECTORY}") + endif() + set(CPP_FILE "cpp/${MOD_STUB}.cpp") + file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_ABSPATH}") - add_custom_command( - COMMAND neuron::nocmodl -o "${CMAKE_CURRENT_BINARY_DIR}/cpp" "${MOD_ABSPATH}" - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}" - DEPENDS neuron::nocmodl) + list(APPEND L_MECH_DECLARE "extern \"C\" void _${MOD_STUB}_reg(void)\;") + list(APPEND L_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") + list(APPEND L_MECH_REGISTRE "_${MOD_STUB}_reg()\;") - list(APPEND L_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}") - endforeach() + add_custom_command( + COMMAND ${ENV_COMMAND} ${NEURON_TRANSPILER_LAUNCHER} -o "${ARTIFACTS_OUTPUT_DIR}/cpp" + "${MOD_ABSPATH}" ${NRN_MECH_NMODL_EXTRA_ARGS} + OUTPUT "${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" + COMMENT "Converting ${MOD_ABSPATH} to ${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" + # TODO some mod files may include other files, and NMODL can get the AST of a given file in + # JSON form, which we could potentially parse with CMake and get the full list of + # dependencies + DEPENDS "${MOD_ABSPATH}" + VERBATIM) + + list(APPEND L_SOURCES "${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}") + endforeach() + + # add the nrnmech library + add_library(${TARGET_LIBRARY_NAME} ${LIBRARY_TYPE} ${L_SOURCES}) + set_target_properties( + ${TARGET_LIBRARY_NAME} PROPERTIES OUTPUT_NAME "${LIBNAME}" LIBRARY_OUTPUT_DIRECTORY + "${LIBRARY_OUTPUT_DIR}") + target_link_libraries(${TARGET_LIBRARY_NAME} PUBLIC neuron::nrniv) + # we need to add the `mech_func.cpp` file as well since it handles registration of mechanisms + list(JOIN L_MECH_DECLARE "\n" MECH_DECLARE) + list(JOIN L_MECH_PRINT " \n" MECH_PRINT) + list(JOIN L_MECH_REGISTRE " \n" MECH_REGISTRE) + get_filename_component(MECH_REG "${_NEURON_MECH_REG}" NAME_WLE) + configure_file(${_NEURON_MECH_REG} "${ARTIFACTS_OUTPUT_DIR}/${MECH_REG}" @ONLY) + target_sources(${TARGET_LIBRARY_NAME} PRIVATE "${ARTIFACTS_OUTPUT_DIR}/${MECH_REG}") + target_compile_definitions(${TARGET_LIBRARY_NAME} PUBLIC AUTO_DLOPEN_NRNMECH=0) + target_include_directories(${TARGET_LIBRARY_NAME} BEFORE PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) + # sometimes people will add `#include`s in VERBATIM blocks; usually those are in the same + # directory as the mod file, so let's add that as well + target_include_directories(${TARGET_LIBRARY_NAME} PRIVATE "${MOD_DIRECTORIES}") + + # add the special executable + if(NRN_MECH_SPECIAL) + add_executable(${TARGET_EXECUTABLE_NAME} ${_NEURON_MAIN} + "${ARTIFACTS_OUTPUT_DIR}/${MECH_REG}") + target_include_directories(${TARGET_EXECUTABLE_NAME} BEFORE + PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) + target_link_libraries(${TARGET_EXECUTABLE_NAME} PUBLIC ${TARGET_LIBRARY_NAME}) + set_target_properties( + ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special" RUNTIME_OUTPUT_DIRECTORY + "${EXECUTABLE_OUTPUT_DIR}") + endif() + + endif() + + # Convert mod files for use with coreNEURON if(NRN_MECH_CORENEURON) # CoreNEURON requires additional mod files. Only append them to the input list if similar named # mods are _not yet present_ file(GLOB BASE_MOD_FILES "${_CORENEURON_BASE_MOD}/*.mod") foreach(MOD_FILE IN LISTS BASE_MOD_FILES) get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) - if("${MOD_STUB}" IN_LIST INPUT_STUBS) - - else() + if(NOT "${MOD_STUB}" IN_LIST INPUT_STUBS) list(APPEND MOD_FILES "${MOD_FILE}") endif() endforeach() + # Convert to CPP files foreach(MOD_FILE IN LISTS MOD_FILES) get_filename_component(MOD_STUB "${MOD_FILE}" NAME_WLE) # nmodl _may_ have trouble with symlinks, so we always use the real path @@ -63,73 +286,54 @@ function(create_nrnmech) set(CPP_FILE "cpp_core/${MOD_STUB}.cpp") file(RELATIVE_PATH MOD_SHORT "${CMAKE_SOURCE_DIR}" "${MOD_ABSPATH}") - list(APPEND L_CORE_MECH_DECLARE "extern int void _${MOD_STUB}_reg(void)\;") + list(APPEND L_CORE_MECH_DECLARE "extern int _${MOD_STUB}_reg(void)\;") list(APPEND L_CORE_MECH_PRINT "fprintf(stderr, \" \\\"${MOD_SHORT}\\\"\")\;") list(APPEND L_CORE_MECH_REGISTRE "_${MOD_STUB}_reg()\;") add_custom_command( - COMMAND "${NMODL}" -o "${CMAKE_CURRENT_BINARY_DIR}/cpp_core" "${MOD_ABSPATH}" - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}" - DEPENDS "${NMODL}") + COMMAND ${ENV_COMMAND} ${NMODL_EXECUTABLE} -o "${ARTIFACTS_OUTPUT_DIR}/cpp_core" + "${MOD_ABSPATH}" ${NRN_MECH_NMODL_EXTRA_ARGS} + OUTPUT "${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" + COMMENT "Converting ${MOD_ABSPATH} to ${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" + DEPENDS "${MOD_ABSPATH}" + VERBATIM) - list(APPEND L_CORE_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${CPP_FILE}") + list(APPEND L_CORE_SOURCES "${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}") endforeach() - endif() - add_library(${LIBNAME} SHARED ${L_SOURCES}) - target_link_libraries(${LIBNAME} PUBLIC neuron::nrniv) - # set_target_properties(${LIBNAME} PROPERTIES OUTPUT_NAME - # "${LIBNAME}$<$:_${NRN_MECH_MECHANISM_NAME}>") - install(TARGETS ${LIBNAME} DESTINATION lib) + add_library(core${TARGET_LIBRARY_NAME} ${LIBRARY_TYPE} ${_CORENEURON_MECH_ENG} + ${L_CORE_SOURCES}) + set_target_properties( + core${TARGET_LIBRARY_NAME} PROPERTIES OUTPUT_NAME "core${LIBNAME}" LIBRARY_OUTPUT_DIRECTORY + "${LIBRARY_OUTPUT_DIR}") + target_include_directories(core${TARGET_LIBRARY_NAME} BEFORE + PUBLIC ${_CORENEURON_RANDOM_INCLUDE}) + target_compile_options(core${TARGET_LIBRARY_NAME} BEFORE PRIVATE ${_CORENEURON_FLAGS}) + target_link_libraries(core${TARGET_LIBRARY_NAME} PUBLIC neuron::corenrn) + target_compile_definitions(core${TARGET_LIBRARY_NAME} PUBLIC ADDITIONAL_MECHS) + # Random123 does not play nicely with NVHPC + target_compile_definitions(core${TARGET_LIBRARY_NAME} PUBLIC R123_USE_INTRIN_H=0) - if(NRN_MECH_CORENEURON) - add_library(core${LIBNAME} SHARED ${_CORENEURON_MECH_ENG} ${L_CORE_SOURCES}) - target_include_directories(core${LIBNAME} PRIVATE ${_CORENEURON_RANDOM_INCLUDE}) - target_compile_options(core${LIBNAME} PRIVATE ${_CORENEURON_FLAGS}) - target_link_libraries(core${LIBNAME} PUBLIC neuron::corenrn) - # set_target_properties(${LIBNAME} PROPERTIES OUTPUT_NAME - # "${LIBNAME}$<$:_${NRN_MECH_MECHANISM_NAME}>") - install(TARGETS core${LIBNAME} DESTINATION lib) - endif() - - if(NRN_MECH_INSTALL_CPP) - install(FILES ${L_SOURCES} DESTINATION "share/${NRN_MECH_MECHANISM_NAME}/cpp") - if(NRN_ENABLE_CORENEURON) - install(FILES ${L_CORE_SOURCES} DESTINATION "share/${NRN_MECH_MECHANISM_NAME}/cpp_core") - endif() - endif() + list(JOIN L_CORE_MECH_DECLARE "\n" MECH_DECLARE) + list(JOIN L_CORE_MECH_PRINT " \n" MECH_PRINT) + list(JOIN L_CORE_MECH_REGISTRE " \n" MECH_REGISTRE) - if(NRN_MECH_INSTALL_MOD) - install(FILES ${MOD_FILES} DESTINATION "share/${NRN_MECH_MECHANISM_NAME}/mod") - endif() + get_filename_component(CORE_MECH_REG "${_CORENEURON_MECH_REG}" NAME_WLE) + configure_file(${_CORENEURON_MECH_REG} "${ARTIFACTS_OUTPUT_DIR}/core${CORE_MECH_REG}" @ONLY) - if(NRN_MECH_SPECIAL) - list(JOIN L_MECH_DECLARE "\n" MECH_DECLARE) - list(JOIN L_MECH_PRINT " \n" MECH_PRINT) - list(JOIN L_MECH_REGISTRE " \n" MECH_REGISTRE) + target_sources(core${TARGET_LIBRARY_NAME} + PRIVATE "${ARTIFACTS_OUTPUT_DIR}/core${CORE_MECH_REG}") - get_filename_component(MECH_REG "${_NEURON_MECH_REG}" NAME_WLE) - configure_file(${_NEURON_MECH_REG} ${MECH_REG} @ONLY) - - add_executable(${EXENAME} ${_NEURON_MAIN} ${MECH_REG}) - target_include_directories(${EXENAME} PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) - target_link_libraries(${EXENAME} ${LIBNAME}) - set_target_properties(${EXENAME} PROPERTIES OUTPUT_NAME "special") - install(TARGETS ${EXENAME} DESTINATION bin) - - if(NRN_MECH_CORENEURON) - list(JOIN L_CORE_MECH_DECLARE "\n" MECH_DECLARE) - list(JOIN L_CORE_MECH_PRINT " \n" MECH_PRINT) - list(JOIN L_CORE_MECH_REGISTRE " \n" MECH_REGISTRE) - - get_filename_component(CORE_MECH_REG "${_NEURON_COREMECH_REG}" NAME_WLE) - configure_file(${_NEURON_MECH_REG} core${CORE_MECH_REG} @ONLY) - - add_executable(core${EXENAME} ${_CORENEURON_MAIN} core${CORE_MECH_REG}) - target_include_directories(core${EXENAME} PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) - target_link_libraries(core${EXENAME} core${LIBNAME}) - set_target_properties(core${EXENAME} PROPERTIES OUTPUT_NAME "special-core") - install(TARGETS core${EXENAME} DESTINATION bin) + if(NRN_MECH_SPECIAL) + add_executable(core${TARGET_EXECUTABLE_NAME} ${_CORENEURON_MAIN} + "${ARTIFACTS_OUTPUT_DIR}/core${CORE_MECH_REG}") + target_include_directories(core${TARGET_EXECUTABLE_NAME} BEFORE + PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) + target_link_libraries(core${TARGET_EXECUTABLE_NAME} PUBLIC core${TARGET_LIBRARY_NAME}) + target_compile_definitions(core${TARGET_EXECUTABLE_NAME} PUBLIC ADDITIONAL_MECHS) + set_target_properties( + core${TARGET_EXECUTABLE_NAME} + PROPERTIES OUTPUT_NAME "special-core" RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_DIR}") endif() endif() endfunction() From f0eaccc135e2e88c67e4e8e9659b73c37aaed9d6 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 3 Jun 2025 16:39:30 +0200 Subject: [PATCH 19/63] Remove comments --- src/nrnpython/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/nrnpython/CMakeLists.txt b/src/nrnpython/CMakeLists.txt index f1d9100256..ae091104b7 100644 --- a/src/nrnpython/CMakeLists.txt +++ b/src/nrnpython/CMakeLists.txt @@ -57,10 +57,6 @@ endif() # user has selected dynamic python support (could be multiple versions) if(NRN_ENABLE_PYTHON_DYNAMIC) - # set(INCLUDE_DIRS . .. ../oc ../nrnoc ../ivoc ../nrniv ../gnu ../nrnmpi - # ${PROJECT_BINARY_DIR}/src/nrnpython ${PROJECT_BINARY_DIR}/src/ivos ${PROJECT_BINARY_DIR}/src/oc - # ${NRN_OC_GENERATED_SOURCES}) if(NRN_ENABLE_INTERVIEWS) list(APPEND INCLUDE_DIRS - # ${IV_INCLUDE_DIR}) else() list(APPEND INCLUDE_DIRS ../ivos) endif() foreach(val RANGE ${NRN_PYTHON_ITERATION_LIMIT}) # the NEURON Python library (with nanobind) From c0f168afed2a79955112e434dcf2782c043c0c6c Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 13:30:01 +0200 Subject: [PATCH 20/63] Add tentative test --- test/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3af9cf9ae2..43dad54b22 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -826,3 +826,8 @@ if((NRN_ENABLE_NMODL OR NRN_ENABLE_CORENEURON) AND NRN_ENABLE_TESTS) add_subdirectory(nmodl/transpiler/usecases) endif() endif() + +# Test nrnivmodl-cmake +if(NRN_ENABLE_CORENEURON AND NRN_ENABLE_TESTS) + add_subdirectory(nrnivmodl-cmake) +endif() From 758142c7e3eb2f75bd541f0c5ef2c14419c31000 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 13:41:34 +0200 Subject: [PATCH 21/63] Neuron config --- CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac634fbae8..b2348de183 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1110,7 +1110,18 @@ endif() # ============================================================================= # Install CMake glue # ============================================================================= +configure_file(cmake/neuronMechMaker.cmake + "${PROJECT_BINARY_DIR}/lib/cmake/neuron/neuronMechMaker.cmake" COPYONLY) +configure_file(cmake/mod_reg_nrn.cpp.in "${PROJECT_BINARY_DIR}/share/nrn/mod_reg_nrn.cpp.in" + COPYONLY) +configure_file(cmake/mod_reg_corenrn.cpp.in + "${PROJECT_BINARY_DIR}/share/nrn/mod_reg_corenrn.cpp.in" COPYONLY) install(TARGETS ${NRN_INSTALL_TARGETS} ${CORENRN_INSTALL_TARGETS} EXPORT NeuronTargets) +export( + EXPORT NeuronTargets + FILE ${PROJECT_BINARY_DIR}/lib/cmake/neuron/neuronTargets.cmake + NAMESPACE neuron::) + install( EXPORT NeuronTargets FILE neuronTargets.cmake @@ -1118,7 +1129,7 @@ install( DESTINATION lib/cmake/neuron) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/neuronConfig.cmake @ONLY) + ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/neuronConfig.cmake DESTINATION lib/cmake/neuron) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake DESTINATION lib/cmake/neuron) From 32c2cc17bd217530f23da2160bae9ac3e9927a16 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 14:07:57 +0200 Subject: [PATCH 22/63] Fix include paths Also finally add (hacky) test --- cmake/neuronConfig.cmake.in | 4 ++-- test/nrnivmodl-cmake/CMakeLists.txt | 20 +++++++++++++++++++ .../build_cmake/CMakeLists.txt | 6 ++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 test/nrnivmodl-cmake/CMakeLists.txt create mode 100644 test/nrnivmodl-cmake/build_cmake/CMakeLists.txt diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index 2375f0d608..68c6252459 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -10,14 +10,14 @@ get_filename_component(_prefix "${_dir}/../../.." ABSOLUTE) set(NRN_ENABLE_CORENEURON @NRN_ENABLE_CORENEURON@) set(_NEURON_MAIN "${_prefix}/share/nrn/nrnmain.cpp") -set(_NEURON_MAIN_INCLUDE_DIR "${_prefix}/include/nrncvode") +set(_NEURON_MAIN_INCLUDE_DIR "${_prefix}/include/nrncvode" "${_prefix}/include") set(_NEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_nrn.cpp.in") set(_CORENEURON_BASE_MOD "${_prefix}/share/modfile") set(_CORENEURON_MAIN "${_prefix}/share/coreneuron/coreneuron.cpp") set(_CORENEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_corenrn.cpp.in") set(_CORENEURON_MECH_ENG "${_prefix}/share/coreneuron/enginemech.cpp") -set(_CORENEURON_RANDOM_INCLUDE "${_prefix}/include/coreneuron/utils/randoms") +set(_CORENEURON_RANDOM_INCLUDE "${_prefix}/include/coreneuron/utils/randoms" "${_prefix}/include") set(_CORENEURON_FLAGS @CORENRN_CXX_FLAGS@) find_program(NMODL nmodl REQUIRED) diff --git a/test/nrnivmodl-cmake/CMakeLists.txt b/test/nrnivmodl-cmake/CMakeLists.txt new file mode 100644 index 0000000000..5cbe720a8f --- /dev/null +++ b/test/nrnivmodl-cmake/CMakeLists.txt @@ -0,0 +1,20 @@ +# ~~~ +# Test for `create_nrnmech` as if it was already installed +# ~~~ +set(TEST_NAMESPACE "nrnivmodl-cmake") +set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/build_cmake") +file(GLOB MOD_FILES "${PROJECT_SOURCE_DIR}/test/coreneuron/mod files/*.mod") + +# This is admittedly a bit hacky, but we are launching CMake inside of CMake, and we cannot use any +# of the set variables, either via CMake itself, or through the env. The only thing that must be +# available is the NEURON CMake config file, and NMODL must be in PATH at CMake configure time. +add_test( + NAME "${TEST_NAMESPACE}::modfiles" + COMMAND + sh -c + "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ + ${CMAKE_COMMAND} -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' -DMOD_FILES='${MOD_FILES}' \ + && \ + ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ + && \ + rm -fr '${TEST_DIR}'") diff --git a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt new file mode 100644 index 0000000000..b71dffea71 --- /dev/null +++ b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.15) +project(modfile_test CXX) + +find_package(neuron REQUIRED) + +create_nrnmech(CORENEURON MOD_FILES ${MOD_FILES}) From 6a8ed75579371b02d29d7dcf4f28a659969e11b8 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 14:21:52 +0200 Subject: [PATCH 23/63] Add NEURON and special --- test/nrnivmodl-cmake/CMakeLists.txt | 1 + test/nrnivmodl-cmake/build_cmake/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/nrnivmodl-cmake/CMakeLists.txt b/test/nrnivmodl-cmake/CMakeLists.txt index 5cbe720a8f..a62657a21b 100644 --- a/test/nrnivmodl-cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/CMakeLists.txt @@ -17,4 +17,5 @@ add_test( && \ ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ && \ + '${TEST_DIR}/special' -nobanner -nogui -c 'quit()' \ rm -fr '${TEST_DIR}'") diff --git a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt index b71dffea71..da4f2733bd 100644 --- a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt @@ -3,4 +3,4 @@ project(modfile_test CXX) find_package(neuron REQUIRED) -create_nrnmech(CORENEURON MOD_FILES ${MOD_FILES}) +create_nrnmech(NEURON CORENEURON SPECIAL MOD_FILES ${MOD_FILES}) From 6988505682a244b4665c3ac6e0663683920bb434 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 14:41:03 +0200 Subject: [PATCH 24/63] Formatting --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 43dad54b22..e6f37005c9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -829,5 +829,5 @@ endif() # Test nrnivmodl-cmake if(NRN_ENABLE_CORENEURON AND NRN_ENABLE_TESTS) - add_subdirectory(nrnivmodl-cmake) + add_subdirectory(nrnivmodl-cmake) endif() From b00f3dcefeb828b262cd63102d19e8c172fb24ed Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 14:46:40 +0200 Subject: [PATCH 25/63] Better config --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2348de183..15d05c0829 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1131,7 +1131,7 @@ install( configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/neuronConfig.cmake DESTINATION lib/cmake/neuron) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake DESTINATION lib/cmake/neuron) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake DESTINATION lib/cmake/neuron) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_nrn.cpp.in From 535bb1c57bdbdb8c7e942351d859b89ff901621e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 14:56:14 +0200 Subject: [PATCH 26/63] Formatting --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15d05c0829..1a347aa497 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1131,7 +1131,8 @@ install( configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake DESTINATION lib/cmake/neuron) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake + DESTINATION lib/cmake/neuron) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake DESTINATION lib/cmake/neuron) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_nrn.cpp.in From 3a7bb988b220c4ed4f8421d6c0f747f81c7a28d3 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 16:01:11 +0200 Subject: [PATCH 27/63] Appease MODLUNIT --- test/CMakeLists.txt | 2 +- test/nrnivmodl-cmake/CMakeLists.txt | 11 ++++++++--- test/nrnivmodl-cmake/build_cmake/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e6f37005c9..a95667bdd6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -828,6 +828,6 @@ if((NRN_ENABLE_NMODL OR NRN_ENABLE_CORENEURON) AND NRN_ENABLE_TESTS) endif() # Test nrnivmodl-cmake -if(NRN_ENABLE_CORENEURON AND NRN_ENABLE_TESTS) +if(NRN_ENABLE_TESTS) add_subdirectory(nrnivmodl-cmake) endif() diff --git a/test/nrnivmodl-cmake/CMakeLists.txt b/test/nrnivmodl-cmake/CMakeLists.txt index a62657a21b..f66e1e99ff 100644 --- a/test/nrnivmodl-cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/CMakeLists.txt @@ -2,18 +2,23 @@ # Test for `create_nrnmech` as if it was already installed # ~~~ set(TEST_NAMESPACE "nrnivmodl-cmake") -set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/build_cmake") file(GLOB MOD_FILES "${PROJECT_SOURCE_DIR}/test/coreneuron/mod files/*.mod") # This is admittedly a bit hacky, but we are launching CMake inside of CMake, and we cannot use any # of the set variables, either via CMake itself, or through the env. The only thing that must be # available is the NEURON CMake config file, and NMODL must be in PATH at CMake configure time. +set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/build_cmake") +if(NRN_ENABLE_CORENEURON) + set(CORENEURON CORENEURON) +endif() add_test( NAME "${TEST_NAMESPACE}::modfiles" COMMAND sh -c - "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ - ${CMAKE_COMMAND} -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' -DMOD_FILES='${MOD_FILES}' \ + "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ + PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ + MODLUNIT='${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib' \ + ${CMAKE_COMMAND} -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' -DMOD_FILES='${MOD_FILES}' -DCORENEURON=${CORENEURON} \ && \ ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ && \ diff --git a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt index da4f2733bd..737abf33fb 100644 --- a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt @@ -3,4 +3,4 @@ project(modfile_test CXX) find_package(neuron REQUIRED) -create_nrnmech(NEURON CORENEURON SPECIAL MOD_FILES ${MOD_FILES}) +create_nrnmech(NEURON ${CORENEURON} SPECIAL MOD_FILES ${MOD_FILES}) From 908dc4e3dbcfe2372bf1b3b4760f48eb7af5dd65 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 4 Jun 2025 18:09:01 +0200 Subject: [PATCH 28/63] Workaround for NOCMODL --- cmake/neuronMechMaker.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 6e41878e5c..3c94c76a01 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -148,6 +148,12 @@ function(create_nrnmech) set(ENV_COMMAND) endif() + # nocmodl sometimes does not work due to lack of MODLUNIT, see: + # https://github.com/neuronsimulator/nrn/issues/3470 + if(DEFINED ENV{MODLUNIT}) + list(APPEND ENV_COMMAND "MODLUNIT=$ENV{MODLUNIT}") + endif() + # Override the _target_ name, but not the library name. This is useful when we are using this # function for building NEURON components, since we may experience collisions in the target names if(NRN_MECH_TARGET_LIBRARY_NAME) From 1462039e1fccd94e174bef6e4a6674c3cf35f28b Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 5 Jun 2025 12:09:52 +0200 Subject: [PATCH 29/63] Use same compiler as used by system --- test/nrnivmodl-cmake/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/nrnivmodl-cmake/CMakeLists.txt b/test/nrnivmodl-cmake/CMakeLists.txt index f66e1e99ff..773408aa57 100644 --- a/test/nrnivmodl-cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/CMakeLists.txt @@ -14,11 +14,15 @@ endif() add_test( NAME "${TEST_NAMESPACE}::modfiles" COMMAND - sh -c - "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ + sh -c "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ MODLUNIT='${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib' \ - ${CMAKE_COMMAND} -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' -DMOD_FILES='${MOD_FILES}' -DCORENEURON=${CORENEURON} \ + ${CMAKE_COMMAND} \ + -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' \ + -DMOD_FILES='${MOD_FILES}' \ + -DCORENEURON=${CORENEURON} \ + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} \ + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} \ && \ ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ && \ From 446fb4836ad5d84fbdf865fa8b745e89913759bd Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 5 Jun 2025 13:13:45 +0200 Subject: [PATCH 30/63] Disable CMake mechanism test if using sanitizers --- test/CMakeLists.txt | 5 +++-- test/nrnivmodl-cmake/build_cmake/CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a95667bdd6..4fde4a072f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -827,7 +827,8 @@ if((NRN_ENABLE_NMODL OR NRN_ENABLE_CORENEURON) AND NRN_ENABLE_TESTS) endif() endif() -# Test nrnivmodl-cmake -if(NRN_ENABLE_TESTS) +# Test nrnivmodl-cmake, but only without sanitizers since those cause issues, and end-users won't +# get builds with sanitizer builds anyway +if(NRN_ENABLE_TESTS AND NOT NRN_SANITIZERS) add_subdirectory(nrnivmodl-cmake) endif() diff --git a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt index 737abf33fb..836884d5cc 100644 --- a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(modfile_test CXX) +project(modfile_test LANGUAGES C CXX) find_package(neuron REQUIRED) From ebbe6f5000399884f273ac38134a62664de4cac4 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 5 Jun 2025 14:59:42 +0200 Subject: [PATCH 31/63] Use `-nopython` when launching `special` --- test/nrnivmodl-cmake/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/nrnivmodl-cmake/CMakeLists.txt b/test/nrnivmodl-cmake/CMakeLists.txt index 773408aa57..f3cb8be679 100644 --- a/test/nrnivmodl-cmake/CMakeLists.txt +++ b/test/nrnivmodl-cmake/CMakeLists.txt @@ -6,7 +6,9 @@ file(GLOB MOD_FILES "${PROJECT_SOURCE_DIR}/test/coreneuron/mod files/*.mod") # This is admittedly a bit hacky, but we are launching CMake inside of CMake, and we cannot use any # of the set variables, either via CMake itself, or through the env. The only thing that must be -# available is the NEURON CMake config file, and NMODL must be in PATH at CMake configure time. +# available is the NEURON CMake config file, and NMODL must be in PATH at CMake configure time. Note +# that we do not try to use Python abilities of `special`, since those require setting env +# variables, which the user may not be aware of. set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/build_cmake") if(NRN_ENABLE_CORENEURON) set(CORENEURON CORENEURON) @@ -20,11 +22,12 @@ add_test( ${CMAKE_COMMAND} \ -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' \ -DMOD_FILES='${MOD_FILES}' \ + -DCMAKE_BUILD_TYPE=Debug \ -DCORENEURON=${CORENEURON} \ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} \ -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} \ && \ ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ && \ - '${TEST_DIR}/special' -nobanner -nogui -c 'quit()' \ + '${TEST_DIR}/special' -nopython -nobanner -nogui -c 'quit()' \ rm -fr '${TEST_DIR}'") From 81c1d1f326b3a02a66c4b3c6fad0a679b0b4c81e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 5 Jun 2025 16:14:50 +0200 Subject: [PATCH 32/63] Disable test on coverage as well --- test/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4fde4a072f..809bc84722 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -828,7 +828,9 @@ if((NRN_ENABLE_NMODL OR NRN_ENABLE_CORENEURON) AND NRN_ENABLE_TESTS) endif() # Test nrnivmodl-cmake, but only without sanitizers since those cause issues, and end-users won't -# get builds with sanitizer builds anyway -if(NRN_ENABLE_TESTS AND NOT NRN_SANITIZERS) +# get builds with sanitizer builds anyway. The same reasoning applies to coverage. +if(NRN_ENABLE_TESTS + AND NOT NRN_SANITIZERS + AND NOT NRN_ENABLE_COVERAGE) add_subdirectory(nrnivmodl-cmake) endif() From b08e7720ed7fa4b28052999291993a56d579233e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 17 Jun 2025 10:21:23 +0200 Subject: [PATCH 33/63] Small changes --- cmake/MacroHelper.cmake | 27 ------------------- test/CMakeLists.txt | 2 +- .../CMakeLists.txt | 26 ++++++++++++------ .../build_cmake/CMakeLists.txt | 2 +- 4 files changed, 20 insertions(+), 37 deletions(-) rename test/{nrnivmodl-cmake => nrnivmodl_cmake}/CMakeLists.txt (61%) rename test/{nrnivmodl-cmake => nrnivmodl_cmake}/build_cmake/CMakeLists.txt (72%) diff --git a/cmake/MacroHelper.cmake b/cmake/MacroHelper.cmake index b3397483cb..caa26b58fb 100644 --- a/cmake/MacroHelper.cmake +++ b/cmake/MacroHelper.cmake @@ -11,33 +11,6 @@ include(CMakeParseArguments) set(CMAKE_REQUIRED_QUIET TRUE) -# ============================================================================= -# Check if directory related to DIR exists by compiling code -# ============================================================================= -macro(nrn_check_dir_exists HEADER VARIABLE) - # code template to check existence of DIR - string( - CONCAT CONFTEST_DIR_TPL - "#include \n" - "#include <@dir_header@>\n" - "int main () {\n" - " if ((DIR *) 0)\n" - " return 0\;\n" - " return 0\;\n" - "}\n") - # first get header file - check_include_files(${HEADER} HAVE_HEADER) - if(${HAVE_HEADER}) - # if header is found, create a code from template - string(REPLACE "@dir_header@" ${HEADER} CONFTEST_DIR "${CONFTEST_DIR_TPL}") - file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/conftest.cpp" ${CONFTEST_DIR}) - # try to compile - try_compile(${VARIABLE} "${CMAKE_CURRENT_SOURCE_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/conftest.cpp") - file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/conftest.cpp") - endif() -endmacro() - # ============================================================================= # Check if given type exists by compiling code # ============================================================================= diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 809bc84722..8bbc2684cc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -832,5 +832,5 @@ endif() if(NRN_ENABLE_TESTS AND NOT NRN_SANITIZERS AND NOT NRN_ENABLE_COVERAGE) - add_subdirectory(nrnivmodl-cmake) + add_subdirectory(nrnivmodl_cmake) endif() diff --git a/test/nrnivmodl-cmake/CMakeLists.txt b/test/nrnivmodl_cmake/CMakeLists.txt similarity index 61% rename from test/nrnivmodl-cmake/CMakeLists.txt rename to test/nrnivmodl_cmake/CMakeLists.txt index f3cb8be679..451b111531 100644 --- a/test/nrnivmodl-cmake/CMakeLists.txt +++ b/test/nrnivmodl_cmake/CMakeLists.txt @@ -1,7 +1,7 @@ # ~~~ # Test for `create_nrnmech` as if it was already installed # ~~~ -set(TEST_NAMESPACE "nrnivmodl-cmake") +set(TEST_NAMESPACE "nrnivmodl_cmake") file(GLOB MOD_FILES "${PROJECT_SOURCE_DIR}/test/coreneuron/mod files/*.mod") # This is admittedly a bit hacky, but we are launching CMake inside of CMake, and we cannot use any @@ -9,23 +9,33 @@ file(GLOB MOD_FILES "${PROJECT_SOURCE_DIR}/test/coreneuron/mod files/*.mod") # available is the NEURON CMake config file, and NMODL must be in PATH at CMake configure time. Note # that we do not try to use Python abilities of `special`, since those require setting env # variables, which the user may not be aware of. -set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/build_cmake") +set(TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/build_cmake/build") if(NRN_ENABLE_CORENEURON) set(CORENEURON CORENEURON) endif() -add_test( - NAME "${TEST_NAMESPACE}::modfiles" - COMMAND - sh -c "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ +# we need to enable CUDA if using NVHPC, otherwise the flags are not propagated properly +if(CMAKE_CUDA_COMPILER) + set(CUDA_STRING "CUDA") +endif() +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build_cmake/CMakeLists.txt" "${CMAKE_CURRENT_BINARY_DIR}/build_cmake/CMakeLists.txt" @ONLY) +set(test_command +"CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ MODLUNIT='${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib' \ ${CMAKE_COMMAND} \ - -S '${CMAKE_CURRENT_SOURCE_DIR}/build_cmake' -B '${TEST_DIR}' \ + -S '${CMAKE_CURRENT_BINARY_DIR}/build_cmake' -B '${TEST_DIR}' \ -DMOD_FILES='${MOD_FILES}' \ -DCMAKE_BUILD_TYPE=Debug \ -DCORENEURON=${CORENEURON} \ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} \ - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} \ + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") +if(CMAKE_LANGUAGES MATCHES "CUDA") + set(test_command "${test_command} -DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}") +endif() +add_test( + NAME "${TEST_NAMESPACE}::modfiles" + COMMAND + sh -c "${test_command} \ && \ ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ && \ diff --git a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt b/test/nrnivmodl_cmake/build_cmake/CMakeLists.txt similarity index 72% rename from test/nrnivmodl-cmake/build_cmake/CMakeLists.txt rename to test/nrnivmodl_cmake/build_cmake/CMakeLists.txt index 836884d5cc..fd8ccf52e0 100644 --- a/test/nrnivmodl-cmake/build_cmake/CMakeLists.txt +++ b/test/nrnivmodl_cmake/build_cmake/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(modfile_test LANGUAGES C CXX) +project(modfile_test LANGUAGES C CXX @CUDA_STRING@) find_package(neuron REQUIRED) From af6aa53b53693e58868a816968c2b4ade4a05c1f Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 17 Jun 2025 13:16:29 +0200 Subject: [PATCH 34/63] Fix for building special-core on NVHPC --- cmake/coreneuron/OpenAccHelper.cmake | 2 ++ cmake/neuronConfig.cmake.in | 5 ++++- cmake/neuronMechMaker.cmake | 1 + test/nrnivmodl_cmake/CMakeLists.txt | 4 +++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmake/coreneuron/OpenAccHelper.cmake b/cmake/coreneuron/OpenAccHelper.cmake index 113ab18703..c66b8d18a6 100644 --- a/cmake/coreneuron/OpenAccHelper.cmake +++ b/cmake/coreneuron/OpenAccHelper.cmake @@ -95,6 +95,8 @@ if(CORENRN_ENABLE_GPU) # Use of `-Mautoinline` ensure that the necessary functions like `net_receive_kernel` are inlined # for OpenACC code generation. set(NVHPC_CXX_INLINE_FLAGS "-Mautoinline") + # The cmake version of nrnivmodl needs cuda flags for special-core, which are nested in scopes in scopes, so we set an internal cache variable instead + set(NRNIVMODL_CORENEURON_INTERNAL_EXE_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE INTERNAL "CUDA flags for special-core") endif() # ============================================================================= diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index 68c6252459..c1791da63b 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -19,7 +19,10 @@ set(_CORENEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_corenrn.cpp.in") set(_CORENEURON_MECH_ENG "${_prefix}/share/coreneuron/enginemech.cpp") set(_CORENEURON_RANDOM_INCLUDE "${_prefix}/include/coreneuron/utils/randoms" "${_prefix}/include") set(_CORENEURON_FLAGS @CORENRN_CXX_FLAGS@) +set(_CORENEURON_EXE_LINKER_FLAGS @NRNIVMODL_CORENEURON_INTERNAL_EXE_LINK_FLAGS@) -find_program(NMODL nmodl REQUIRED) +if(@NRN_ENABLE_CORENEURON@) + find_program(NMODL nmodl REQUIRED) +endif() include(${CMAKE_CURRENT_LIST_DIR}/neuronMechMaker.cmake) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 3c94c76a01..a7d456fe36 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -340,6 +340,7 @@ function(create_nrnmech) set_target_properties( core${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special-core" RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_DIR}") + target_link_options(core${TARGET_EXECUTABLE_NAME} PRIVATE "${_CORENEURON_EXE_LINKER_FLAGS}") endif() endif() endfunction() diff --git a/test/nrnivmodl_cmake/CMakeLists.txt b/test/nrnivmodl_cmake/CMakeLists.txt index 451b111531..f6cb8be90b 100644 --- a/test/nrnivmodl_cmake/CMakeLists.txt +++ b/test/nrnivmodl_cmake/CMakeLists.txt @@ -35,7 +35,9 @@ endif() add_test( NAME "${TEST_NAMESPACE}::modfiles" COMMAND - sh -c "${test_command} \ + sh -c " + rm -fr ${TEST_DIR} \ + && ${test_command} \ && \ ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ && \ From 6194db88ef0995309bd475b96dc844f8ffd7f36e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 17 Jun 2025 13:23:15 +0200 Subject: [PATCH 35/63] Fix formatting --- cmake/coreneuron/OpenAccHelper.cmake | 7 +++++-- cmake/neuronMechMaker.cmake | 2 +- test/nrnivmodl_cmake/CMakeLists.txt | 9 +++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/cmake/coreneuron/OpenAccHelper.cmake b/cmake/coreneuron/OpenAccHelper.cmake index c66b8d18a6..8a0203f412 100644 --- a/cmake/coreneuron/OpenAccHelper.cmake +++ b/cmake/coreneuron/OpenAccHelper.cmake @@ -95,8 +95,11 @@ if(CORENRN_ENABLE_GPU) # Use of `-Mautoinline` ensure that the necessary functions like `net_receive_kernel` are inlined # for OpenACC code generation. set(NVHPC_CXX_INLINE_FLAGS "-Mautoinline") - # The cmake version of nrnivmodl needs cuda flags for special-core, which are nested in scopes in scopes, so we set an internal cache variable instead - set(NRNIVMODL_CORENEURON_INTERNAL_EXE_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE INTERNAL "CUDA flags for special-core") + # The cmake version of nrnivmodl needs cuda flags for special-core, which are nested in scopes in + # scopes, so we set an internal cache variable instead + set(NRNIVMODL_CORENEURON_INTERNAL_EXE_LINK_FLAGS + "${CMAKE_EXE_LINKER_FLAGS}" + CACHE INTERNAL "CUDA flags for special-core") endif() # ============================================================================= diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index a7d456fe36..33d2512ae2 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -340,7 +340,7 @@ function(create_nrnmech) set_target_properties( core${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special-core" RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_DIR}") - target_link_options(core${TARGET_EXECUTABLE_NAME} PRIVATE "${_CORENEURON_EXE_LINKER_FLAGS}") + target_link_options(core${TARGET_EXECUTABLE_NAME} PRIVATE "${_CORENEURON_EXE_LINKER_FLAGS}") endif() endif() endfunction() diff --git a/test/nrnivmodl_cmake/CMakeLists.txt b/test/nrnivmodl_cmake/CMakeLists.txt index f6cb8be90b..50e1d9dabd 100644 --- a/test/nrnivmodl_cmake/CMakeLists.txt +++ b/test/nrnivmodl_cmake/CMakeLists.txt @@ -15,11 +15,12 @@ if(NRN_ENABLE_CORENEURON) endif() # we need to enable CUDA if using NVHPC, otherwise the flags are not propagated properly if(CMAKE_CUDA_COMPILER) - set(CUDA_STRING "CUDA") + set(CUDA_STRING "CUDA") endif() -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build_cmake/CMakeLists.txt" "${CMAKE_CURRENT_BINARY_DIR}/build_cmake/CMakeLists.txt" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build_cmake/CMakeLists.txt" + "${CMAKE_CURRENT_BINARY_DIR}/build_cmake/CMakeLists.txt" @ONLY) set(test_command -"CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ + "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ MODLUNIT='${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib' \ ${CMAKE_COMMAND} \ @@ -30,7 +31,7 @@ set(test_command -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} \ -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") if(CMAKE_LANGUAGES MATCHES "CUDA") - set(test_command "${test_command} -DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}") + set(test_command "${test_command} -DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}") endif() add_test( NAME "${TEST_NAMESPACE}::modfiles" From 5497de036c7171b6abd4168741c70a0798b5f9cb Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 18 Jun 2025 15:00:26 +0200 Subject: [PATCH 36/63] More flexibility for CUDA detection --- cmake/coreneuron/OpenAccHelper.cmake | 5 ----- cmake/neuronConfig.cmake.in | 5 ----- cmake/neuronMechMaker.cmake | 28 ++++++++++++++++++++++++---- src/coreneuron/CMakeLists.txt | 4 ++-- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/cmake/coreneuron/OpenAccHelper.cmake b/cmake/coreneuron/OpenAccHelper.cmake index 8a0203f412..113ab18703 100644 --- a/cmake/coreneuron/OpenAccHelper.cmake +++ b/cmake/coreneuron/OpenAccHelper.cmake @@ -95,11 +95,6 @@ if(CORENRN_ENABLE_GPU) # Use of `-Mautoinline` ensure that the necessary functions like `net_receive_kernel` are inlined # for OpenACC code generation. set(NVHPC_CXX_INLINE_FLAGS "-Mautoinline") - # The cmake version of nrnivmodl needs cuda flags for special-core, which are nested in scopes in - # scopes, so we set an internal cache variable instead - set(NRNIVMODL_CORENEURON_INTERNAL_EXE_LINK_FLAGS - "${CMAKE_EXE_LINKER_FLAGS}" - CACHE INTERNAL "CUDA flags for special-core") endif() # ============================================================================= diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index c1791da63b..495b6c9ee4 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -19,10 +19,5 @@ set(_CORENEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_corenrn.cpp.in") set(_CORENEURON_MECH_ENG "${_prefix}/share/coreneuron/enginemech.cpp") set(_CORENEURON_RANDOM_INCLUDE "${_prefix}/include/coreneuron/utils/randoms" "${_prefix}/include") set(_CORENEURON_FLAGS @CORENRN_CXX_FLAGS@) -set(_CORENEURON_EXE_LINKER_FLAGS @NRNIVMODL_CORENEURON_INTERNAL_EXE_LINK_FLAGS@) - -if(@NRN_ENABLE_CORENEURON@) - find_program(NMODL nmodl REQUIRED) -endif() include(${CMAKE_CURRENT_LIST_DIR}/neuronMechMaker.cmake) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 33d2512ae2..df3a60f98e 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -103,7 +103,7 @@ function(create_nrnmech) if(NRN_MECH_NMODL_EXECUTABLE) set(NMODL_EXECUTABLE "${NRN_MECH_NMODL_EXECUTABLE}") else() - set(NMODL_EXECUTABLE "${NMODL}") + set(NMODL_EXECUTABLE $) endif() if(NRN_MECH_NOCMODL_EXECUTABLE) @@ -317,8 +317,29 @@ function(create_nrnmech) target_compile_options(core${TARGET_LIBRARY_NAME} BEFORE PRIVATE ${_CORENEURON_FLAGS}) target_link_libraries(core${TARGET_LIBRARY_NAME} PUBLIC neuron::corenrn) target_compile_definitions(core${TARGET_LIBRARY_NAME} PUBLIC ADDITIONAL_MECHS) - # Random123 does not play nicely with NVHPC - target_compile_definitions(core${TARGET_LIBRARY_NAME} PUBLIC R123_USE_INTRIN_H=0) + + if(CMAKE_CUDA_COMPILER) + # Find the cuda toolkit and openacc (if not found already) + if(NOT CUDAToolkit_FOUND) + find_package(CUDAToolkit 9.0 REQUIRED) + endif() + if(NOT OpenACC_FOUND) + find_package(OpenACC REQUIRED) + endif() + # Random123 does not play nicely with NVHPC + target_compile_definitions(core${TARGET_LIBRARY_NAME} PUBLIC R123_USE_INTRIN_H=0) + # if using NVHPC, link corenrnmech lib to the CUDA runtime and openacc + if("${LIBRARY_TYPE}" STREQUAL "STATIC") + target_link_libraries(core${TARGET_LIBRARY_NAME} PUBLIC CUDA::cudart_static + OpenACC::OpenACC_CXX) + elseif("${LIBRARY_TYPE}" STREQUAL "SHARED") + target_link_libraries(core${TARGET_LIBRARY_NAME} PUBLIC CUDA::cudart OpenACC::OpenACC_CXX) + else() + message(FATAL_ERROR "Unsupported library type for CUDA: ${LIBRARY_TYPE}") + endif() + # for some reason we need to add `-cuda` to nrnmech (which gets propagated to special-core) + target_link_options(core${TARGET_LIBRARY_NAME} PUBLIC "-cuda") + endif() list(JOIN L_CORE_MECH_DECLARE "\n" MECH_DECLARE) list(JOIN L_CORE_MECH_PRINT " \n" MECH_PRINT) @@ -340,7 +361,6 @@ function(create_nrnmech) set_target_properties( core${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special-core" RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_DIR}") - target_link_options(core${TARGET_EXECUTABLE_NAME} PRIVATE "${_CORENEURON_EXE_LINKER_FLAGS}") endif() endif() endfunction() diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index 6453fe13c5..9d900ca709 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -419,12 +419,12 @@ if(CORENRN_ENABLE_GPU) target_link_libraries(coreneuron-core PUBLIC coreneuron-cuda) # list() commands don't propagate to parent scope set(CORENRN_INSTALL_TARGETS - "coreneuron-core;coreneuron-cuda" + "coreneuron-core;coreneuron-cuda;nmodl" PARENT_SCOPE) else() set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) set(CORENRN_INSTALL_TARGETS - coreneuron-core + "coreneuron-core;nmodl" PARENT_SCOPE) endif() From 2e7b44fc14e3438ffc34ad109ad0c08757c2f4b8 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 18 Jun 2025 15:40:28 +0200 Subject: [PATCH 37/63] Use dynamic min CUDA toolkit version --- cmake/neuronConfig.cmake.in | 2 ++ cmake/neuronMechMaker.cmake | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index 495b6c9ee4..cc4f20cd3c 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -20,4 +20,6 @@ set(_CORENEURON_MECH_ENG "${_prefix}/share/coreneuron/enginemech.cpp") set(_CORENEURON_RANDOM_INCLUDE "${_prefix}/include/coreneuron/utils/randoms" "${_prefix}/include") set(_CORENEURON_FLAGS @CORENRN_CXX_FLAGS@) +set(_CORENEURON_MIN_CUDA_TOOLKIT_VERSION @CORENRN_CUDA_VERSION_SHORT@) + include(${CMAKE_CURRENT_LIST_DIR}/neuronMechMaker.cmake) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index df3a60f98e..22647c8322 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -321,7 +321,7 @@ function(create_nrnmech) if(CMAKE_CUDA_COMPILER) # Find the cuda toolkit and openacc (if not found already) if(NOT CUDAToolkit_FOUND) - find_package(CUDAToolkit 9.0 REQUIRED) + find_package(CUDAToolkit ${_CORENEURON_MIN_CUDA_TOOLKIT_VERSION} REQUIRED) endif() if(NOT OpenACC_FOUND) find_package(OpenACC REQUIRED) From b87f6c403505f08b8574ff8ac945e740d043f14c Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 19 Jun 2025 13:59:00 +0200 Subject: [PATCH 38/63] More debugging in `create_nrnmech` --- cmake/neuronMechMaker.cmake | 109 ++++++++++++++++++++++++++++-------- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 22647c8322..9baf94e3c5 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -28,24 +28,26 @@ # [NOCMODL_EXECUTABLE path/to/nocmodl] # [NMODL_EXECUTABLE path/to/nmodl] # [MOD_FILES mod1 mod2 ...] -# [NMODL_EXTRA_ARGS arg1 arg2 ...] +# [NMODL_NEURON_EXTRA_ARGS arg1 arg2 ...] +# [NMODL_CORENEURON_EXTRA_ARGS arg1 arg2 ...] # [EXTRA_ENV KEY1=VAL1 KEY2=VAL2 ...] # ) # # Create a suitable mechanism for loading into NEURON. # -# NEURON - (optional) whether a library compatible with NEURON should be created. -# CORENEURON - (optional) whether a library compatible with coreNEURON should be created. At least one of NEURON or CORENEURON must be specified. -# SPECIAL - (optional) whether a `special` (or `special-core` in case of coreNEURON) executable should be created. -# NMODL_NEURON_CODEGEN - (optional) whether to use NMODL to generate files compatible with NEURON. -# TARGET_LIBRARY_NAME - (optional, default: nrnmech) the name of the CMake target for the library. Note that `core` is prepended to the coreNEURON target. -# TARGET_EXECUTABLE_NAME - (optional, default: special) the name of the CMake target for the executable. Note that `-core` is appended to the coreNEURON target. -# ARTIFACTS_OUTPUT_DIR - (optional) the path where the CPP files will be placed at build-time. -# NOCMODL_EXECUTABLE - (optional) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. -# NMODL_EXECUTABLE - (optional) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. -# MOD_FILES - list of mod files to convert. -# NMODL_EXTRA_ARGS - (optional, default: None) list of additional arguments to pass to NMODL. -# EXTRA_ENV - (optional, default: None) list of additional environmental variables to pass when building the targets. +# NEURON - (optional) whether a library compatible with NEURON should be created. +# CORENEURON - (optional) whether a library compatible with coreNEURON should be created. At least one of NEURON or CORENEURON must be specified. +# SPECIAL - (optional) whether a `special` (or `special-core` in case of coreNEURON) executable should be created. +# NMODL_NEURON_CODEGEN - (optional) whether to use NMODL to generate files compatible with NEURON. +# TARGET_LIBRARY_NAME - (optional, default: nrnmech) the name of the CMake target for the library. Note that `core` is prepended to the coreNEURON target. +# TARGET_EXECUTABLE_NAME - (optional, default: special) the name of the CMake target for the executable. Note that `-core` is appended to the coreNEURON target. +# ARTIFACTS_OUTPUT_DIR - (optional) the path where the CPP files will be placed at build-time. +# NOCMODL_EXECUTABLE - (optional) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. +# NMODL_EXECUTABLE - (optional) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. +# MOD_FILES - list of mod files to convert. +# NMODL_NEURON_EXTRA_ARGS - (optional, default: None) list of additional arguments to pass to NMODL for NEURON codegen. +# NMODL_CORENEURON_EXTRA_ARGS - (optional, default: `passes --inline host --c` if CUDA disabled, `passes --inline host --c acc --oacc` if CUDA enabled) list of additional arguments to pass to NMODL for coreNEURON codegen. +# EXTRA_ENV - (optional, default: None) list of additional environmental variables to pass when building the targets. # TODO figure out why we get missing symbols when testing # ~~~ function(create_nrnmech) @@ -60,18 +62,24 @@ function(create_nrnmech) LIBRARY_TYPE NOCMODL_EXECUTABLE NMODL_EXECUTABLE) - set(multiValueArgs MOD_FILES NMODL_EXTRA_ARGS EXTRA_ENV) + set(multiValueArgs MOD_FILES NMODL_NEURON_EXTRA_ARGS NMODL_CORENEURON_EXTRA_ARGS EXTRA_ENV) cmake_parse_arguments(NRN_MECH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + # The message priority for logging + set(MESSAGE_PRIORITY "VERBOSE") + # The name of the output library set(LIBNAME "nrnmech") + # The name of the output executable set(EXENAME "special") + # The default type of the output library. Note that `nrnmech` and `corenrnmech` are actually # module libraries (since they are loaded via `dlopen`-like functionality), but a module library # cannot be linked to, and since `special` must link to `nrnmech`, so to avoid having to compile # the source files twice, we use a shared library instead. set(DEFAULT_LIBRARY_TYPE "SHARED") + # The default name of the mechanism set(DEFAULT_MECHANISM_NAME "neuron") @@ -92,12 +100,32 @@ function(create_nrnmech) message(FATAL_ERROR "No input mod files specified!") endif() + if(NRN_MECH_NEURON) + message("${MESSAGE_PRIORITY}" "NEURON | enabled") + else() + message("${MESSAGE_PRIORITY}" "NEURON | disabled") + endif() + + if(NRN_MECH_CORENEURON) + message("${MESSAGE_PRIORITY}" "coreNEURON | enabled") + else() + message("${MESSAGE_PRIORITY}" "coreNEURON | disabled") + endif() + + if(NRN_MECH_SPECIAL) + message("${MESSAGE_PRIORITY}" "special executable | enabled") + else() + message("${MESSAGE_PRIORITY}" "special executable | disabled") + endif() + if(NRN_MECH_MECHANISM_NAME) set(MECHANISM_NAME "${NRN_MECH_MECHANISM_NAME}") else() set(MECHANISM_NAME "${DEFAULT_MECHANISM_NAME}") endif() + message("${MESSAGE_PRIORITY}" "MECHANISM_NAME | ${MECHANISM_NAME}") + # the `nmodl` and `nocmodl` executables are usually found through `find_program` on the user's # system, but we allow overrides (for testing purposes only) if(NRN_MECH_NMODL_EXECUTABLE) @@ -106,12 +134,16 @@ function(create_nrnmech) set(NMODL_EXECUTABLE $) endif() + message("${MESSAGE_PRIORITY}" "NMODL_EXECUTABLE | ${NMODL_EXECUTABLE}") + if(NRN_MECH_NOCMODL_EXECUTABLE) set(NOCMODL_EXECUTABLE "${NRN_MECH_NOCMODL_EXECUTABLE}") else() set(NOCMODL_EXECUTABLE $) endif() + message("${MESSAGE_PRIORITY}" "NOCMODL_EXECUTABLE | ${NOCMODL_EXECUTABLE}") + # the option `CORENRN_ENABLE_SHARED` toggles the kind of library we want to build, so we respect # it here if(NRN_MECH_LIBRARY_TYPE) @@ -120,6 +152,8 @@ function(create_nrnmech) set(LIBRARY_TYPE "${DEFAULT_LIBRARY_TYPE}") endif() + message("${MESSAGE_PRIORITY}" "LIBRARY_TYPE | ${LIBRARY_TYPE}") + # nmodl by default generates code for coreNEURON, so we toggle this via an option if(NRN_MECH_NMODL_NEURON_CODEGEN) set(NEURON_TRANSPILER_LAUNCHER ${NMODL_EXECUTABLE} --neuron) @@ -130,16 +164,33 @@ function(create_nrnmech) # raise warning that NMODL extra args will be ignored if we use NEURON codegen with NOCMODL if(NRN_MECH_NEURON AND NOT NRN_MECH_NMODL_NEURON_CODEGEN - AND NRN_MECH_NMODL_EXTRA_ARGS) + AND NRN_MECH_NMODL_NEURON_EXTRA_ARGS) message( WARNING - "create_nrmech: requested NEURON library with NOCMODL codegen, but NMODL_EXTRA_ARGS is not empty; " - "will ignore NMODL_EXTRA_ARGS when building NEURON library.\n" - "Hint: if you want to use NMODL for codegen, add the NMODL_NEURON_CODEGEN option when calling this function." + "${CMAKE_CURRENT_FUNCTION}: requested NEURON library with NOCMODL codegen, but NMODL_NEURON_EXTRA_ARGS is not empty; " + "will ignore NMODL_NEURON_EXTRA_ARGS when building NEURON library.\n" + "Hint: if you want to use NMODL for codegen for NEURON, add the NMODL_NEURON_CODEGEN option when calling this function." ) - set(NRN_MECH_NMODL_EXTRA_ARGS) + set(NRN_MECH_NMODL_NEURON_EXTRA_ARGS) + endif() + + list(JOIN NRN_MECH_NMODL_NEURON_EXTRA_ARGS "" NMODL_NEURON_EXTRA_ARGS_SPACES) + message("${MESSAGE_PRIORITY}" "NMODL_NEURON_EXTRA_ARGS | ${NMODL_NEURON_EXTRA_ARGS_SPACES}") + + # set default flags for NMODL for coreNEURON. + if(NOT NRN_MECH_NMODL_CORENEURON_EXTRA_ARGS) + set(NRN_MECH_NMODL_CORENEURON_EXTRA_ARGS passes --inline) + list(APPEND NRN_MECH_NMODL_CORENEURON_EXTRA_ARGS host --c) + # OpenACC flags + if(CMAKE_CUDA_COMPILER) + list(APPEND NRN_MECH_NMODL_CORENEURON_EXTRA_ARGS acc --oacc) + endif() endif() + list(JOIN NRN_MECH_NMODL_CORENEURON_EXTRA_ARGS " " NMODL_CORENEURON_EXTRA_ARGS_SPACES) + message("${MESSAGE_PRIORITY}" + "NMODL_CORENEURON_EXTRA_ARGS | ${NMODL_CORENEURON_EXTRA_ARGS_SPACES}") + # any extra environment variables that need to be passed (for testing purposes only). Because # CMake likes to escape and quote things, we need to do it the roundabout way... if(NRN_MECH_EXTRA_ENV) @@ -148,6 +199,8 @@ function(create_nrnmech) set(ENV_COMMAND) endif() + message("${MESSAGE_PRIORITY}" "EXTRA_ENV | ${NRN_MECH_EXTRA_ENV}") + # nocmodl sometimes does not work due to lack of MODLUNIT, see: # https://github.com/neuronsimulator/nrn/issues/3470 if(DEFINED ENV{MODLUNIT}) @@ -162,6 +215,8 @@ function(create_nrnmech) set(TARGET_LIBRARY_NAME "${LIBNAME}") endif() + message("${MESSAGE_PRIORITY}" "TARGET_LIBRARY_NAME | ${TARGET_LIBRARY_NAME}") + # Override the _target_ name, but not the executable name. This is useful when we are using this # function for building NEURON components, since we may experience collisions in the target names if(NRN_MECH_TARGET_EXECUTABLE_NAME) @@ -170,6 +225,8 @@ function(create_nrnmech) set(TARGET_EXECUTABLE_NAME "${EXENAME}") endif() + message("${MESSAGE_PRIORITY}" "TARGET_EXECUTABLE_NAME | ${TARGET_EXECUTABLE_NAME}") + # Where to output the library (during build) if(NRN_MECH_LIBRARY_OUTPUT_DIR) set(LIBRARY_OUTPUT_DIR "${NRN_MECH_LIBRARY_OUTPUT_DIR}") @@ -177,6 +234,8 @@ function(create_nrnmech) set(LIBRARY_OUTPUT_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") endif() + message("${MESSAGE_PRIORITY}" "LIBRARY_OUTPUT_DIR | ${LIBRARY_OUTPUT_DIR}") + # Where to output the executable (during build) if(NRN_MECH_EXECUTABLE_OUTPUT_DIR) set(EXECUTABLE_OUTPUT_DIR "${NRN_MECH_EXECUTABLE_OUTPUT_DIR}") @@ -184,6 +243,8 @@ function(create_nrnmech) set(EXECUTABLE_OUTPUT_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") endif() + message("${MESSAGE_PRIORITY}" "EXECUTABLE_OUTPUT_DIR | ${EXECUTABLE_OUTPUT_DIR}") + # Where the intermediate CPP files will be placed if(NRN_MECH_ARTIFACTS_OUTPUT_DIR) set(ARTIFACTS_OUTPUT_DIR "${NRN_MECH_ARTIFACTS_OUTPUT_DIR}") @@ -191,6 +252,8 @@ function(create_nrnmech) set(ARTIFACTS_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") endif() + message("${MESSAGE_PRIORITY}" "ARTIFACTS_OUTPUT_DIR | ${ARTIFACTS_OUTPUT_DIR}") + # Collect mod files, output any warnings set(MOD_FILES "") foreach(MOD_FILE IN LISTS NRN_MECH_MOD_FILES) @@ -202,7 +265,9 @@ function(create_nrnmech) list(APPEND MOD_FILES "${MOD_FILE}") endforeach() - # We later include the directories where the mod files in case people add headers in VERBATIM + message("${MESSAGE_PRIORITY}" "MOD_FILES | ${MOD_FILES}") + + # We later include the directories where the mod files are in case people add headers in VERBATIM # blocks set(MOD_DIRECTORIES) @@ -226,7 +291,7 @@ function(create_nrnmech) add_custom_command( COMMAND ${ENV_COMMAND} ${NEURON_TRANSPILER_LAUNCHER} -o "${ARTIFACTS_OUTPUT_DIR}/cpp" - "${MOD_ABSPATH}" ${NRN_MECH_NMODL_EXTRA_ARGS} + "${MOD_ABSPATH}" ${NRN_MECH_NMODL_NEURON_EXTRA_ARGS} OUTPUT "${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" COMMENT "Converting ${MOD_ABSPATH} to ${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" # TODO some mod files may include other files, and NMODL can get the AST of a given file in @@ -298,7 +363,7 @@ function(create_nrnmech) add_custom_command( COMMAND ${ENV_COMMAND} ${NMODL_EXECUTABLE} -o "${ARTIFACTS_OUTPUT_DIR}/cpp_core" - "${MOD_ABSPATH}" ${NRN_MECH_NMODL_EXTRA_ARGS} + "${MOD_ABSPATH}" ${NRN_MECH_NMODL_CORENEURON_EXTRA_ARGS} OUTPUT "${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" COMMENT "Converting ${MOD_ABSPATH} to ${ARTIFACTS_OUTPUT_DIR}/${CPP_FILE}" DEPENDS "${MOD_ABSPATH}" From 64963f9caf238fb962b853c976375f37f650be36 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 19 Jun 2025 16:33:36 +0200 Subject: [PATCH 39/63] Actually update docs to use CMake --- ci/requirements.txt | 5 +++ cmake/neuronMechMaker.cmake | 51 +--------------------- docs/conf.py | 1 + docs/dev/index.rst | 1 + docs/dev/nrnivmodl-cmake.rst | 74 ++++++++++++++++++++++++++++++++ docs/dev/workflow-code-paths.rst | 4 ++ 6 files changed, 86 insertions(+), 50 deletions(-) create mode 100644 docs/dev/nrnivmodl-cmake.rst diff --git a/ci/requirements.txt b/ci/requirements.txt index 4b2079437a..7f12038bea 100644 --- a/ci/requirements.txt +++ b/ci/requirements.txt @@ -2199,6 +2199,7 @@ sphinx==7.3.7 \ # sphinx-inline-tabs # sphinx-rtd-theme # sphinxcontrib-jquery + # sphinxcontrib-moderncmakedomain sphinx-design==0.6.1 \ --hash=sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c \ --hash=sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632 @@ -2237,6 +2238,10 @@ sphinxcontrib-jsmath==1.0.1 \ --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 # via sphinx +sphinxcontrib-moderncmakedomain==3.29.0 \ + --hash=sha256:22385d9956e9565311eca41a09f26688312e4997a7366cb965fa610d1fd1436c \ + --hash=sha256:3587def241ff2577d0bbef11810a082e9dec1b78a3d4b4a066240b5f3dc1b5b2 + # via -r docs/docs_requirements.txt sphinxcontrib-qthelp==2.0.0 \ --hash=sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab \ --hash=sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 9baf94e3c5..743117243c 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -1,54 +1,5 @@ # ~~~ -# Helper functions for generating (core)NEURON mechanism libraries directly in CMake -# The basic idea is to replicate all of the previous functionality of the Makefiles, -# but without having to deal with reading Makefiles or having to worry about dependencies. -# What `nrnivmodl` and `nrnivmodl -coreneuron` were doing was essentially: -# - create a subdir equivalent to `CMAKE_HOST_SYSTEM_PROCESSOR` in the current working directory -# - translate a given list of mod files to cpp files (using either NOCMODL or NMODL) -# - create a file `mod_func.cpp` which dynamically (that is, upon running `nrniv` or similar) registers the mechanisms in NEURON -# - create a `nrnmech` library in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from all of the above listed cpp files -# - create a `special` executable in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from the `nrnmain.cpp` file -# - link the above executable to the `nrnmech` library -# In case the `-coreneuron` option is given, it additionally does the following: -# - create a `corenrnmech` library in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from all of the above listed cpp files, except with a different `mod_func.cpp` which correctly registers it under the `coreneuron` cpp namespace -# - create a `special-core` executable in the `CMAKE_HOST_SYSTEM_PROCESSOR` subdirectory from the `coreneuron.cpp` file -# - link the above executable to the `corenrnmech` library -# Note that any other files created are basically noise. -# create_nrnmech( -# [NEURON] -# [CORENEURON] -# [SPECIAL] -# [NMODL_NEURON_CODEGEN] -# [TARGET_LIBRARY_NAME lib_tgt] -# [TARGET_EXECUTABLE_NAME exe_tgt] -# [LIBRARY_OUTPUT_DIR lib_outdir] -# [EXECUTABLE_OUTPUT_DIR exe_outdir] -# [ARTIFACTS_OUTPUT_DIR art_outdir] -# [LIBRARY_TYPE type] -# [NOCMODL_EXECUTABLE path/to/nocmodl] -# [NMODL_EXECUTABLE path/to/nmodl] -# [MOD_FILES mod1 mod2 ...] -# [NMODL_NEURON_EXTRA_ARGS arg1 arg2 ...] -# [NMODL_CORENEURON_EXTRA_ARGS arg1 arg2 ...] -# [EXTRA_ENV KEY1=VAL1 KEY2=VAL2 ...] -# ) -# -# Create a suitable mechanism for loading into NEURON. -# -# NEURON - (optional) whether a library compatible with NEURON should be created. -# CORENEURON - (optional) whether a library compatible with coreNEURON should be created. At least one of NEURON or CORENEURON must be specified. -# SPECIAL - (optional) whether a `special` (or `special-core` in case of coreNEURON) executable should be created. -# NMODL_NEURON_CODEGEN - (optional) whether to use NMODL to generate files compatible with NEURON. -# TARGET_LIBRARY_NAME - (optional, default: nrnmech) the name of the CMake target for the library. Note that `core` is prepended to the coreNEURON target. -# TARGET_EXECUTABLE_NAME - (optional, default: special) the name of the CMake target for the executable. Note that `-core` is appended to the coreNEURON target. -# ARTIFACTS_OUTPUT_DIR - (optional) the path where the CPP files will be placed at build-time. -# NOCMODL_EXECUTABLE - (optional) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. -# NMODL_EXECUTABLE - (optional) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. -# MOD_FILES - list of mod files to convert. -# NMODL_NEURON_EXTRA_ARGS - (optional, default: None) list of additional arguments to pass to NMODL for NEURON codegen. -# NMODL_CORENEURON_EXTRA_ARGS - (optional, default: `passes --inline host --c` if CUDA disabled, `passes --inline host --c acc --oacc` if CUDA enabled) list of additional arguments to pass to NMODL for coreNEURON codegen. -# EXTRA_ENV - (optional, default: None) list of additional environmental variables to pass when building the targets. -# TODO figure out why we get missing symbols when testing +# See ``docs/dev/nrnivmodl-cmake.rst`` for the description of the API. # ~~~ function(create_nrnmech) set(options NEURON CORENEURON SPECIAL NMODL_NEURON_CODEGEN) diff --git a/docs/conf.py b/docs/conf.py index a7870ac826..95bf836ad2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -42,6 +42,7 @@ "nbsphinx", "sphinx_design", "sphinx_inline_tabs", + "sphinxcontrib.moderncmakedomain", ] source_suffix = { diff --git a/docs/dev/index.rst b/docs/dev/index.rst index ca101e6d4f..efa048ee30 100644 --- a/docs/dev/index.rst +++ b/docs/dev/index.rst @@ -9,6 +9,7 @@ NEURON Development topics data-structures.rst gpu-testing.rst workflow-code-paths.rst + nrnivmodl-cmake.rst ./python/wheels.md ./morphology/morphology.md hocdomain-sphinx.md diff --git a/docs/dev/nrnivmodl-cmake.rst b/docs/dev/nrnivmodl-cmake.rst new file mode 100644 index 0000000000..da4aa1e0b1 --- /dev/null +++ b/docs/dev/nrnivmodl-cmake.rst @@ -0,0 +1,74 @@ +Mechanism building with CMake +============================= + +.. note:: + + This API is **experimental** and subject to change. + +Helper functions for generating (core)NEURON mechanism libraries directly in CMake. +The basic idea is to replicate all of the previous functionality of the Makefiles, +but without having to deal with reading Makefiles or having to worry about dependencies. + +Overview +-------- + +What ``nrnivmodl`` and ``nrnivmodl -coreneuron`` were doing was essentially: + +- create a subdir equivalent to ``CMAKE_HOST_SYSTEM_PROCESSOR`` in the current working directory +- translate a given list of mod files to cpp files (using either NOCMODL or NMODL) +- create a file ``mod_func.cpp`` which dynamically (that is, upon running ``nrniv`` or similar) registers the mechanisms in NEURON +- create a ``nrnmech`` library in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from all of the above listed cpp files +- create a ``special`` executable in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from the ``nrnmain.cpp`` file +- link the above executable to the ``nrnmech`` library + +In case the ``-coreneuron`` option is given, it additionally does the following: + +- create a ``corenrnmech`` library in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from all of the above listed cpp files, except with a different ``mod_func.cpp`` which correctly registers it under the ``coreneuron`` cpp namespace +- create a ``special-core`` executable in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from the ``coreneuron.cpp`` file +- link the above executable to the ``corenrnmech`` library + +Reference +--------- + +.. cmake:command:: create_nrnmech + + **Options** + + ``NEURON`` + (*optional*) whether a library compatible with NEURON should be created. + + ``CORENEURON`` + (*optional*) whether a library compatible with coreNEURON should be created. At least one of ``NEURON`` or ``CORENEURON`` must be specified. + + ``SPECIAL`` + (*optional*) whether a ``special`` (or ``special-core`` in case of coreNEURON) executable should be created. + + ``NMODL_NEURON_CODEGEN`` + (*optional*) whether to use NMODL to generate files compatible with NEURON. + + ``TARGET_LIBRARY_NAME`` + (*optional*, default: ``nrnmech``) the name of the CMake target for the library. Note that ``core`` is prepended to the coreNEURON target. + + ``TARGET_EXECUTABLE_NAME`` + (*optional*, default: ``special``) the name of the CMake target for the executable. Note that ``-core`` is appended to the coreNEURON target. + + ``ARTIFACTS_OUTPUT_DIR`` + (*optional*) the path where the CPP files will be placed at build-time. + + ``NOCMODL_EXECUTABLE`` + (*optional*) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. + + ``NMODL_EXECUTABLE`` + (*optional*) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. + + ``MOD_FILES`` + list of mod files to convert. + + ``NMODL_NEURON_EXTRA_ARGS`` + (*optional*, default: None) list of additional arguments to pass to NMODL for NEURON codegen. + + ``NMODL_CORENEURON_EXTRA_ARGS`` + (*optional*, default: ``passes --inline host --c`` if CUDA disabled, ``passes --inline host --c acc --oacc`` if CUDA enabled) list of additional arguments to pass to NMODL for coreNEURON codegen. + + ``EXTRA_ENV`` + (*optional*, default: None) list of additional environmental variables to pass when building the targets. diff --git a/docs/dev/workflow-code-paths.rst b/docs/dev/workflow-code-paths.rst index 498557894d..395d7499b8 100644 --- a/docs/dev/workflow-code-paths.rst +++ b/docs/dev/workflow-code-paths.rst @@ -22,6 +22,10 @@ The ``nrnivmodl`` executable translates the ``MOD`` files from the ``NMODL`` lan .. raw:: html :file: mechanism_registration.svg +.. note:: + + Have a look at :doc:`nrnivmodl-cmake` for an more modern (experimental!) way of building mechanisms. + Circuit creation ^^^^^^^^^^^^^^^^ From 73f346c0a426c50d214aec2c1da1c1d90d6848e7 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 19 Jun 2025 16:34:34 +0200 Subject: [PATCH 40/63] Forgot to add it to reqs --- docs/docs_requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs_requirements.txt b/docs/docs_requirements.txt index f5de32a92f..277ef5baf2 100644 --- a/docs/docs_requirements.txt +++ b/docs/docs_requirements.txt @@ -18,3 +18,4 @@ sphinx-inline-tabs packaging<=24.2,>=22.0 tenacity<8.4 anywidget +sphinxcontrib-moderncmakedomain<=3.29.0 From 6b3983f9ecbe0d4782c3916c2ce02e5bf9f82dd4 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 19 Jun 2025 17:31:31 +0200 Subject: [PATCH 41/63] Put docs back next to implementation --- cmake/neuronMechMaker.cmake | 82 ++++++++++++++++++++++++++++++-- docs/dev/index.rst | 1 - docs/dev/nrnivmodl-cmake.rst | 75 +---------------------------- docs/dev/workflow-code-paths.rst | 2 +- 4 files changed, 81 insertions(+), 79 deletions(-) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 743117243c..a5bc32f38e 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -1,6 +1,82 @@ -# ~~~ -# See ``docs/dev/nrnivmodl-cmake.rst`` for the description of the API. -# ~~~ +#[=======================================================================[.rst: + +Mechanism building with CMake +============================= + +.. note:: + + This API is **experimental** and subject to change. + +Helper functions for generating (core)NEURON mechanism libraries directly in CMake. +The basic idea is to replicate all of the previous functionality of the Makefiles, +but without having to deal with reading Makefiles or having to worry about dependencies. + +Overview +-------- + +What ``nrnivmodl`` and ``nrnivmodl -coreneuron`` were doing was essentially: + +- create a subdir equivalent to ``CMAKE_HOST_SYSTEM_PROCESSOR`` in the current working directory +- translate a given list of mod files to cpp files (using either NOCMODL or NMODL) +- create a file ``mod_func.cpp`` which dynamically (that is, upon running ``nrniv`` or similar) registers the mechanisms in NEURON +- create a ``nrnmech`` library in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from all of the above listed cpp files +- create a ``special`` executable in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from the ``nrnmain.cpp`` file +- link the above executable to the ``nrnmech`` library + +In case the ``-coreneuron`` option is given, it additionally does the following: + +- create a ``corenrnmech`` library in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from all of the above listed cpp files, except with a different ``mod_func.cpp`` which correctly registers it under the ``coreneuron`` cpp namespace +- create a ``special-core`` executable in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from the ``coreneuron.cpp`` file +- link the above executable to the ``corenrnmech`` library + +API reference +------------- + +.. cmake:command:: create_nrnmech + + **Options** + + ``NEURON`` + (*optional*) whether a library compatible with NEURON should be created. + + ``CORENEURON`` + (*optional*) whether a library compatible with coreNEURON should be created. At least one of ``NEURON`` or ``CORENEURON`` must be specified. + + ``SPECIAL`` + (*optional*) whether a ``special`` (or ``special-core`` in case of coreNEURON) executable should be created. + + ``NMODL_NEURON_CODEGEN`` + (*optional*) whether to use NMODL to generate files compatible with NEURON. + + ``TARGET_LIBRARY_NAME`` + (*optional*, default: ``nrnmech``) the name of the CMake target for the library. Note that ``core`` is prepended to the coreNEURON target. + + ``TARGET_EXECUTABLE_NAME`` + (*optional*, default: ``special``) the name of the CMake target for the executable. Note that ``-core`` is appended to the coreNEURON target. + + ``ARTIFACTS_OUTPUT_DIR`` + (*optional*) the path where the CPP files will be placed at build-time. + + ``NOCMODL_EXECUTABLE`` + (*optional*) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. + + ``NMODL_EXECUTABLE`` + (*optional*) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. + + ``MOD_FILES`` + list of mod files to convert. + + ``NMODL_NEURON_EXTRA_ARGS`` + (*optional*, default: None) list of additional arguments to pass to NMODL for NEURON codegen. + + ``NMODL_CORENEURON_EXTRA_ARGS`` + (*optional*, default: ``passes --inline host --c`` if CUDA disabled, ``passes --inline host --c acc --oacc`` if CUDA enabled) list of additional arguments to pass to NMODL for coreNEURON codegen. + + ``EXTRA_ENV`` + (*optional*, default: None) list of additional environmental variables to pass when building the targets. + +#]=======================================================================] + function(create_nrnmech) set(options NEURON CORENEURON SPECIAL NMODL_NEURON_CODEGEN) set(oneValueArgs diff --git a/docs/dev/index.rst b/docs/dev/index.rst index efa048ee30..7a9959351b 100644 --- a/docs/dev/index.rst +++ b/docs/dev/index.rst @@ -13,4 +13,3 @@ NEURON Development topics ./python/wheels.md ./morphology/morphology.md hocdomain-sphinx.md - diff --git a/docs/dev/nrnivmodl-cmake.rst b/docs/dev/nrnivmodl-cmake.rst index da4aa1e0b1..5f242aca84 100644 --- a/docs/dev/nrnivmodl-cmake.rst +++ b/docs/dev/nrnivmodl-cmake.rst @@ -1,74 +1 @@ -Mechanism building with CMake -============================= - -.. note:: - - This API is **experimental** and subject to change. - -Helper functions for generating (core)NEURON mechanism libraries directly in CMake. -The basic idea is to replicate all of the previous functionality of the Makefiles, -but without having to deal with reading Makefiles or having to worry about dependencies. - -Overview --------- - -What ``nrnivmodl`` and ``nrnivmodl -coreneuron`` were doing was essentially: - -- create a subdir equivalent to ``CMAKE_HOST_SYSTEM_PROCESSOR`` in the current working directory -- translate a given list of mod files to cpp files (using either NOCMODL or NMODL) -- create a file ``mod_func.cpp`` which dynamically (that is, upon running ``nrniv`` or similar) registers the mechanisms in NEURON -- create a ``nrnmech`` library in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from all of the above listed cpp files -- create a ``special`` executable in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from the ``nrnmain.cpp`` file -- link the above executable to the ``nrnmech`` library - -In case the ``-coreneuron`` option is given, it additionally does the following: - -- create a ``corenrnmech`` library in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from all of the above listed cpp files, except with a different ``mod_func.cpp`` which correctly registers it under the ``coreneuron`` cpp namespace -- create a ``special-core`` executable in the ``CMAKE_HOST_SYSTEM_PROCESSOR`` subdirectory from the ``coreneuron.cpp`` file -- link the above executable to the ``corenrnmech`` library - -Reference ---------- - -.. cmake:command:: create_nrnmech - - **Options** - - ``NEURON`` - (*optional*) whether a library compatible with NEURON should be created. - - ``CORENEURON`` - (*optional*) whether a library compatible with coreNEURON should be created. At least one of ``NEURON`` or ``CORENEURON`` must be specified. - - ``SPECIAL`` - (*optional*) whether a ``special`` (or ``special-core`` in case of coreNEURON) executable should be created. - - ``NMODL_NEURON_CODEGEN`` - (*optional*) whether to use NMODL to generate files compatible with NEURON. - - ``TARGET_LIBRARY_NAME`` - (*optional*, default: ``nrnmech``) the name of the CMake target for the library. Note that ``core`` is prepended to the coreNEURON target. - - ``TARGET_EXECUTABLE_NAME`` - (*optional*, default: ``special``) the name of the CMake target for the executable. Note that ``-core`` is appended to the coreNEURON target. - - ``ARTIFACTS_OUTPUT_DIR`` - (*optional*) the path where the CPP files will be placed at build-time. - - ``NOCMODL_EXECUTABLE`` - (*optional*) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. - - ``NMODL_EXECUTABLE`` - (*optional*) the path to the NMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. - - ``MOD_FILES`` - list of mod files to convert. - - ``NMODL_NEURON_EXTRA_ARGS`` - (*optional*, default: None) list of additional arguments to pass to NMODL for NEURON codegen. - - ``NMODL_CORENEURON_EXTRA_ARGS`` - (*optional*, default: ``passes --inline host --c`` if CUDA disabled, ``passes --inline host --c acc --oacc`` if CUDA enabled) list of additional arguments to pass to NMODL for coreNEURON codegen. - - ``EXTRA_ENV`` - (*optional*, default: None) list of additional environmental variables to pass when building the targets. +.. cmake-module:: ../../cmake/neuronMechMaker.cmake diff --git a/docs/dev/workflow-code-paths.rst b/docs/dev/workflow-code-paths.rst index 395d7499b8..b13bb833aa 100644 --- a/docs/dev/workflow-code-paths.rst +++ b/docs/dev/workflow-code-paths.rst @@ -24,7 +24,7 @@ The ``nrnivmodl`` executable translates the ``MOD`` files from the ``NMODL`` lan .. note:: - Have a look at :doc:`nrnivmodl-cmake` for an more modern (experimental!) way of building mechanisms. + Have a look at :doc:`nrnivmodl-cmake` for a more modern (experimental!) way of building mechanisms. Circuit creation ^^^^^^^^^^^^^^^^ From 5f5f413d650947c10bc259dc486d22a2fdf6f4aa Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 19 Jun 2025 17:51:50 +0200 Subject: [PATCH 42/63] Add example to create_nrnmech --- cmake/neuronMechMaker.cmake | 63 ++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index a5bc32f38e..7e91032fb3 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -3,13 +3,10 @@ Mechanism building with CMake ============================= -.. note:: - - This API is **experimental** and subject to change. - -Helper functions for generating (core)NEURON mechanism libraries directly in CMake. -The basic idea is to replicate all of the previous functionality of the Makefiles, -but without having to deal with reading Makefiles or having to worry about dependencies. +This module contains helper functions for generating (core)NEURON mechanism +libraries directly in CMake. The basic idea is to replicate all of the previous +functionality of the Makefiles, but without having to deal with their +maintenance or having to worry about managing dependencies. Overview -------- @@ -32,6 +29,10 @@ In case the ``-coreneuron`` option is given, it additionally does the following: API reference ------------- +.. note:: + + This API is **experimental** and subject to change. + .. cmake:command:: create_nrnmech **Options** @@ -75,6 +76,54 @@ API reference ``EXTRA_ENV`` (*optional*, default: None) list of additional environmental variables to pass when building the targets. + +Examples +-------- + +.. note:: + + You need to insert the path to ``neuronTargets.cmake`` in ``CMAKE_PREFIX_PATH``. + If you installed NEURON via CMake, the usual loaction of it is ``CMAKE_INSTALL_PREFIX/lib/cmake``. + If instead you installed NEURON as a Python wheel, the usual location is ``WHEEL_INSTALL_DIR/neuron/.data/lib/make``, where ``WHEEL_INSTALL_DIR`` is listed after ``Location:`` when calling ``pip show neuron``. + +To build a mechanism, put this in your ``CMakeLists.txt``: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.15) + project(custom_modfiles LANGUAGES C CXX) + + find_package(neuron REQUIRED) + + create_nrnmech(NEURON CORENEURON SPECIAL MOD_FILES + modfile1.mod + path/to/modfile2.mod) + +.. note:: + + If you want to enable coreNEURON's GPU support, you need to first build NEURON itself with ``CORENRN_ENABLE_GPU=ON`` and customize the ``CMAKE_C_COMPILER``, ``CMAKE_CXX_COMPILER``, and ``CMAKE_CUDA_COMPILER`` variables. + Currently only NVHPC is supported. + You also need to add ``CUDA`` to the ``LANGUAGES`` above. + +Then you can configure your mechanisms using: + +.. code-block:: sh + + cmake -B build + +Any CMake option (such as the compiler, generator, etc.) can be specified. +To build the mechanisms (i.e. the ``nrnmech`` library and ``special`` executable), run: + +.. code-block:: sh + + cmake --build build + +The ``nrnmech`` library will then be available under ``build``, and can be loaded in NEURON using: + +.. code-block:: sh + + nrniv -dll build/libnrnmech.so + #]=======================================================================] function(create_nrnmech) From 9a098350ce6813fd27ba0a92df5888ed861db9b3 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Fri, 20 Jun 2025 12:32:55 +0200 Subject: [PATCH 43/63] Fix issue with wheels containing wrong paths --- CMakeLists.txt | 20 ++++++++++++++------ cmake/neuronConfig.cmake.in | 2 +- src/coreneuron/CMakeLists.txt | 13 ++++++++----- src/nrniv/CMakeLists.txt | 12 ++++++++++-- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a24ac64e2..03150e4391 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -579,7 +579,6 @@ endif() cpp_cc_git_submodule(CLI11 BUILD PACKAGE CLI11 REQUIRED) # coreneuron targets will get propagated down from the subdirectory -set(NRN_INSTALL_TARGETS nrniv_lib nocmodl) # ============================================================================= # Enable NMODL code-generator support @@ -1117,7 +1116,14 @@ configure_file(cmake/mod_reg_nrn.cpp.in "${PROJECT_BINARY_DIR}/share/nrn/mod_reg COPYONLY) configure_file(cmake/mod_reg_corenrn.cpp.in "${PROJECT_BINARY_DIR}/share/nrn/mod_reg_corenrn.cpp.in" COPYONLY) -install(TARGETS ${NRN_INSTALL_TARGETS} ${CORENRN_INSTALL_TARGETS} EXPORT NeuronTargets) +install( + TARGETS ${CORENRN_INSTALL_LIB_TARGETS} + EXPORT NeuronTargets + DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib") +install( + TARGETS ${CORENRN_INSTALL_BIN_TARGETS} + EXPORT NeuronTargets + DESTINATION "${NRN_INSTALL_DATA_PREFIX}/bin") export( EXPORT NeuronTargets FILE ${PROJECT_BINARY_DIR}/lib/cmake/neuron/neuronTargets.cmake @@ -1127,17 +1133,19 @@ install( EXPORT NeuronTargets FILE neuronTargets.cmake NAMESPACE neuron:: - DESTINATION lib/cmake/neuron) + DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib/cmake/neuron") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake - DESTINATION lib/cmake/neuron) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake DESTINATION lib/cmake/neuron) + DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib/cmake/neuron") +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake + DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib/cmake/neuron") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_nrn.cpp.in - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_corenrn.cpp.in DESTINATION share/nrn) + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_corenrn.cpp.in + DESTINATION "${NRN_INSTALL_DATA_PREFIX}/share/nrn") # ============================================================================= # Copy bash executable for windows diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index cc4f20cd3c..b791720bd3 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -22,4 +22,4 @@ set(_CORENEURON_FLAGS @CORENRN_CXX_FLAGS@) set(_CORENEURON_MIN_CUDA_TOOLKIT_VERSION @CORENRN_CUDA_VERSION_SHORT@) -include(${CMAKE_CURRENT_LIST_DIR}/neuronMechMaker.cmake) +include("${CMAKE_CURRENT_LIST_DIR}/neuronMechMaker.cmake") diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index 9d900ca709..2061990101 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -418,15 +418,18 @@ if(CORENRN_ENABLE_GPU) set_target_properties(coreneuron-cuda PROPERTIES EXPORT_NAME corenrn-cuda) target_link_libraries(coreneuron-core PUBLIC coreneuron-cuda) # list() commands don't propagate to parent scope - set(CORENRN_INSTALL_TARGETS - "coreneuron-core;coreneuron-cuda;nmodl" + set(CORENRN_INSTALL_LIB_TARGETS + "coreneuron-core;coreneuron-cuda" PARENT_SCOPE) else() set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) - set(CORENRN_INSTALL_TARGETS - "coreneuron-core;nmodl" + set(CORENRN_INSTALL_LIB_TARGETS + "coreneuron-core" PARENT_SCOPE) endif() +set(CORENRN_INSTALL_BIN_TARGETS + "nmodl" + PARENT_SCOPE) foreach(target coreneuron-core ${coreneuron_cuda_target}) target_include_directories(${target} PRIVATE ${PROJECT_SOURCE_DIR}/src @@ -506,7 +509,7 @@ target_link_libraries(coreneuron-core PUBLIC ${sonatareport_LIBRARY} ${CORENRN_C ${CORENRN_LIKWID_LIB}) set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) target_compile_features(coreneuron-core PUBLIC cxx_std_17) -target_include_directories(coreneuron-core INTERFACE $) +target_include_directories(coreneuron-core INTERFACE $) # TODO: fix adding a dependency of coreneuron-core on CLI11::CLI11 when CLI11 is a submodule. Right # now this doesn't work because the CLI11 targets are not exported/installed but coreneuron-core is. diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index ea7fa9c808..b03eeacdcb 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -409,7 +409,8 @@ target_include_directories( cpp_cc_configure_sanitizers(TARGET nrniv_lib) # Source-directory .cpp needs to find generated .hpp. target_include_directories(nrniv_lib PUBLIC $) -target_include_directories(nrniv_lib INTERFACE $) +target_include_directories(nrniv_lib + INTERFACE $) if(NRN_ENABLE_PYTHON AND NOT NRN_ENABLE_PYTHON_DYNAMIC) target_link_libraries(nrniv_lib PRIVATE nrnpython) endif() @@ -580,7 +581,14 @@ endif() # expected when ctypes looks for dlls # ~~~ install(TARGETS nrniv nocmodl modlunit DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) -install(TARGETS nrniv_lib DESTINATION ${NRN_INSTALL_SHARE_LIB_DIR}) +install( + TARGETS nocmodl + DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin + EXPORT NeuronTargets) +install( + TARGETS nrniv_lib + DESTINATION ${NRN_INSTALL_SHARE_LIB_DIR} + EXPORT NeuronTargets) if(LIBIVX11DYNAM_NAME) install(FILES ${PROJECT_BINARY_DIR}/lib/${LIBIVX11DYNAM_NAME} DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib) From 66ba781abf69293e8974533c0c87a08447e2a1ac Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Fri, 20 Jun 2025 12:43:41 +0200 Subject: [PATCH 44/63] Fix slashes in installer --- CMakeLists.txt | 39 ++++++++++++++++----------------- bin/CMakeLists.txt | 6 ++--- src/coreneuron/CMakeLists.txt | 29 ++++++++++++------------ src/nmodl/pybind/CMakeLists.txt | 6 ++--- src/nrniv/CMakeLists.txt | 10 ++++----- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03150e4391..17cf66ee13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,9 +53,8 @@ if(SKBUILD) set(IV_HEADERS_INSTALL_DIR "${NRN_INSTALL_DATA_PREFIX}/include") set(IV_BIN_INSTALL_DIR "${NRN_INSTALL_DATA_PREFIX}/bin") else() - set(NRN_INSTALL_PYTHON_PREFIX "lib/python/neuron") - # TODO figure out if this needs to be set to NRN_INSTALL_DATA_PREFIX instead - set(NRN_INSTALL_DATA_PREFIX ".") + set(NRN_INSTALL_PYTHON_PREFIX "lib/python/neuron/") + set(NRN_INSTALL_DATA_PREFIX) endif() # ============================================================================= @@ -348,7 +347,7 @@ include(cmake/PythonHelper.cmake) if(NRN_SANITIZERS) configure_file(bin/nrn-enable-sanitizer.in bin/nrn-enable-sanitizer @ONLY) install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/nrn-enable-sanitizer - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) + DESTINATION "${NRN_INSTALL_DATA_PREFIX}bin") endif() # ============================================================================= @@ -629,12 +628,12 @@ if(NRN_ENABLE_NMODL # install nrnunits.lib and libpywrapper.so from external/nmodl install( FILES ${NMODL_PROJECT_PLATLIB_BINARY_DIR}/lib/libpywrapper${CMAKE_SHARED_LIBRARY_SUFFIX} - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib + DESTINATION "${NRN_INSTALL_DATA_PREFIX}lib" COMPONENT pywrapper OPTIONAL) install( FILES ${NMODL_PROJECT_PLATLIB_BINARY_DIR}/share/nmodl/nrnunits.lib - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/share/nmodl + DESTINATION "${NRN_INSTALL_DATA_PREFIX}share/nmodl" COMPONENT nrnunits) # set correct arguments for nmodl for cpu/gpu target @@ -724,11 +723,11 @@ include(ConfigFileSetting) if(MINGW) set(NRN_INSTALL_SHARE_DIR ${NRN_INSTALL_DATA_PREFIX}) set(NRN_BUILD_SHARE_DIR ${CMAKE_BINARY_DIR}) - set(NRN_INSTALL_SHARE_LIB_DIR ${NRN_INSTALL_DATA_PREFIX}/bin) + set(NRN_INSTALL_SHARE_LIB_DIR ${NRN_INSTALL_DATA_PREFIX}bin) else() - set(NRN_INSTALL_SHARE_DIR ${NRN_INSTALL_DATA_PREFIX}/share/nrn) + set(NRN_INSTALL_SHARE_DIR ${NRN_INSTALL_DATA_PREFIX}share/nrn) set(NRN_BUILD_SHARE_DIR ${CMAKE_BINARY_DIR}/share/nrn) - set(NRN_INSTALL_SHARE_LIB_DIR ${NRN_INSTALL_DATA_PREFIX}/lib) + set(NRN_INSTALL_SHARE_LIB_DIR ${NRN_INSTALL_DATA_PREFIX}lib) endif() # ============================================================================= @@ -1100,7 +1099,7 @@ add_custom_target( COMMENT "Copying headers to build directory" DEPENDS ${headers_in_build_dir}) add_dependencies(nrniv_lib copy_headers_to_build) -install(DIRECTORY ${PROJECT_BINARY_DIR}/include DESTINATION "${NRN_INSTALL_DATA_PREFIX}") +install(DIRECTORY ${PROJECT_BINARY_DIR}/include/ DESTINATION "${NRN_INSTALL_DATA_PREFIX}include") if(NRN_MACOS_BUILD AND NOT SKBUILD) # universal build for neurondemo needs to be after, or at end of, install @@ -1119,11 +1118,11 @@ configure_file(cmake/mod_reg_corenrn.cpp.in install( TARGETS ${CORENRN_INSTALL_LIB_TARGETS} EXPORT NeuronTargets - DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib") + DESTINATION "${NRN_INSTALL_DATA_PREFIX}lib") install( TARGETS ${CORENRN_INSTALL_BIN_TARGETS} EXPORT NeuronTargets - DESTINATION "${NRN_INSTALL_DATA_PREFIX}/bin") + DESTINATION "${NRN_INSTALL_DATA_PREFIX}bin") export( EXPORT NeuronTargets FILE ${PROJECT_BINARY_DIR}/lib/cmake/neuron/neuronTargets.cmake @@ -1133,19 +1132,19 @@ install( EXPORT NeuronTargets FILE neuronTargets.cmake NAMESPACE neuron:: - DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib/cmake/neuron") + DESTINATION "${NRN_INSTALL_DATA_PREFIX}lib/cmake/neuron") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/neuronConfig.cmake - DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib/cmake/neuron") + DESTINATION "${NRN_INSTALL_DATA_PREFIX}lib/cmake/neuron") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuronMechMaker.cmake - DESTINATION "${NRN_INSTALL_DATA_PREFIX}/lib/cmake/neuron") + DESTINATION "${NRN_INSTALL_DATA_PREFIX}lib/cmake/neuron") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_nrn.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_corenrn.cpp.in - DESTINATION "${NRN_INSTALL_DATA_PREFIX}/share/nrn") + DESTINATION "${NRN_INSTALL_DATA_PREFIX}share/nrn") # ============================================================================= # Copy bash executable for windows @@ -1173,10 +1172,10 @@ endif() # ============================================================================= if(NOT NRN_WINDOWS_BUILD) # create arch folder under prefix with symlink to bin and lib - nrn_install_dir_symlink(${NRN_INSTALL_DATA_PREFIX}/bin - ${NRN_INSTALL_DATA_PREFIX}/${CMAKE_HOST_SYSTEM_PROCESSOR}/bin) - nrn_install_dir_symlink(${NRN_INSTALL_DATA_PREFIX}/lib - ${NRN_INSTALL_DATA_PREFIX}/${CMAKE_HOST_SYSTEM_PROCESSOR}/lib) + nrn_install_dir_symlink(${NRN_INSTALL_DATA_PREFIX}bin + ${NRN_INSTALL_DATA_PREFIX}${CMAKE_HOST_SYSTEM_PROCESSOR}/bin) + nrn_install_dir_symlink(${NRN_INSTALL_DATA_PREFIX}lib + ${NRN_INSTALL_DATA_PREFIX}${CMAKE_HOST_SYSTEM_PROCESSOR}/lib) endif() # ============================================================================= diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 5989c54550..09a3e19d1a 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -68,9 +68,9 @@ file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/bin/tmp") # Install targets # ============================================================================= install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/nrngui ${PROJECT_BINARY_DIR}/bin/neurondemo - ${PROJECT_BINARY_DIR}/bin/nrnivmodl DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) + ${PROJECT_BINARY_DIR}/bin/nrnivmodl DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) -install(FILES ${PROJECT_BINARY_DIR}/bin/nrnmech_makefile DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) +install(FILES ${PROJECT_BINARY_DIR}/bin/nrnmech_makefile DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/sortspike ${CMAKE_CURRENT_SOURCE_DIR}/mkthreadsafe ${PROJECT_BINARY_DIR}/bin/nrnpyenv.sh ${CMAKE_CURRENT_SOURCE_DIR}/set_nrnpyenv.sh - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) + DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) diff --git a/src/coreneuron/CMakeLists.txt b/src/coreneuron/CMakeLists.txt index 2061990101..df591e2ee5 100644 --- a/src/coreneuron/CMakeLists.txt +++ b/src/coreneuron/CMakeLists.txt @@ -500,7 +500,7 @@ if(NRN_ENABLE_MPI AND NRN_ENABLE_MPI_DYNAMIC) PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib POSITION_INDEPENDENT_CODE ON) - install(TARGETS ${corenrn_mpi_targets} DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib) + install(TARGETS ${corenrn_mpi_targets} DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib) endif() # Suppress some compiler warnings. @@ -509,7 +509,8 @@ target_link_libraries(coreneuron-core PUBLIC ${sonatareport_LIBRARY} ${CORENRN_C ${CORENRN_LIKWID_LIB}) set_target_properties(coreneuron-core PROPERTIES EXPORT_NAME corenrn) target_compile_features(coreneuron-core PUBLIC cxx_std_17) -target_include_directories(coreneuron-core INTERFACE $) +target_include_directories(coreneuron-core + INTERFACE $) # TODO: fix adding a dependency of coreneuron-core on CLI11::CLI11 when CLI11 is a submodule. Right # now this doesn't work because the CLI11 targets are not exported/installed but coreneuron-core is. @@ -646,46 +647,46 @@ endif() install( TARGETS coreneuron-core ${coreneuron_cuda_target} EXPORT coreneuron - LIBRARY DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib - ARCHIVE DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib + LIBRARY DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib + ARCHIVE DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib INCLUDES - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/include) + DESTINATION ${NRN_INSTALL_DATA_PREFIX}include) # headers and some standalone code files for nrnivmodl-core install( DIRECTORY ${CMAKE_BINARY_DIR}/include/coreneuron - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/include/ + DESTINATION ${NRN_INSTALL_DATA_PREFIX}include/ FILES_MATCHING PATTERN "*.h*" PATTERN "*.ipp") install(FILES ${MODFUNC_SHELL_SCRIPT} ${ENGINEMECH_CODE_FILE} - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/share/coreneuron) + DESTINATION ${NRN_INSTALL_DATA_PREFIX}share/coreneuron) # copy nmodl for nrnivmodl-core -install(PROGRAMS ${CORENRN_NMODL_BINARY} DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) +install(PROGRAMS ${CORENRN_NMODL_BINARY} DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) # install nrniv-core app install( PROGRAMS ${CMAKE_BINARY_DIR}/bin/${CMAKE_HOST_SYSTEM_PROCESSOR}/special-core - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin + DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin RENAME nrniv-core) -install(FILES apps/coreneuron.cpp DESTINATION ${NRN_INSTALL_DATA_PREFIX}/share/coreneuron) +install(FILES apps/coreneuron.cpp DESTINATION ${NRN_INSTALL_DATA_PREFIX}share/coreneuron) # install mechanism library in shared library builds, if we're linking statically then there is no # need if(CORENRN_ENABLE_SHARED) - install(FILES ${corenrn_mech_library} DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib) + install(FILES ${corenrn_mech_library} DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib) endif() # install mod files -install(DIRECTORY ${CMAKE_BINARY_DIR}/share/modfile DESTINATION ${NRN_INSTALL_DATA_PREFIX}/share) +install(DIRECTORY ${CMAKE_BINARY_DIR}/share/modfile DESTINATION ${NRN_INSTALL_DATA_PREFIX}share) # ============================================================================= # Install for end users # ============================================================================= install(FILES ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/share/coreneuron) -install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) + DESTINATION ${NRN_INSTALL_DATA_PREFIX}share/coreneuron) +install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) # ============================================================================= # Set flag for NEURON linking diff --git a/src/nmodl/pybind/CMakeLists.txt b/src/nmodl/pybind/CMakeLists.txt index 9b8c4ed73d..e4af21839c 100644 --- a/src/nmodl/pybind/CMakeLists.txt +++ b/src/nmodl/pybind/CMakeLists.txt @@ -110,13 +110,13 @@ file(COPY ${NMODL_PROJECT_PURELIB_SOURCE_DIR}/ext DESTINATION ${NMODL_PROJECT_PU # Install python binding components # ============================================================================= if(NOT NRN_LINK_AGAINST_PYTHON) - install(TARGETS pywrapper DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib) + install(TARGETS pywrapper DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib) if(NMODL_ENABLE_PYTHON_BINDINGS) - install(TARGETS _nmodl DESTINATION ${NRN_INSTALL_PYTHON_PREFIX}/nmodl) + install(TARGETS _nmodl DESTINATION ${NRN_INSTALL_PYTHON_PREFIX}nmodl) endif() else() install( DIRECTORY ${CMAKE_BINARY_DIR}/lib/ - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib + DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib PATTERN "__pycache__" EXCLUDE) endif() diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index b03eeacdcb..839e568e33 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -410,7 +410,7 @@ cpp_cc_configure_sanitizers(TARGET nrniv_lib) # Source-directory .cpp needs to find generated .hpp. target_include_directories(nrniv_lib PUBLIC $) target_include_directories(nrniv_lib - INTERFACE $) + INTERFACE $) if(NRN_ENABLE_PYTHON AND NOT NRN_ENABLE_PYTHON_DYNAMIC) target_link_libraries(nrniv_lib PRIVATE nrnpython) endif() @@ -580,10 +580,10 @@ endif() # For now, we keep this distinction as it reduces the PATH and is # expected when ctypes looks for dlls # ~~~ -install(TARGETS nrniv nocmodl modlunit DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin) +install(TARGETS nrniv nocmodl modlunit DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) install( TARGETS nocmodl - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/bin + DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin EXPORT NeuronTargets) install( TARGETS nrniv_lib @@ -591,7 +591,7 @@ install( EXPORT NeuronTargets) if(LIBIVX11DYNAM_NAME) install(FILES ${PROJECT_BINARY_DIR}/lib/${LIBIVX11DYNAM_NAME} - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/lib) + DESTINATION ${NRN_INSTALL_DATA_PREFIX}lib) endif() # ============================================================================= @@ -620,4 +620,4 @@ add_custom_target( # For the installation install(FILES ${PROJECT_SOURCE_DIR}/src/ivoc/nrnmain.cpp - DESTINATION ${NRN_INSTALL_DATA_PREFIX}/share/nrn) + DESTINATION ${NRN_INSTALL_DATA_PREFIX}share/nrn) From e086ace1f26ff039033af23ec7c50047b7722c5e Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Sat, 21 Jun 2025 09:35:54 +0200 Subject: [PATCH 45/63] Add workaround for running special under wheels --- cmake/neuronConfig.cmake.in | 2 ++ cmake/neuronMechMaker.cmake | 16 +++++++++++++--- share/lib/python/scripts/CMakeLists.txt | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index b791720bd3..60d1ac3dec 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -12,6 +12,8 @@ set(NRN_ENABLE_CORENEURON @NRN_ENABLE_CORENEURON@) set(_NEURON_MAIN "${_prefix}/share/nrn/nrnmain.cpp") set(_NEURON_MAIN_INCLUDE_DIR "${_prefix}/include/nrncvode" "${_prefix}/include") set(_NEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_nrn.cpp.in") +set(_NEURON_WHEEL @SKBUILD@) +set(_NEURON_PYTHON_BINWRAPPER "${_prefix}/share/nrn/binwrapper.py") set(_CORENEURON_BASE_MOD "${_prefix}/share/modfile") set(_CORENEURON_MAIN "${_prefix}/share/coreneuron/coreneuron.cpp") diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 7e91032fb3..7d68bb4dcf 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -406,9 +406,19 @@ function(create_nrnmech) target_include_directories(${TARGET_EXECUTABLE_NAME} BEFORE PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) target_link_libraries(${TARGET_EXECUTABLE_NAME} PUBLIC ${TARGET_LIBRARY_NAME}) - set_target_properties( - ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special" RUNTIME_OUTPUT_DIRECTORY - "${EXECUTABLE_OUTPUT_DIR}") + if(NOT _NEURON_WHEEL) + set_target_properties( + ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special" RUNTIME_OUTPUT_DIRECTORY + "${EXECUTABLE_OUTPUT_DIR}") + else() + # we use a Python wrapper for `special` so the env is set properly when launched + configure_file(${_NEURON_PYTHON_BINWRAPPER} "${ARTIFACTS_OUTPUT_DIR}/special" COPYONLY) + add_custom_target(py${TARGET_EXECUTABLE_NAME} ALL DEPENDS "${ARTIFACTS_OUTPUT_DIR}/special") + + set_target_properties( + ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special.nrn" RUNTIME_OUTPUT_DIRECTORY + "${EXECUTABLE_OUTPUT_DIR}") + endif() endif() endif() diff --git a/share/lib/python/scripts/CMakeLists.txt b/share/lib/python/scripts/CMakeLists.txt index 23a34609a0..bbc3327148 100644 --- a/share/lib/python/scripts/CMakeLists.txt +++ b/share/lib/python/scripts/CMakeLists.txt @@ -19,4 +19,6 @@ if(SKBUILD) DESTINATION "${SKBUILD_SCRIPTS_DIR}" RENAME "${script}") endforeach() + # in order for mechanism building via CMake to work with a Python wheel, we need `binwrapper.py` + install(PROGRAMS binwrapper.py DESTINATION "${NRN_INSTALL_DATA_PREFIX}share/nrn") endif() From a40003ff3825c6c746ff2b7b58a110e1f4467b91 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Sat, 21 Jun 2025 09:44:36 +0200 Subject: [PATCH 46/63] Update docs for CMake API --- cmake/neuronMechMaker.cmake | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index 7d68bb4dcf..fc0e6aaeb8 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -35,6 +35,27 @@ API reference .. cmake:command:: create_nrnmech + .. code-block:: cmake + + create_nrnmech( + [NEURON] + [CORENEURON] + [SPECIAL] + [NMODL_NEURON_CODEGEN] + [TARGET_LIBRARY_NAME lib_tgt] + [TARGET_EXECUTABLE_NAME exe_tgt] + [LIBRARY_OUTPUT_DIR lib_outdir] + [EXECUTABLE_OUTPUT_DIR exe_outdir] + [ARTIFACTS_OUTPUT_DIR art_outdir] + [LIBRARY_TYPE type] + [NOCMODL_EXECUTABLE path/to/nocmodl] + [NMODL_EXECUTABLE path/to/nmodl] + [MOD_FILES mod1 mod2 ...] + [NMODL_NEURON_EXTRA_ARGS arg1 arg2 ...] + [NMODL_CORENEURON_EXTRA_ARGS arg1 arg2 ...] + [EXTRA_ENV KEY1=VAL1 KEY2=VAL2 ...] + ) + **Options** ``NEURON`` @@ -55,8 +76,17 @@ API reference ``TARGET_EXECUTABLE_NAME`` (*optional*, default: ``special``) the name of the CMake target for the executable. Note that ``-core`` is appended to the coreNEURON target. + ``LIBRARY_OUTPUT_DIR`` + (*optional*, default: ``CMAKE_CURRENT_BINARY_DIR``) the path where the library targets will be placed at build-time. + + ``EXECUTABLE_OUTPUT_DIR`` + (*optional*, default: ``CMAKE_CURRENT_BINARY_DIR``) the path where the executable targets will be placed at build-time. + ``ARTIFACTS_OUTPUT_DIR`` - (*optional*) the path where the CPP files will be placed at build-time. + (*optional*, default: ``CMAKE_CURRENT_BINARY_DIR``) the path where the CPP files will be placed at build-time. + + ``LIBRARY_TYPE`` + (*optional*, default: ``SHARED``) the type of library to build. ``NOCMODL_EXECUTABLE`` (*optional*) the path to the NOCMODL executable. If not specified, attempts to find deduce the location of the executable from the NEURON CMake configuration. From 67c27596a0f9b73bd32dd1162263ed93ae7e6d14 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Sat, 21 Jun 2025 09:46:37 +0200 Subject: [PATCH 47/63] Fix install dir on Windows --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17cf66ee13..4e550002f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -721,9 +721,9 @@ include(ConfigFileSetting) # well. Setting these here as setup.py.in needs it. # ~~~ if(MINGW) - set(NRN_INSTALL_SHARE_DIR ${NRN_INSTALL_DATA_PREFIX}) + set(NRN_INSTALL_SHARE_DIR ${CMAKE_INSTALL_PREFIX}) set(NRN_BUILD_SHARE_DIR ${CMAKE_BINARY_DIR}) - set(NRN_INSTALL_SHARE_LIB_DIR ${NRN_INSTALL_DATA_PREFIX}bin) + set(NRN_INSTALL_SHARE_LIB_DIR ${CMAKE_INSTALL_PREFIX}/bin) else() set(NRN_INSTALL_SHARE_DIR ${NRN_INSTALL_DATA_PREFIX}share/nrn) set(NRN_BUILD_SHARE_DIR ${CMAKE_BINARY_DIR}/share/nrn) From 4e0d8cb0b26be55281fefd07d29d46499a6ee9c0 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Mon, 24 Nov 2025 11:28:32 +0100 Subject: [PATCH 48/63] Refactor test --- test/nrnivmodl_cmake/CMakeLists.txt | 32 ++++------- test/nrnivmodl_cmake/run_modfiles_test.cmake | 57 ++++++++++++++++++++ 2 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 test/nrnivmodl_cmake/run_modfiles_test.cmake diff --git a/test/nrnivmodl_cmake/CMakeLists.txt b/test/nrnivmodl_cmake/CMakeLists.txt index 50e1d9dabd..f477db26a1 100644 --- a/test/nrnivmodl_cmake/CMakeLists.txt +++ b/test/nrnivmodl_cmake/CMakeLists.txt @@ -19,28 +19,16 @@ if(CMAKE_CUDA_COMPILER) endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build_cmake/CMakeLists.txt" "${CMAKE_CURRENT_BINARY_DIR}/build_cmake/CMakeLists.txt" @ONLY) -set(test_command - "CMAKE_PREFIX_PATH='${PROJECT_BINARY_DIR}/lib/cmake' \ - PATH='${PROJECT_BINARY_DIR}/bin:$ENV{PATH}' \ - MODLUNIT='${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib' \ - ${CMAKE_COMMAND} \ - -S '${CMAKE_CURRENT_BINARY_DIR}/build_cmake' -B '${TEST_DIR}' \ - -DMOD_FILES='${MOD_FILES}' \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCORENEURON=${CORENEURON} \ - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} \ - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") -if(CMAKE_LANGUAGES MATCHES "CUDA") - set(test_command "${test_command} -DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}") -endif() add_test( NAME "${TEST_NAMESPACE}::modfiles" COMMAND - sh -c " - rm -fr ${TEST_DIR} \ - && ${test_command} \ - && \ - ${CMAKE_COMMAND} --build '${TEST_DIR}' -v --parallel \ - && \ - '${TEST_DIR}/special' -nopython -nobanner -nogui -c 'quit()' \ - rm -fr '${TEST_DIR}'") + ${CMAKE_COMMAND} "-DTEST_DIR=${TEST_DIR}" "-DMOD_FILES=${MOD_FILES}" + "-DCORENEURON=${CORENEURON}" "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}" -P + "${CMAKE_CURRENT_SOURCE_DIR}/run_modfiles_test.cmake") + +set_tests_properties( + "${TEST_NAMESPACE}::modfiles" + PROPERTIES + ENVIRONMENT + "CMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/lib/cmake;PATH=${PROJECT_BINARY_DIR}/bin:$ENV{PATH}") diff --git a/test/nrnivmodl_cmake/run_modfiles_test.cmake b/test/nrnivmodl_cmake/run_modfiles_test.cmake new file mode 100644 index 0000000000..d1d163b6af --- /dev/null +++ b/test/nrnivmodl_cmake/run_modfiles_test.cmake @@ -0,0 +1,57 @@ +# Ensure cleanup even if something fails +function(cleanup) + message(STATUS "Cleaning up ${TEST_DIR}") + file(REMOVE_RECURSE "${TEST_DIR}") +endfunction() + +cleanup() + +message(STATUS "Mod files: ${MOD_FILES}") +# Due to CMake not being a useful language, and having only a string type, we need to do some +# escaping in order to pass things along to the CLI +string(REPLACE " " "\ " MOD_FILES "${MOD_FILES}") +string(REPLACE ";" "\;" MOD_FILES "${MOD_FILES}") + +# Configure +if(CMAKE_CUDA_COMPILER) + # One would figure saving the below into a variable, and only appending the CUDA stuff if + # necessary, would work, but alas, due to quoting rules, I can't figure out the magic combination + # of those that actually work, so we just duplicate the command string verbatim. + execute_process( + COMMAND + "${CMAKE_COMMAND}" -S "${CMAKE_CURRENT_BINARY_DIR}/build_cmake" -B "${TEST_DIR}" + -DMOD_FILES=${MOD_FILES} -DCMAKE_BUILD_TYPE=Debug -DCORENEURON=${CORENEURON} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER} + RESULT_VARIABLE res_configure) +else() + execute_process( + COMMAND + "${CMAKE_COMMAND}" -S "${CMAKE_CURRENT_BINARY_DIR}/build_cmake" -B "${TEST_DIR}" + -DMOD_FILES=${MOD_FILES} -DCMAKE_BUILD_TYPE=Debug -DCORENEURON=${CORENEURON} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + RESULT_VARIABLE res_configure) +endif() + +if(NOT res_configure EQUAL 0) + cleanup() + message(FATAL_ERROR "Configure failed") +endif() + +# Build +set(BUILD_COMMAND "${CMAKE_COMMAND}" --build "${TEST_DIR}" --parallel -v) +execute_process(COMMAND ${BUILD_COMMAND} RESULT_VARIABLE res_build) +if(NOT res_build EQUAL 0) + message(FATAL_ERROR "Build failed") +endif() + +# Run executable +set(EXE_COMMAND "${TEST_DIR}/special" -nopython -nobanner -nogui -c "quit()") +execute_process(COMMAND ${EXE_COMMAND} RESULT_VARIABLE res_run) +if(NOT res_run EQUAL 0) + cleanup() + message(FATAL_ERROR "Executable failed") +endif() + +# Cleanup at the end +cleanup() From 539f509e9b8b68c6e84617d07312dcbfec64d4b3 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Mon, 24 Nov 2025 12:50:48 +0100 Subject: [PATCH 49/63] Revert "Merge branch 'jelic/parallel_lcov'" This reverts commit 009cc344204ef3c01c60b2ca385483f2897de4e7, reversing changes made to 773e7f281d340001ab70e62290279149eee63458. --- .github/workflows/coverage.yml | 2 +- cmake/Coverage.cmake | 23 +++++++---------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 90cccf2f13..afd8251f73 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,7 +49,7 @@ jobs: - name: Install apt packages run: | - sudo apt-get install xfonts-100dpi build-essential doxygen lcov libboost-all-dev libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin gpg ninja-build flex bison libfl-dev libreadline-dev + sudo apt-get install xfonts-100dpi build-essential doxygen lcov libboost-all-dev libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin gpg ninja-build flex bison libfl-dev shell: bash - name: Install a new ccache diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index 7189f1f7e3..d86a02bca0 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -114,25 +114,16 @@ macro(nrn_enable_coverage_files) endmacro() if(NRN_ENABLE_COVERAGE) - if(LCOV_VERSION GREATER_EQUAL "2.0") - set(LCOV_LAUNCHER ${LCOV} --parallel ${CMAKE_BUILD_PARALLEL_LEVEL} --ignore-errors mismatch) - set(GENHTML_LAUNCHER genhtml --parallel ${CMAKE_BUILD_PARALLEL_LEVEL}) - else() - set(LCOV_LAUNCHER ${LCOV}) - set(GENHTML_LAUNCHER genhtml) - endif() set(cover_clean_command find "${PROJECT_BINARY_DIR}" "-name" "*.gcda" "-type" "f" "-delete") set(cover_baseline_command - "${LCOV_LAUNCHER}" "--capture" "--initial" "--no-external" "--directory" - "${PROJECT_SOURCE_DIR}" "--directory" "${PROJECT_BINARY_DIR}" "--output-file" - "coverage-base.info") + "${LCOV}" "--capture" "--initial" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" + "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-base.info") set(cover_collect_command - "${LCOV_LAUNCHER}" "--capture" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" - "--directory" "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info") - set(cover_combine_command - "${LCOV_LAUNCHER}" "--add-tracefile" "coverage-base.info" "--add-tracefile" - "coverage-run.info" "--output-file" "coverage-combined.info") - set(cover_html_command ${GENHTML_LAUNCHER} "coverage-combined.info" "--output-directory" html) + "${LCOV}" "--capture" "--no-external" "--directory" "${PROJECT_SOURCE_DIR}" "--directory" + "${PROJECT_BINARY_DIR}" "--output-file" "coverage-run.info") + set(cover_combine_command "${LCOV}" "--add-tracefile" "coverage-base.info" "--add-tracefile" + "coverage-run.info" "--output-file" "coverage-combined.info") + set(cover_html_command genhtml "coverage-combined.info" "--output-directory" html) add_custom_target( cover_clean COMMAND ${cover_clean_command} From e49258358be98777492494dc7253f5c9996c5032 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Mon, 24 Nov 2025 12:56:32 +0100 Subject: [PATCH 50/63] Make min version match one of NEURON --- test/nrnivmodl_cmake/build_cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nrnivmodl_cmake/build_cmake/CMakeLists.txt b/test/nrnivmodl_cmake/build_cmake/CMakeLists.txt index fd8ccf52e0..f166d35692 100644 --- a/test/nrnivmodl_cmake/build_cmake/CMakeLists.txt +++ b/test/nrnivmodl_cmake/build_cmake/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION @CMAKE_MINIMUM_REQUIRED_VERSION@) project(modfile_test LANGUAGES C CXX @CUDA_STRING@) find_package(neuron REQUIRED) From aabe405ed7708cb0c94910ae3dacf6e91c58bc9b Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Mon, 24 Nov 2025 17:30:55 +0100 Subject: [PATCH 51/63] Fix issue with embedded nrnunits.lib --- CMakeLists.txt | 18 +++++++++++++++ cmake/ConfigFileSetting.cmake | 18 --------------- share/lib/python/scripts/binwrapper.py | 1 - share/nmodl/{nrnunits.lib => nrnunits.lib.in} | 3 ++- src/nmodl/CMakeLists.txt | 11 ++++++++-- src/nmodl/config/config.cpp.in | 5 +++++ src/nmodl/config/config.h | 22 ++++++++++++++++++- src/nmodl/utils/CMakeLists.txt | 1 + test/nmodl/transpiler/unit/CMakeLists.txt | 1 + 9 files changed, 57 insertions(+), 23 deletions(-) rename share/nmodl/{nrnunits.lib => nrnunits.lib.in} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d7430884..60466c53f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -585,6 +585,24 @@ endif() # initialize CLI11 submodule cpp_cc_git_submodule(CLI11 BUILD PACKAGE CLI11 REQUIRED) +# ============================================================================= +# Copy "old" nrnunits.lib to build dir +# ============================================================================= +set(nrnunits_start "") +set(nrnunits_stop "") + +configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in + ${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib @ONLY) + +# ============================================================================= +# use a C++11 string literal to embed nrnunits.lib directly in C++ code, see: +# https://en.cppreference.com/w/cpp/language/string_literal.html +# ============================================================================= +set(nrnunits_start "R\"nrnunits(") +set(nrnunits_stop ")nrnunits\"") +configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in + ${PROJECT_BINARY_DIR}/share/nrn/lib/embedded_nrnunits.lib @ONLY) + # coreneuron targets will get propagated down from the subdirectory # ============================================================================= diff --git a/cmake/ConfigFileSetting.cmake b/cmake/ConfigFileSetting.cmake index 2c42b0a722..8b7ee8956c 100644 --- a/cmake/ConfigFileSetting.cmake +++ b/cmake/ConfigFileSetting.cmake @@ -161,24 +161,6 @@ configure_file("${PROJECT_SOURCE_DIR}/src/sundials/sundials_config.h.in" configure_file("${PROJECT_SOURCE_DIR}/share/lib/nrn.defaults.in" "${PROJECT_BINARY_DIR}/share/nrn/lib/nrn.defaults" @ONLY) -# ============================================================================= -# Copy "old" nrnunits.lib to build dir -# ============================================================================= -set(nrnunits_start "") -set(nrnunits_stop "") - -configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in - ${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib @ONLY) - -# ============================================================================= -# use a C++11 string literal to embed nrnunits.lib directly in C++ code, see: -# https://en.cppreference.com/w/cpp/language/string_literal.html -# ============================================================================= -set(nrnunits_start "R\"nrnunits(") -set(nrnunits_stop ")nrnunits\"") -configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in - ${PROJECT_BINARY_DIR}/share/nrn/lib/embedded_nrnunits.lib @ONLY) - if(NRN_MACOS_BUILD) set(abs_top_builddir ${PROJECT_BINARY_DIR}) configure_file("${PROJECT_SOURCE_DIR}/src/mac/macdist.pkgproj.in" diff --git a/share/lib/python/scripts/binwrapper.py b/share/lib/python/scripts/binwrapper.py index ba751e65c0..55f815baaa 100755 --- a/share/lib/python/scripts/binwrapper.py +++ b/share/lib/python/scripts/binwrapper.py @@ -82,7 +82,6 @@ def _config_exe(exe_name): os.environ["CORENRNHOME"] = NRN_PREFIX os.environ["NRN_PYTHONEXE"] = sys.executable os.environ["CORENRN_PYTHONEXE"] = sys.executable - os.environ["CORENRN_PERLEXE"] = shutil.which("perl") os.environ["NRNBIN"] = os.path.dirname(__file__) if "NMODLHOME" not in os.environ: diff --git a/share/nmodl/nrnunits.lib b/share/nmodl/nrnunits.lib.in similarity index 99% rename from share/nmodl/nrnunits.lib rename to share/nmodl/nrnunits.lib.in index 3abc601834..eba80af32b 100755 --- a/share/nmodl/nrnunits.lib +++ b/share/nmodl/nrnunits.lib.in @@ -1,4 +1,4 @@ -/ from gnu units distribution +@nrnunits_start@/ from gnu units distribution / Nov, 2017 updated faraday, R, e, planck, hbar, mole, k according to / https://physics.nist.gov/cuu/Constants/index.html @@ -620,3 +620,4 @@ linenyarncount 900 ft/pound worstedyarncount 1680 ft/pound metricyarncount meter/gram jewlerspoint 2 milligram +@nrnunits_stop@ diff --git a/src/nmodl/CMakeLists.txt b/src/nmodl/CMakeLists.txt index e5c47a8edd..14c0e0fde8 100644 --- a/src/nmodl/CMakeLists.txt +++ b/src/nmodl/CMakeLists.txt @@ -137,8 +137,15 @@ install( EXPORT nmodlTargets RUNTIME DESTINATION ${NMODL_INSTALL_DIR_SUFFIX}bin) -configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib - ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib COPYONLY) +set(nrnunits_start "") +set(nrnunits_stop "") +configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib.in + ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib @ONLY) +set(nrnunits_start "R\"nrnunits(") +set(nrnunits_stop ")nrnunits\"") +configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib.in + ${PROJECT_BINARY_DIR}/share/nmodl/embedded_nrnunits.lib @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib DESTINATION ${NMODL_INSTALL_DIR_SUFFIX}share/nmodl) diff --git a/src/nmodl/config/config.cpp.in b/src/nmodl/config/config.cpp.in index 9dd05e25ba..6291d33206 100644 --- a/src/nmodl/config/config.cpp.in +++ b/src/nmodl/config/config.cpp.in @@ -15,6 +15,11 @@ const std::string nmodl::Version::NMODL_VERSION = "@PROJECT_VERSION@"; const std::string nmodl::CMakeInfo::SHARED_LIBRARY_SUFFIX = "@CMAKE_SHARED_LIBRARY_SUFFIX@"; +/// If none of the paths below work, we use the embedded version +const std::string_view nmodl::NrnUnitsLib::embedded_nrnunits = +#include "embedded_nrnunits.lib" +; + /** * \brief Path of nrnutils.lib file * diff --git a/src/nmodl/config/config.h b/src/nmodl/config/config.h index df5d7d379a..6b83c2230a 100644 --- a/src/nmodl/config/config.h +++ b/src/nmodl/config/config.h @@ -15,15 +15,19 @@ * \brief Version information and units file path */ +#include #include +#include #include #include #include +#include #include #include "utils/common_utils.hpp" namespace nmodl { +namespace fs = std::filesystem; /** * \brief Project version information @@ -48,6 +52,8 @@ struct NrnUnitsLib { /// paths where nrnunits.lib can be found static std::vector NRNUNITSLIB_PATH; + static const std::string_view embedded_nrnunits; + /** * Return path of units database file */ @@ -70,7 +76,21 @@ struct NrnUnitsLib { for (const auto& path: NRNUNITSLIB_PATH) { err_msg << path << "\n"; } - throw std::runtime_error(err_msg.str()); + err_msg << "Falling back to embedded nrnunits.lib\n"; + const auto& temp_dir = fs::temp_directory_path(); + + const auto& embedded_path = temp_dir / "nrnunits.lib"; + const auto& lock_dir = embedded_path.string() + ".lock"; + while (not fs::create_directory(lock_dir)) { + // Someone else has the lock, wait + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + if (not fs::exists(embedded_path)) { + auto file = std::ofstream(embedded_path); + file << embedded_nrnunits; + } + fs::remove(lock_dir); + return embedded_path; } }; diff --git a/src/nmodl/utils/CMakeLists.txt b/src/nmodl/utils/CMakeLists.txt index ed80309327..92ba924da3 100644 --- a/src/nmodl/utils/CMakeLists.txt +++ b/src/nmodl/utils/CMakeLists.txt @@ -12,6 +12,7 @@ add_library( table_data.cpp ${PROJECT_BINARY_DIR}/src/nmodl/config/config.cpp) +target_include_directories(util PUBLIC "${PROJECT_BINARY_DIR}/share/nmodl") set_property(TARGET util PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(util PUBLIC fmt::fmt nlohmann_json::nlohmann_json spdlog::spdlog) diff --git a/test/nmodl/transpiler/unit/CMakeLists.txt b/test/nmodl/transpiler/unit/CMakeLists.txt index 68c6bfe9eb..67cc996a83 100644 --- a/test/nmodl/transpiler/unit/CMakeLists.txt +++ b/test/nmodl/transpiler/unit/CMakeLists.txt @@ -30,6 +30,7 @@ target_link_libraries(test_util PUBLIC spdlog::spdlog nmodl_test_flags) # ============================================================================= add_library(config STATIC ${PROJECT_BINARY_DIR}/src/nmodl/config/config.cpp) target_link_libraries(config PUBLIC nmodl_test_flags) +target_include_directories(config PUBLIC "${PROJECT_BINARY_DIR}/share/nmodl") # ============================================================================= # Test executables From 1e189fc18f3fcd947ea6f390b65e66b884c52240 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Mon, 24 Nov 2025 17:31:32 +0100 Subject: [PATCH 52/63] Privately link to readline --- src/nrniv/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index 71915d2f43..8547fc67f1 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -441,9 +441,9 @@ if(NRN_WINDOWS_BUILD) target_link_libraries(nrniv_lib PUBLIC ${TERMCAP_LIBRARIES} ${Readline_LIBRARY}) else() if(READLINE_FOUND) - target_link_libraries(nrniv_lib PUBLIC ${Readline_LIBRARY}) + target_link_libraries(nrniv_lib PRIVATE ${Readline_LIBRARY}) else() - target_link_libraries(nrniv_lib PUBLIC readline) + target_link_libraries(nrniv_lib PRIVATE readline) endif() if(CURSES_FOUND) From 9d763386bd5caa1f1ea35a5652057d39e6e9d9ed Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 25 Nov 2025 12:03:12 +0100 Subject: [PATCH 53/63] Embed nrnunits in NMODL --- share/nmodl/{nrnunits.lib => nrnunits.lib.in} | 3 ++- src/nmodl/CMakeLists.txt | 11 ++++++++-- src/nmodl/config/config.cpp.in | 5 +++++ src/nmodl/config/config.h | 21 ++++++++++++++++++- src/nmodl/main.cpp | 2 +- src/nmodl/utils/CMakeLists.txt | 1 + src/nmodl/visitors/units_visitor.cpp | 2 +- src/nmodl/visitors/units_visitor.hpp | 12 +++++------ test/nmodl/transpiler/unit/CMakeLists.txt | 1 + test/nmodl/transpiler/unit/visitor/units.cpp | 2 +- 10 files changed, 47 insertions(+), 13 deletions(-) rename share/nmodl/{nrnunits.lib => nrnunits.lib.in} (99%) diff --git a/share/nmodl/nrnunits.lib b/share/nmodl/nrnunits.lib.in similarity index 99% rename from share/nmodl/nrnunits.lib rename to share/nmodl/nrnunits.lib.in index 3abc601834..eba80af32b 100755 --- a/share/nmodl/nrnunits.lib +++ b/share/nmodl/nrnunits.lib.in @@ -1,4 +1,4 @@ -/ from gnu units distribution +@nrnunits_start@/ from gnu units distribution / Nov, 2017 updated faraday, R, e, planck, hbar, mole, k according to / https://physics.nist.gov/cuu/Constants/index.html @@ -620,3 +620,4 @@ linenyarncount 900 ft/pound worstedyarncount 1680 ft/pound metricyarncount meter/gram jewlerspoint 2 milligram +@nrnunits_stop@ diff --git a/src/nmodl/CMakeLists.txt b/src/nmodl/CMakeLists.txt index e5c47a8edd..14c0e0fde8 100644 --- a/src/nmodl/CMakeLists.txt +++ b/src/nmodl/CMakeLists.txt @@ -137,8 +137,15 @@ install( EXPORT nmodlTargets RUNTIME DESTINATION ${NMODL_INSTALL_DIR_SUFFIX}bin) -configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib - ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib COPYONLY) +set(nrnunits_start "") +set(nrnunits_stop "") +configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib.in + ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib @ONLY) +set(nrnunits_start "R\"nrnunits(") +set(nrnunits_stop ")nrnunits\"") +configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib.in + ${PROJECT_BINARY_DIR}/share/nmodl/embedded_nrnunits.lib @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib DESTINATION ${NMODL_INSTALL_DIR_SUFFIX}share/nmodl) diff --git a/src/nmodl/config/config.cpp.in b/src/nmodl/config/config.cpp.in index 9dd05e25ba..6291d33206 100644 --- a/src/nmodl/config/config.cpp.in +++ b/src/nmodl/config/config.cpp.in @@ -15,6 +15,11 @@ const std::string nmodl::Version::NMODL_VERSION = "@PROJECT_VERSION@"; const std::string nmodl::CMakeInfo::SHARED_LIBRARY_SUFFIX = "@CMAKE_SHARED_LIBRARY_SUFFIX@"; +/// If none of the paths below work, we use the embedded version +const std::string_view nmodl::NrnUnitsLib::embedded_nrnunits = +#include "embedded_nrnunits.lib" +; + /** * \brief Path of nrnutils.lib file * diff --git a/src/nmodl/config/config.h b/src/nmodl/config/config.h index df5d7d379a..016df40121 100644 --- a/src/nmodl/config/config.h +++ b/src/nmodl/config/config.h @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -24,6 +25,7 @@ #include "utils/common_utils.hpp" namespace nmodl { +namespace fs = std::filesystem; /** * \brief Project version information @@ -48,6 +50,22 @@ struct NrnUnitsLib { /// paths where nrnunits.lib can be found static std::vector NRNUNITSLIB_PATH; + static const std::string_view embedded_nrnunits; + + /** + * Return content of units database file + */ + static std::string get_content(const std::string& path) { + if (not path.size()) { + return std::string(embedded_nrnunits); + } + auto f = std::ifstream(path.c_str()); + auto size = std::filesystem::file_size(path); + auto content = std::string(size, '\0'); + f.read(content.data(), size); + return content; + } + /** * Return path of units database file */ @@ -70,7 +88,8 @@ struct NrnUnitsLib { for (const auto& path: NRNUNITSLIB_PATH) { err_msg << path << "\n"; } - throw std::runtime_error(err_msg.str()); + err_msg << "Falling back to embedded nrnunits.lib\n"; + return ""; } }; diff --git a/src/nmodl/main.cpp b/src/nmodl/main.cpp index 39eb304a9e..ee87ccf0ad 100644 --- a/src/nmodl/main.cpp +++ b/src/nmodl/main.cpp @@ -482,7 +482,7 @@ int run_nmodl(int argc, const char* argv[]) { /// Parsing units fron "nrnunits.lib" and mod files { logger->info("Parsing Units"); - UnitsVisitor(units_dir).visit_program(*ast); + UnitsVisitor(NrnUnitsLib::get_content(units_dir)).visit_program(*ast); } /// once we start modifying (especially removing) older constructs diff --git a/src/nmodl/utils/CMakeLists.txt b/src/nmodl/utils/CMakeLists.txt index ed80309327..92ba924da3 100644 --- a/src/nmodl/utils/CMakeLists.txt +++ b/src/nmodl/utils/CMakeLists.txt @@ -12,6 +12,7 @@ add_library( table_data.cpp ${PROJECT_BINARY_DIR}/src/nmodl/config/config.cpp) +target_include_directories(util PUBLIC "${PROJECT_BINARY_DIR}/share/nmodl") set_property(TARGET util PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(util PUBLIC fmt::fmt nlohmann_json::nlohmann_json spdlog::spdlog) diff --git a/src/nmodl/visitors/units_visitor.cpp b/src/nmodl/visitors/units_visitor.cpp index 2ad612d0ea..c882c48588 100644 --- a/src/nmodl/visitors/units_visitor.cpp +++ b/src/nmodl/visitors/units_visitor.cpp @@ -20,7 +20,7 @@ namespace nmodl { namespace visitor { void UnitsVisitor::visit_program(ast::Program& node) { - units_driver.parse_file(units_dir); + units_driver.parse_string(units_content); node.visit_children(*this); } diff --git a/src/nmodl/visitors/units_visitor.hpp b/src/nmodl/visitors/units_visitor.hpp index 543b0655a0..aff03a5c05 100644 --- a/src/nmodl/visitors/units_visitor.hpp +++ b/src/nmodl/visitors/units_visitor.hpp @@ -45,8 +45,8 @@ class UnitsVisitor: public AstVisitor { /// mod files' units parser::UnitDriver units_driver; - /// Directory of units lib file that defines all the basic units - std::string units_dir; + /// Content of units lib file that defines all the basic units + std::string units_content; /// Declaration of `fuzz` constant unit, which is the equivilant of `1` /// in mod files UNITS definitions @@ -59,10 +59,10 @@ class UnitsVisitor: public AstVisitor { /// Default UnitsVisitor constructor UnitsVisitor() = default; - /// UnitsVisitor constructor that takes as argument the units file to parse + /// UnitsVisitor constructor that takes as argument the contents of the units file to parse /// the units from - explicit UnitsVisitor(std::string t_units_dir) - : units_dir(std::move(t_units_dir)) {} + explicit UnitsVisitor(std::string t_units_content) + : units_content(std::move(t_units_content)) {} /// \} @@ -74,7 +74,7 @@ class UnitsVisitor: public AstVisitor { /// as ast::FactorDef in the UNITS block of mod files void visit_factor_def(ast::FactorDef& node) override; - /// Override visit_program function to parse the \c nrnunits.lib unit file + /// Override visit_program function to parse the contents of the \c nrnunits.lib unit file /// before starting visiting the AST to parse the units defined in mod files void visit_program(ast::Program& node) override; diff --git a/test/nmodl/transpiler/unit/CMakeLists.txt b/test/nmodl/transpiler/unit/CMakeLists.txt index 68c6bfe9eb..67cc996a83 100644 --- a/test/nmodl/transpiler/unit/CMakeLists.txt +++ b/test/nmodl/transpiler/unit/CMakeLists.txt @@ -30,6 +30,7 @@ target_link_libraries(test_util PUBLIC spdlog::spdlog nmodl_test_flags) # ============================================================================= add_library(config STATIC ${PROJECT_BINARY_DIR}/src/nmodl/config/config.cpp) target_link_libraries(config PUBLIC nmodl_test_flags) +target_include_directories(config PUBLIC "${PROJECT_BINARY_DIR}/share/nmodl") # ============================================================================= # Test executables diff --git a/test/nmodl/transpiler/unit/visitor/units.cpp b/test/nmodl/transpiler/unit/visitor/units.cpp index 36b3a5d4cd..f0c26b2c83 100644 --- a/test/nmodl/transpiler/unit/visitor/units.cpp +++ b/test/nmodl/transpiler/unit/visitor/units.cpp @@ -37,7 +37,7 @@ std::tuple, std::shared_ptr> run // Parse nrnunits.lib file and the UNITS block of the mod file const std::string units_lib_path(NrnUnitsLib::get_path()); - UnitsVisitor units_visitor = UnitsVisitor(units_lib_path); + UnitsVisitor units_visitor = UnitsVisitor(NrnUnitsLib::get_content(units_lib_path)); units_visitor.visit_program(*ast); From 3efeb709cf4f066ddcdc825f1651fd5541187f98 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 25 Nov 2025 12:05:58 +0100 Subject: [PATCH 54/63] Revert "Fix issue with embedded nrnunits.lib" This reverts commit aabe405ed7708cb0c94910ae3dacf6e91c58bc9b. --- CMakeLists.txt | 18 --------------- cmake/ConfigFileSetting.cmake | 18 +++++++++++++++ share/lib/python/scripts/binwrapper.py | 1 + share/nmodl/{nrnunits.lib.in => nrnunits.lib} | 3 +-- src/nmodl/CMakeLists.txt | 11 ++-------- src/nmodl/config/config.cpp.in | 5 ----- src/nmodl/config/config.h | 22 +------------------ src/nmodl/utils/CMakeLists.txt | 1 - test/nmodl/transpiler/unit/CMakeLists.txt | 1 - 9 files changed, 23 insertions(+), 57 deletions(-) rename share/nmodl/{nrnunits.lib.in => nrnunits.lib} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60466c53f3..81d7430884 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -585,24 +585,6 @@ endif() # initialize CLI11 submodule cpp_cc_git_submodule(CLI11 BUILD PACKAGE CLI11 REQUIRED) -# ============================================================================= -# Copy "old" nrnunits.lib to build dir -# ============================================================================= -set(nrnunits_start "") -set(nrnunits_stop "") - -configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in - ${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib @ONLY) - -# ============================================================================= -# use a C++11 string literal to embed nrnunits.lib directly in C++ code, see: -# https://en.cppreference.com/w/cpp/language/string_literal.html -# ============================================================================= -set(nrnunits_start "R\"nrnunits(") -set(nrnunits_stop ")nrnunits\"") -configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in - ${PROJECT_BINARY_DIR}/share/nrn/lib/embedded_nrnunits.lib @ONLY) - # coreneuron targets will get propagated down from the subdirectory # ============================================================================= diff --git a/cmake/ConfigFileSetting.cmake b/cmake/ConfigFileSetting.cmake index 8b7ee8956c..2c42b0a722 100644 --- a/cmake/ConfigFileSetting.cmake +++ b/cmake/ConfigFileSetting.cmake @@ -161,6 +161,24 @@ configure_file("${PROJECT_SOURCE_DIR}/src/sundials/sundials_config.h.in" configure_file("${PROJECT_SOURCE_DIR}/share/lib/nrn.defaults.in" "${PROJECT_BINARY_DIR}/share/nrn/lib/nrn.defaults" @ONLY) +# ============================================================================= +# Copy "old" nrnunits.lib to build dir +# ============================================================================= +set(nrnunits_start "") +set(nrnunits_stop "") + +configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in + ${PROJECT_BINARY_DIR}/share/nrn/lib/nrnunits.lib @ONLY) + +# ============================================================================= +# use a C++11 string literal to embed nrnunits.lib directly in C++ code, see: +# https://en.cppreference.com/w/cpp/language/string_literal.html +# ============================================================================= +set(nrnunits_start "R\"nrnunits(") +set(nrnunits_stop ")nrnunits\"") +configure_file(${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib.in + ${PROJECT_BINARY_DIR}/share/nrn/lib/embedded_nrnunits.lib @ONLY) + if(NRN_MACOS_BUILD) set(abs_top_builddir ${PROJECT_BINARY_DIR}) configure_file("${PROJECT_SOURCE_DIR}/src/mac/macdist.pkgproj.in" diff --git a/share/lib/python/scripts/binwrapper.py b/share/lib/python/scripts/binwrapper.py index 55f815baaa..ba751e65c0 100755 --- a/share/lib/python/scripts/binwrapper.py +++ b/share/lib/python/scripts/binwrapper.py @@ -82,6 +82,7 @@ def _config_exe(exe_name): os.environ["CORENRNHOME"] = NRN_PREFIX os.environ["NRN_PYTHONEXE"] = sys.executable os.environ["CORENRN_PYTHONEXE"] = sys.executable + os.environ["CORENRN_PERLEXE"] = shutil.which("perl") os.environ["NRNBIN"] = os.path.dirname(__file__) if "NMODLHOME" not in os.environ: diff --git a/share/nmodl/nrnunits.lib.in b/share/nmodl/nrnunits.lib similarity index 99% rename from share/nmodl/nrnunits.lib.in rename to share/nmodl/nrnunits.lib index eba80af32b..3abc601834 100755 --- a/share/nmodl/nrnunits.lib.in +++ b/share/nmodl/nrnunits.lib @@ -1,4 +1,4 @@ -@nrnunits_start@/ from gnu units distribution +/ from gnu units distribution / Nov, 2017 updated faraday, R, e, planck, hbar, mole, k according to / https://physics.nist.gov/cuu/Constants/index.html @@ -620,4 +620,3 @@ linenyarncount 900 ft/pound worstedyarncount 1680 ft/pound metricyarncount meter/gram jewlerspoint 2 milligram -@nrnunits_stop@ diff --git a/src/nmodl/CMakeLists.txt b/src/nmodl/CMakeLists.txt index 14c0e0fde8..e5c47a8edd 100644 --- a/src/nmodl/CMakeLists.txt +++ b/src/nmodl/CMakeLists.txt @@ -137,15 +137,8 @@ install( EXPORT nmodlTargets RUNTIME DESTINATION ${NMODL_INSTALL_DIR_SUFFIX}bin) -set(nrnunits_start "") -set(nrnunits_stop "") -configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib.in - ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib @ONLY) -set(nrnunits_start "R\"nrnunits(") -set(nrnunits_stop ")nrnunits\"") -configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib.in - ${PROJECT_BINARY_DIR}/share/nmodl/embedded_nrnunits.lib @ONLY) - +configure_file(${PROJECT_SOURCE_DIR}/share/nmodl/nrnunits.lib + ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib COPYONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/nmodl/nrnunits.lib DESTINATION ${NMODL_INSTALL_DIR_SUFFIX}share/nmodl) diff --git a/src/nmodl/config/config.cpp.in b/src/nmodl/config/config.cpp.in index 6291d33206..9dd05e25ba 100644 --- a/src/nmodl/config/config.cpp.in +++ b/src/nmodl/config/config.cpp.in @@ -15,11 +15,6 @@ const std::string nmodl::Version::NMODL_VERSION = "@PROJECT_VERSION@"; const std::string nmodl::CMakeInfo::SHARED_LIBRARY_SUFFIX = "@CMAKE_SHARED_LIBRARY_SUFFIX@"; -/// If none of the paths below work, we use the embedded version -const std::string_view nmodl::NrnUnitsLib::embedded_nrnunits = -#include "embedded_nrnunits.lib" -; - /** * \brief Path of nrnutils.lib file * diff --git a/src/nmodl/config/config.h b/src/nmodl/config/config.h index 6b83c2230a..df5d7d379a 100644 --- a/src/nmodl/config/config.h +++ b/src/nmodl/config/config.h @@ -15,19 +15,15 @@ * \brief Version information and units file path */ -#include #include -#include #include #include #include -#include #include #include "utils/common_utils.hpp" namespace nmodl { -namespace fs = std::filesystem; /** * \brief Project version information @@ -52,8 +48,6 @@ struct NrnUnitsLib { /// paths where nrnunits.lib can be found static std::vector NRNUNITSLIB_PATH; - static const std::string_view embedded_nrnunits; - /** * Return path of units database file */ @@ -76,21 +70,7 @@ struct NrnUnitsLib { for (const auto& path: NRNUNITSLIB_PATH) { err_msg << path << "\n"; } - err_msg << "Falling back to embedded nrnunits.lib\n"; - const auto& temp_dir = fs::temp_directory_path(); - - const auto& embedded_path = temp_dir / "nrnunits.lib"; - const auto& lock_dir = embedded_path.string() + ".lock"; - while (not fs::create_directory(lock_dir)) { - // Someone else has the lock, wait - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - if (not fs::exists(embedded_path)) { - auto file = std::ofstream(embedded_path); - file << embedded_nrnunits; - } - fs::remove(lock_dir); - return embedded_path; + throw std::runtime_error(err_msg.str()); } }; diff --git a/src/nmodl/utils/CMakeLists.txt b/src/nmodl/utils/CMakeLists.txt index 92ba924da3..ed80309327 100644 --- a/src/nmodl/utils/CMakeLists.txt +++ b/src/nmodl/utils/CMakeLists.txt @@ -12,7 +12,6 @@ add_library( table_data.cpp ${PROJECT_BINARY_DIR}/src/nmodl/config/config.cpp) -target_include_directories(util PUBLIC "${PROJECT_BINARY_DIR}/share/nmodl") set_property(TARGET util PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(util PUBLIC fmt::fmt nlohmann_json::nlohmann_json spdlog::spdlog) diff --git a/test/nmodl/transpiler/unit/CMakeLists.txt b/test/nmodl/transpiler/unit/CMakeLists.txt index 67cc996a83..68c6bfe9eb 100644 --- a/test/nmodl/transpiler/unit/CMakeLists.txt +++ b/test/nmodl/transpiler/unit/CMakeLists.txt @@ -30,7 +30,6 @@ target_link_libraries(test_util PUBLIC spdlog::spdlog nmodl_test_flags) # ============================================================================= add_library(config STATIC ${PROJECT_BINARY_DIR}/src/nmodl/config/config.cpp) target_link_libraries(config PUBLIC nmodl_test_flags) -target_include_directories(config PUBLIC "${PROJECT_BINARY_DIR}/share/nmodl") # ============================================================================= # Test executables From 6ee81f77b79f43577b4e6fc88676b980856fa8fb Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Tue, 25 Nov 2025 12:25:48 +0100 Subject: [PATCH 55/63] Remove error message --- src/nmodl/config/config.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/nmodl/config/config.h b/src/nmodl/config/config.h index 016df40121..145fb254fb 100644 --- a/src/nmodl/config/config.h +++ b/src/nmodl/config/config.h @@ -83,12 +83,6 @@ struct NrnUnitsLib { return path; } } - std::ostringstream err_msg; - err_msg << "Could not find nrnunits.lib in any of:\n"; - for (const auto& path: NRNUNITSLIB_PATH) { - err_msg << path << "\n"; - } - err_msg << "Falling back to embedded nrnunits.lib\n"; return ""; } }; From 305fb2d540c4179c9016bb0f5cd5e02178385a35 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 26 Nov 2025 14:56:28 +0100 Subject: [PATCH 56/63] Add `nrnivmodl.cmake` --- CMakeLists.txt | 6 ++ bin/CMakeLists.txt | 31 ++++++++++- bin/nrnivmodl-cmake.in | 74 +++++++++++++++++++++++++ cmake/nrnivmodl.cmake | 43 ++++++++++++++ share/lib/python/scripts/CMakeLists.txt | 9 ++- 5 files changed, 160 insertions(+), 3 deletions(-) create mode 100755 bin/nrnivmodl-cmake.in create mode 100644 cmake/nrnivmodl.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d7430884..1ec0d8907b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1152,6 +1152,12 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_nrn.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_reg_corenrn.cpp.in DESTINATION "${NRN_INSTALL_DATA_PREFIX}share/nrn") +# configuration and installation of nrnivmodl +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nrnivmodl.cmake + ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/nrnivmodl/CMakeLists.txt @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/neuron/nrnivmodl/CMakeLists.txt + DESTINATION "${NRN_INSTALL_DATA_PREFIX}lib/cmake/neuron/nrnivmodl") + # ============================================================================= # Copy bash executable for windows # ============================================================================= diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 09a3e19d1a..ed7b721ecf 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -47,7 +47,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nrnpyenv.sh.in ${PROJECT_BINARY_DIR}/ # Make sure nrnivmodl and neurondemo are executable in the build folder, so we can execute it to # prepare test files. This can be done more elegantly in newer CMake versions; v3.19+ have # file(CHMOD ...) and v3.20+ support setting permissions directly in configure_file(...). -set(NRN_CONFIG_EXE_FILES "nrnivmodl" "neurondemo") +set(NRNIVMODL_NEURON ON) +set(NRN_CONFIG_EXE_FILES "nrnivmodl" "neurondemo" "nrnivmodl-cmake") foreach(NRN_CONFIG_EXE_FILE ${NRN_CONFIG_EXE_FILES}) configure_file("${NRN_CONFIG_EXE_FILE}.in" "tmp/${NRN_CONFIG_EXE_FILE}" @ONLY) file( @@ -62,13 +63,39 @@ foreach(NRN_CONFIG_EXE_FILE ${NRN_CONFIG_EXE_FILES}) WORLD_READ WORLD_EXECUTE) endforeach() +unset(NRNIVMODL_NEURON) +if(NRN_ENABLE_CORENEURON) + # nrnivmodl-all-cmake builds mechanisms for both NEURON and coreNEURON + set(NRNIVMODL_NEURON ON) + set(NRNIVMODL_CORENEURON ON) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nrnivmodl-cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/tmp/nrnivmodl-all-cmake" @ONLY) + file( + COPY "${CMAKE_CURRENT_BINARY_DIR}/tmp/nrnivmodl-all-cmake" + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" + FILE_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE) + unset(NRNIVMODL_NEURON) + unset(NRNIVMODL_CORENEURON) +endif() file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/bin/tmp") # ============================================================================= # Install targets # ============================================================================= install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/nrngui ${PROJECT_BINARY_DIR}/bin/neurondemo - ${PROJECT_BINARY_DIR}/bin/nrnivmodl DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) + ${PROJECT_BINARY_DIR}/bin/nrnivmodl ${PROJECT_BINARY_DIR}/bin/nrnivmodl-cmake + DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) +if(NRN_ENABLE_CORENEURON) + install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/nrnivmodl-all-cmake + DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) +endif() install(FILES ${PROJECT_BINARY_DIR}/bin/nrnmech_makefile DESTINATION ${NRN_INSTALL_DATA_PREFIX}bin) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/sortspike ${CMAKE_CURRENT_SOURCE_DIR}/mkthreadsafe diff --git a/bin/nrnivmodl-cmake.in b/bin/nrnivmodl-cmake.in new file mode 100755 index 0000000000..e814499fb4 --- /dev/null +++ b/bin/nrnivmodl-cmake.in @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# ============================================================================= +# Simple wrapper for CMake that builds mechanisms from mod files +# ============================================================================= + +set -eu + +# Where the output files will be placed +bindir="$(uname -m)" + +# The name of the current program +program_name="$(basename "${0}")" + +# Where the `*.cmake` files are located +NRN_CMAKE_PREFIX_PATH_DEFAULT="$(readlink -f "$(dirname "${0}")/../lib/cmake/")" +if [ -n "${CMAKE_PREFIX_PATH:-}" ]; then + CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}:${NRN_CMAKE_PREFIX_PATH_DEFAULT}" +else + CMAKE_PREFIX_PATH="${NRN_CMAKE_PREFIX_PATH_DEFAULT}" +fi +export CMAKE_PREFIX_PATH + +# On MacOS we need to set the deployment target to be equal to the one of NEURON +if command -v xcrun >& /dev/null; then + @NRN_OSX_BUILD_TRUE@export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" + @NRN_OSX_BUILD_TRUE@export MACOSX_DEPLOYMENT_TARGET="@CMAKE_OSX_DEPLOYMENT_TARGET@" + if [ -z "${MACOSX_DEPLOYMENT_TARGET}" ]; then + unset MACOSX_DEPLOYMENT_TARGET + fi +fi + +# We use the CMakeLists.txt from the NEURON installation directory to not have +# to deal with any pre-existing CMakeLists.txt in the current directory +srcdir="${NRN_CMAKE_PREFIX_PATH_DEFAULT}/neuron/nrnivmodl/" + +# In case of no files, default to using the files in the current dir +if [ $# -lt 1 ]; then + set -- ./*.mod +# In case of a single input, check if it's a directory; if it is, collect all mod files in it +elif [ $# -eq 1 ] && [ -d "${1}" ]; then + printf "[%s] Collecting mod files under %s\n" "${program_name}" "$(readlink -f "${1}")" + set -- "${1}"/*.mod +fi + +# After collecting the mod files, check each mod file actually exists +for mod_file in "$@"; do + if [ ! -e "${mod_file}" ]; then + printf "[%s] ERROR: Mod file %s does not exist!\n" "${program_name}" "${mod_file}" >&2 + exit 4 + fi +done + +# Convert all mod file paths to absolute paths because the source dir is in the NEURON install +args=() +for f in "$@"; do + resolved=$(readlink -f "$f") || exit 1 + args+=("$resolved") +done +set -- "${args[@]}" + +# TODO what if the mod filenames contain semicolons? +modfiles=$(IFS=";"; echo "$*") + +# Configure the mod files +cmake \ + -S "${srcdir}" \ + -B "${bindir}" \ + -DNRNIVMODL_MOD_FILES="${modfiles}" \ + -DNRNIVMODL_NEURON=@NRNIVMODL_NEURON@ \ + -DNRNIVMODL_CORENEURON=@NRNIVMODL_CORENEURON@ + +# Actually build them +cmake --build "${bindir}" diff --git a/cmake/nrnivmodl.cmake b/cmake/nrnivmodl.cmake new file mode 100644 index 0000000000..bb9fb8a405 --- /dev/null +++ b/cmake/nrnivmodl.cmake @@ -0,0 +1,43 @@ +# ============================================================== +# CMake wrapper for generating mechanisms for (core)NEURON +# ============================================================== + +cmake_minimum_required(VERSION @CMAKE_MINIMUM_REQUIRED_VERSION@) +project(nrnivmodl) + +find_package(neuron REQUIRED) + +set(NRNIVMODL_MOD_FILES + "" + CACHE STRING "List of mod files to convert to mechanisms") +set(NRNIVMODL_NEURON + ON + CACHE BOOL "Whether to generate mechanisms for NEURON") +set(NRNIVMODL_CORENEURON + OFF + CACHE BOOL "Whether to generate mechanisms for coreNEURON") +set(NRNIVMODL_SPECIAL + ON + CACHE BOOL "Whether to generate the `special` executable") + +set(NRNIVMODL_ARGS) +if(NRNIVMODL_NEURON) + list(APPEND NRNIVMODL_ARGS "NEURON") +endif() +if(NRNIVMODL_CORENEURON) + list(APPEND NRNIVMODL_ARGS "CORENEURON") +endif() +if(NRNIVMODL_SPECIAL) + list(APPEND NRNIVMODL_ARGS "SPECIAL") +endif() + +message(STATUS "Received mod files: ${NRNIVMODL_MOD_FILES}") + +create_nrnmech( + ${NRNIVMODL_ARGS} + MOD_FILES + ${NRNIVMODL_MOD_FILES} + LIBRARY_OUTPUT_DIR + "${CMAKE_CURRENT_BINARY_DIR}" + EXECUTABLE_OUTPUT_DIR + "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/share/lib/python/scripts/CMakeLists.txt b/share/lib/python/scripts/CMakeLists.txt index bbc3327148..11a6998984 100644 --- a/share/lib/python/scripts/CMakeLists.txt +++ b/share/lib/python/scripts/CMakeLists.txt @@ -11,7 +11,8 @@ if(SKBUILD) nrnivmodl nrnivmodl-core nrnpyenv.sh - sortspike) + sortspike + nrnivmodl-cmake) foreach(script IN LISTS scripts) install( @@ -19,6 +20,12 @@ if(SKBUILD) DESTINATION "${SKBUILD_SCRIPTS_DIR}" RENAME "${script}") endforeach() + if(NRN_ENABLE_CORENEURON) + install( + PROGRAMS binwrapper.py + DESTINATION "${SKBUILD_SCRIPTS_DIR}" + RENAME "nrnivmodl-all-cmake") + endif() # in order for mechanism building via CMake to work with a Python wheel, we need `binwrapper.py` install(PROGRAMS binwrapper.py DESTINATION "${NRN_INSTALL_DATA_PREFIX}share/nrn") endif() From 7fcc855556ed044012a64d7ae586c557850946f4 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 26 Nov 2025 16:31:10 +0100 Subject: [PATCH 57/63] Fix issue when using wheels --- cmake/neuronConfig.cmake.in | 2 - cmake/neuronMechMaker.cmake | 16 +--- packaging/python/test_wheels.sh | 136 +++++++++++++++++--------------- 3 files changed, 77 insertions(+), 77 deletions(-) diff --git a/cmake/neuronConfig.cmake.in b/cmake/neuronConfig.cmake.in index 60d1ac3dec..b791720bd3 100644 --- a/cmake/neuronConfig.cmake.in +++ b/cmake/neuronConfig.cmake.in @@ -12,8 +12,6 @@ set(NRN_ENABLE_CORENEURON @NRN_ENABLE_CORENEURON@) set(_NEURON_MAIN "${_prefix}/share/nrn/nrnmain.cpp") set(_NEURON_MAIN_INCLUDE_DIR "${_prefix}/include/nrncvode" "${_prefix}/include") set(_NEURON_MECH_REG "${_prefix}/share/nrn/mod_reg_nrn.cpp.in") -set(_NEURON_WHEEL @SKBUILD@) -set(_NEURON_PYTHON_BINWRAPPER "${_prefix}/share/nrn/binwrapper.py") set(_CORENEURON_BASE_MOD "${_prefix}/share/modfile") set(_CORENEURON_MAIN "${_prefix}/share/coreneuron/coreneuron.cpp") diff --git a/cmake/neuronMechMaker.cmake b/cmake/neuronMechMaker.cmake index fc0e6aaeb8..ece62bbf43 100644 --- a/cmake/neuronMechMaker.cmake +++ b/cmake/neuronMechMaker.cmake @@ -436,19 +436,9 @@ function(create_nrnmech) target_include_directories(${TARGET_EXECUTABLE_NAME} BEFORE PUBLIC ${_NEURON_MAIN_INCLUDE_DIR}) target_link_libraries(${TARGET_EXECUTABLE_NAME} PUBLIC ${TARGET_LIBRARY_NAME}) - if(NOT _NEURON_WHEEL) - set_target_properties( - ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special" RUNTIME_OUTPUT_DIRECTORY - "${EXECUTABLE_OUTPUT_DIR}") - else() - # we use a Python wrapper for `special` so the env is set properly when launched - configure_file(${_NEURON_PYTHON_BINWRAPPER} "${ARTIFACTS_OUTPUT_DIR}/special" COPYONLY) - add_custom_target(py${TARGET_EXECUTABLE_NAME} ALL DEPENDS "${ARTIFACTS_OUTPUT_DIR}/special") - - set_target_properties( - ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special.nrn" RUNTIME_OUTPUT_DIRECTORY - "${EXECUTABLE_OUTPUT_DIR}") - endif() + set_target_properties( + ${TARGET_EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME "special" RUNTIME_OUTPUT_DIRECTORY + "${EXECUTABLE_OUTPUT_DIR}") endif() endif() diff --git a/packaging/python/test_wheels.sh b/packaging/python/test_wheels.sh index a48470c4c3..e3b80b30c3 100755 --- a/packaging/python/test_wheels.sh +++ b/packaging/python/test_wheels.sh @@ -57,42 +57,48 @@ run_mpi_test () { rm -rf *.dat fi - # build new special - rm -rf $ARCH_DIR - nrnivmodl tmp_mod - - # run python test via nrniv and special (except on azure pipelines) - if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then - $mpi_launcher -n 2 ./$ARCH_DIR/special -python src/parallel/test0.py -mpi --expected-hosts 2 - $mpi_launcher -n 2 nrniv -python src/parallel/test0.py -mpi --expected-hosts 2 - fi - - # coreneuron execution via neuron - if [[ "$has_coreneuron" == "true" ]]; then - rm -rf $ARCH_DIR - TEMP_DIR="${TMPDIR:-/tmp}/test/coreneuron/mod files/" - if [ ! -d "${TEMP_DIR}" ]; then - mkdir -p "${TEMP_DIR}" - fi - cp "test/coreneuron/mod files/"* "${TEMP_DIR}/" - # also copy one MOD file containing sparse solver - cp share/examples/nrniv/nmodl/capmp.mod "${TEMP_DIR}" - nrnivmodl -coreneuron "${TEMP_DIR}" + compilers=("nrnivmodl" "nrnivmodl-cmake") + core_compilers=("nrnivmodl -coreneuron" "nrnivmodl-all-cmake") + for index in "${!compilers[@]}"; do + nrnivmodl="${compilers[$index]}" + nrnivmodl_core="${core_compilers[$index]}" + # build new special + rm -rf $ARCH_DIR + ${nrnivmodl} tmp_mod - $mpi_launcher -n 1 $python_exe test/coreneuron/test_direct.py + # run python test via nrniv and special (except on azure pipelines) + if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then + $mpi_launcher -n 2 ./$ARCH_DIR/special -python src/parallel/test0.py -mpi --expected-hosts 2 + $mpi_launcher -n 2 nrniv -python src/parallel/test0.py -mpi --expected-hosts 2 + fi - # using -python doesn't work on Azure CI - if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then - $mpi_launcher -n 2 nrniv -python -mpi test/coreneuron/test_direct.py - NVCOMPILER_ACC_TIME=1 CORENRN_ENABLE_GPU=0 $mpi_launcher -n 2 ./$ARCH_DIR/special -python -mpi test/coreneuron/test_direct.py - fi - fi + # coreneuron execution via neuron + if [[ "$has_coreneuron" == "true" ]]; then + rm -rf $ARCH_DIR + TEMP_DIR="${TMPDIR:-/tmp}/test/coreneuron/mod files/" + if [ ! -d "${TEMP_DIR}" ]; then + mkdir -p "${TEMP_DIR}" + fi + cp "test/coreneuron/mod files/"* "${TEMP_DIR}/" + # also copy one MOD file containing sparse solver + cp share/examples/nrniv/nmodl/capmp.mod "${TEMP_DIR}" + ${nrnivmodl_core} "${TEMP_DIR}" + + $mpi_launcher -n 1 $python_exe test/coreneuron/test_direct.py + + # using -python doesn't work on Azure CI + if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then + $mpi_launcher -n 2 nrniv -python -mpi test/coreneuron/test_direct.py + NVCOMPILER_ACC_TIME=1 CORENRN_ENABLE_GPU=0 $mpi_launcher -n 2 ./$ARCH_DIR/special -python -mpi test/coreneuron/test_direct.py + fi + fi - if [ -n "$mpi_module" ]; then - echo "Unloading module $mpi_module" - module unload $mpi_module - fi - echo -e "----------------------\n\n" + if [ -n "$mpi_module" ]; then + echo "Unloading module $mpi_module" + module unload $mpi_module + fi + echo -e "----------------------\n\n" + done } @@ -113,47 +119,53 @@ run_serial_test () { rm -rf *.dat fi - # Test 4: execute nrnivmodl - rm -rf $ARCH_DIR - nrnivmodl tmp_mod + # Test 4: execute nrnivmodl and friends + compilers=("nrnivmodl" "nrnivmodl-cmake") + for compiler in "${compilers[@]}"; do + rm -rf $ARCH_DIR + ${compiler} tmp_mod - # Test 5: execute special hoc interpreter - ./$ARCH_DIR/special -c "print \"hello\"" + # Test 5: execute special hoc interpreter + ./$ARCH_DIR/special -c "print \"hello\"" - # Test 6: run basic tests via python while loading shared library - $python_exe -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" + # Test 6: run basic tests via python while loading shared library + $python_exe -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" - # Test 7: run basic test to use compiled mod file - $python_exe -c "import neuron; from neuron import h; s = h.Section(); s.insert('cacum'); quit()" + # Test 7: run basic test to use compiled mod file + $python_exe -c "import neuron; from neuron import h; s = h.Section(); s.insert('cacum'); quit()" - # Test 8: run basic tests via special : azure pipelines get stuck with their - # own python from hosted cache (most likely security settings). - if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then - ./$ARCH_DIR/special -python -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" - nrniv -python -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" - else - $python_exe -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" - fi + # Test 8: run basic tests via special : azure pipelines get stuck with their + # own python from hosted cache (most likely security settings). + if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then + ./$ARCH_DIR/special -python -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" + nrniv -python -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" + else + $python_exe -c "import neuron; neuron.test(); neuron.test_rxd(); quit()" + fi + done # Test 9: coreneuron execution via neuron if [[ "$has_coreneuron" == "true" ]]; then - rm -rf $ARCH_DIR + compilers=("nrnivmodl -coreneuron" "nrnivmodl-all-cmake") + for compiler in "${compilers[@]}"; do + rm -rf $ARCH_DIR - # first test vanialla coreneuron support, without nrnivmodl - $python_exe test/coreneuron/test_psolve.py + # first test vanialla coreneuron support, without nrnivmodl + $python_exe test/coreneuron/test_psolve.py - nrnivmodl -coreneuron "test/coreneuron/mod files/" + ${compiler} "test/coreneuron/mod files/" - # coreneuron+gpu can be used via python but special only - $python_exe test/coreneuron/test_direct.py + # coreneuron+gpu can be used via python but special only + $python_exe test/coreneuron/test_direct.py - # using -python doesn't work on Azure CI - if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then - ./$ARCH_DIR/special -python test/coreneuron/test_direct.py - nrniv -python test/coreneuron/test_direct.py - fi + # using -python doesn't work on Azure CI + if [[ "$SKIP_EMBEDED_PYTHON_TEST" != "true" ]]; then + ./$ARCH_DIR/special -python test/coreneuron/test_direct.py + nrniv -python test/coreneuron/test_direct.py + fi - rm -rf $ARCH_DIR + rm -rf $ARCH_DIR + done fi From 922bcf0066d48acc47c03f63349fc8f6ad683d8b Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 26 Nov 2025 16:38:00 +0100 Subject: [PATCH 58/63] Update CI --- .github/workflows/wheels-template.yml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wheels-template.yml b/.github/workflows/wheels-template.yml index 7549e8977a..65db110534 100644 --- a/.github/workflows/wheels-template.yml +++ b/.github/workflows/wheels-template.yml @@ -73,7 +73,7 @@ jobs: run: | brew install --cask xquartz brew uninstall cmake || echo "CMake was not pre-installed" - brew install flex bison cmake mpich + brew install flex bison cmake mpich ninja brew unlink mpich && brew install openmpi # Install newer version of Bash on MacOS brew install bash @@ -127,7 +127,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt update - sudo apt install -y mpich openmpi-bin libopenmpi-dev libmpich-dev + sudo apt install -y mpich openmpi-bin libopenmpi-dev libmpich-dev ninja-build - name: "Apply workaround for MPICH on Ubuntu 24.04" if: inputs.platform == 'ubuntu-24.04' @@ -141,6 +141,22 @@ jobs: wget 'https://launchpad.net/ubuntu/+source/mpich/4.2.0-5.1/+build/28285882/+files/libmpich12_4.2.0-5.1_amd64.deb' sudo dpkg --install mpich_4.2.0-5.1_amd64.deb libmpich12_4.2.0-5.1_amd64.deb + - name: Set env vars for testing (Linux) + if: startsWith(inputs.platform, "ubuntu") + run: | + echo CMAKE_BUILD_PARALLEL_LEVEL=4 >> $GITHUB_ENV + echo CMAKE_GENERATOR=Ninja >> $GITHUB_ENV + + - name: Set env vars for testing (MacOS) + if: startsWith(inputs.platform, "macOS") + run: | + if [[ "${{inputs.platform}}" == "macOS-15-intel" ]]; then + echo CMAKE_BUILD_PARALLEL_LEVEL=4 >> $GITHUB_ENV + else + echo CMAKE_BUILD_PARALLEL_LEVEL=3 >> $GITHUB_ENV + fi + echo CMAKE_GENERATOR=Ninja >> $GITHUB_ENV + - name: Test wheel with ${{ inputs.python_version }} run: | minor_version="$(python${{ inputs.python_version }} -c 'import sys;print(sys.version_info.minor)')" From 4040182024217240ba487bdb77cf18b26606cdc9 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 26 Nov 2025 16:40:31 +0100 Subject: [PATCH 59/63] Fix Azure CI --- ci/azure-wheel-test-upload.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/azure-wheel-test-upload.yml b/ci/azure-wheel-test-upload.yml index c62902a706..24f9e6b03f 100644 --- a/ci/azure-wheel-test-upload.yml +++ b/ci/azure-wheel-test-upload.yml @@ -8,8 +8,9 @@ steps: - script: | brew install python export SKIP_EMBEDED_PYTHON_TEST=true + export CMAKE_BUILD_PARALLEL_LEVEL=4 packaging/python/test_wheels.sh /usr/local/bin/python3 wheelhouse/*.whl - condition: and(eq(variables['agent.os'], 'Darwin'), eq(variables['python.version'], '3.8')) + condition: and(eq(variables['agent.os'], 'Darwin'), eq(variables['python.version'], '3.9')) displayName: 'Test with brew Python' - task: UsePythonVersion@0 @@ -18,6 +19,7 @@ steps: - script: | export SKIP_EMBEDED_PYTHON_TEST=true + export CMAKE_BUILD_PARALLEL_LEVEL=4 packaging/python/test_wheels.sh $(which python) $(ls -t wheelhouse/*.whl) displayName: 'Test with System Python' From 50ca338e394f5804f09d7fe1d87bcf8b675b24bd Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 26 Nov 2025 17:03:41 +0100 Subject: [PATCH 60/63] Make SonarThing happy --- .github/workflows/wheels-template.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wheels-template.yml b/.github/workflows/wheels-template.yml index 65db110534..42d9d299c0 100644 --- a/.github/workflows/wheels-template.yml +++ b/.github/workflows/wheels-template.yml @@ -148,9 +148,9 @@ jobs: echo CMAKE_GENERATOR=Ninja >> $GITHUB_ENV - name: Set env vars for testing (MacOS) - if: startsWith(inputs.platform, "macOS") + if: startsWith(runner.os, "macOS") run: | - if [[ "${{inputs.platform}}" == "macOS-15-intel" ]]; then + if [[ "${{runner.os}}" == "macOS-15-intel" ]]; then echo CMAKE_BUILD_PARALLEL_LEVEL=4 >> $GITHUB_ENV else echo CMAKE_BUILD_PARALLEL_LEVEL=3 >> $GITHUB_ENV From 5d593508d1849a6b8cd16e7dfea10db7687f3053 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 27 Nov 2025 00:32:59 +0100 Subject: [PATCH 61/63] Put this back --- ci/azure-wheel-test-upload.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ci/azure-wheel-test-upload.yml b/ci/azure-wheel-test-upload.yml index 24f9e6b03f..b6f5a61f70 100644 --- a/ci/azure-wheel-test-upload.yml +++ b/ci/azure-wheel-test-upload.yml @@ -8,9 +8,8 @@ steps: - script: | brew install python export SKIP_EMBEDED_PYTHON_TEST=true - export CMAKE_BUILD_PARALLEL_LEVEL=4 packaging/python/test_wheels.sh /usr/local/bin/python3 wheelhouse/*.whl - condition: and(eq(variables['agent.os'], 'Darwin'), eq(variables['python.version'], '3.9')) + condition: and(eq(variables['agent.os'], 'Darwin'), eq(variables['python.version'], '3.8')) displayName: 'Test with brew Python' - task: UsePythonVersion@0 From 99e8d673dcea0a54b6d1d3e2f4106b77680feed8 Mon Sep 17 00:00:00 2001 From: Michael Hines Date: Thu, 22 Jan 2026 16:23:48 -0500 Subject: [PATCH 62/63] CodeCoverage ci error: keyword signature for target_link_libraries. --- src/nrniv/CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index 26bcb44db5..b475c78408 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -426,15 +426,15 @@ if(${NRN_ENABLE_DIGEST}) APPEND PROPERTY INCLUDE_DIRECTORIES /opt/homebrew/Cellar/openssl@3/3.1.0/include) find_library(LIB_CRYPTO crypto PATHS /opt/homebrew/Cellar/openssl@3/3.1.0/lib REQUIRED) - target_link_libraries(nrniv_lib ${LIB_CRYPTO}) + target_link_libraries(nrniv_lib PRIVATE ${LIB_CRYPTO}) else() - target_link_libraries(nrniv_lib crypto) + target_link_libraries(nrniv_lib PRIVATE crypto) endif() endif() if(${NRN_ENABLE_ARCH_INDEP_EXP_POW}) find_library(LIB_MPFR mpfr REQUIRED) - target_link_libraries(nrniv_lib ${LIB_MPFR}) + target_link_libraries(nrniv_lib PRIVATE ${LIB_MPFR}) endif() if(NRN_WINDOWS_BUILD) @@ -458,7 +458,7 @@ if(NRN_ENABLE_MUSIC AND NOT NRN_ENABLE_MPI_DYNAMIC) endif() if(NRN_ENABLE_PROFILING) - target_link_libraries(nrniv_lib PUBLIC ${likwid_LIBRARIES} ${CALIPER_LIB} ${LIKWID_LIB}) + target_link_libraries(nrniv_lib PRIVATE ${likwid_LIBRARIES} ${CALIPER_LIB} ${LIKWID_LIB}) endif() set_target_properties(nrniv_lib PROPERTIES EXPORT_NAME nrniv OUTPUT_NAME nrniv) @@ -468,7 +468,7 @@ target_compile_features(nrniv_lib PUBLIC cxx_std_17) # Link with backward-cpp if enabled # ============================================================================= if(NRN_USE_BACKWARD) - target_link_libraries(nrniv_lib Backward::Backward) + target_link_libraries(nrniv_lib PRIVATE Backward::Backward) target_include_directories(nrniv_lib PRIVATE ${PROJECT_SOURCE_DIR}/external/backward) endif() @@ -484,13 +484,13 @@ if(NRN_ENABLE_MPI) list(GET NRN_MPI_LIBNAME_LIST ${val} libname) add_library(${libname}_lib SHARED ${NRN_NRNMPI_SRC_FILES}) - target_link_libraries(${libname}_lib fmt::fmt) + target_link_libraries(${libname}_lib PRIVATE fmt::fmt) target_include_directories(${libname}_lib BEFORE PUBLIC ${include}) # Note that we do not link here to libmpi. That is dlopen first. if(MINGW) # type msmpi only add_dependencies(${libname}_lib nrniv_lib) - target_link_libraries(${libname}_lib ${MPI_C_LIBRARIES}) - target_link_libraries(${libname}_lib nrniv_lib) + target_link_libraries(${libname}_lib PUBLIC ${MPI_C_LIBRARIES}) + target_link_libraries(${libname}_lib PUBLIC nrniv_lib) endif() set_property(TARGET ${libname}_lib PROPERTY OUTPUT_NAME ${libname}) install(TARGETS ${libname}_lib DESTINATION ${NRN_INSTALL_SHARE_LIB_DIR}) @@ -504,7 +504,7 @@ if(NRN_ENABLE_MPI) add_library(${libnrnmusic}_lib SHARED ${NRN_MUSIC_SRC_FILES}) target_include_directories(${libnrnmusic}_lib BEFORE PUBLIC ${include}) add_dependencies(${libnrnmusic}_lib nrniv_lib ${libname}_lib) - target_link_libraries(${libnrnmusic}_lib nrniv_lib ${libname}_lib) + target_link_libraries(${libnrnmusic}_lib PUBLIC nrniv_lib ${libname}_lib) set_property(TARGET ${libnrnmusic}_lib PROPERTY OUTPUT_NAME ${libnrnmusic}) install(TARGETS ${libnrnmusic}_lib DESTINATION ${NRN_INSTALL_SHARE_LIB_DIR}) endif() @@ -560,9 +560,9 @@ cpp_cc_configure_sanitizers(TARGET nrniv) if(NOT "${NRN_LINK_FLAGS_FOR_ENTRY_POINTS}" STREQUAL "") target_link_options(nrniv PUBLIC ${NRN_LINK_FLAGS_FOR_ENTRY_POINTS}) endif() -target_link_libraries(nrniv nrniv_lib ${INTERNAL_READLINE} ${CMAKE_DL_LIBS}) +target_link_libraries(nrniv nrniv_lib PRIVATE ${INTERNAL_READLINE} ${CMAKE_DL_LIBS}) if(NRN_ENABLE_THREADS) - target_link_libraries(nrniv Threads::Threads) + target_link_libraries(nrniv PRIVATE Threads::Threads) endif() if(NOT MINGW) target_link_libraries(nrniv_lib PUBLIC ${CMAKE_DL_LIBS}) @@ -570,7 +570,7 @@ endif() # TODO: unset in top level CMake is not working if(NOT NRN_MACOS_BUILD AND READLINE_FOUND) - target_link_libraries(nrniv ${Readline_LIBRARY}) + target_link_libraries(nrniv PRIVATE ${Readline_LIBRARY}) endif() # ============================================================================= From 94081a3a6bc16ec6456ca7535d0ac41b6e3e3499 Mon Sep 17 00:00:00 2001 From: Michael Hines Date: Thu, 22 Jan 2026 16:41:31 -0500 Subject: [PATCH 63/63] Previous commit did not have PRIVATE as second arg --- src/nrniv/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index b475c78408..dfc77e9ea3 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -560,7 +560,7 @@ cpp_cc_configure_sanitizers(TARGET nrniv) if(NOT "${NRN_LINK_FLAGS_FOR_ENTRY_POINTS}" STREQUAL "") target_link_options(nrniv PUBLIC ${NRN_LINK_FLAGS_FOR_ENTRY_POINTS}) endif() -target_link_libraries(nrniv nrniv_lib PRIVATE ${INTERNAL_READLINE} ${CMAKE_DL_LIBS}) +target_link_libraries(nrniv PRIVATE nrniv_lib ${INTERNAL_READLINE} ${CMAKE_DL_LIBS}) if(NRN_ENABLE_THREADS) target_link_libraries(nrniv PRIVATE Threads::Threads) endif()