diff --git a/cmake/ConfigFileSetting.cmake b/cmake/ConfigFileSetting.cmake index 54939df7e1..a3832b8adb 100644 --- a/cmake/ConfigFileSetting.cmake +++ b/cmake/ConfigFileSetting.cmake @@ -164,8 +164,17 @@ configure_file("${PROJECT_SOURCE_DIR}/src/sundials/sundials_config.h.in" "${PROJECT_BINARY_DIR}/src/sundials/sundials_config.h" @ONLY) configure_file("${PROJECT_SOURCE_DIR}/share/lib/nrn.defaults.in" "${PROJECT_BINARY_DIR}/share/nrn/lib/nrn.defaults" @ONLY) -file(COPY ${PROJECT_SOURCE_DIR}/share/lib/nrnunits.lib - DESTINATION ${PROJECT_BINARY_DIR}/share/nrn/lib) +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) + +set(nrnunits_start "R\"qwerty(") +set(nrnunits_stop ")qwerty\"") +# Embed 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}) diff --git a/share/lib/nrnunits.lib b/share/lib/nrnunits.lib.in similarity index 99% rename from share/lib/nrnunits.lib rename to share/lib/nrnunits.lib.in index b0839ca173..aa57c4b4a4 100755 --- a/share/lib/nrnunits.lib +++ b/share/lib/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 @@ -617,4 +617,4 @@ metricyarncount meter/gram jewlerspoint 2 milligram - +@nrnunits_stop@ diff --git a/src/modlunit/units.cpp b/src/modlunit/units.cpp index d4433f1da1..69a3e87565 100644 --- a/src/modlunit/units.cpp +++ b/src/modlunit/units.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include /* /local/src/master/nrn/src/modlunit/units.c,v 1.5 1997/11/24 16:19:13 hines Exp */ /* Mostly from Berkeley */ @@ -100,6 +102,23 @@ static int dumpflg; static const char* pc; +static constexpr std::string_view embedded_nrnunits = +#include "embedded_nrnunits.lib" + ; + +// cross-platform workaround for: +// https://github.com/neuronsimulator/nrn/issues/3470 +// the API requires a FILE handle instead of a std::string or similar +// so we write a temporary file +static FILE* open_embedded_nrnunits_as_file() { + auto tmp_path = std::string(std::tmpnam(nullptr)); + auto out = std::ofstream(tmp_path, std::ios::out); + out.write(embedded_nrnunits.data(), embedded_nrnunits.size()); + out.close(); + + return std::fopen(tmp_path.c_str(), "r"); +} + static int Getc(FILE* inp) { if (inp != stdin) { return getc(inp); @@ -565,6 +584,11 @@ void unit_init() { } #endif + // try to load the embedded one as a last resort + if (!inpfile) { + inpfile = open_embedded_nrnunits_as_file(); + } + if (!inpfile) { fprintf(stderr, "Set a MODLUNIT environment variable path to the units table file\n"); fprintf(stderr, "Cant open units table in either of:\n%s\n", buf); diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index a6887ce58a..1a30e1d2de 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -48,6 +48,7 @@ add_dependencies(generated_source_files modlunit_generated_files) add_executable(modlunit ${NRN_MODLUNIT_SRC_FILES} "${NRN_MODLUNIT_GEN}/lex.cpp" "${NRN_MODLUNIT_GEN}/parse1.cpp") add_dependencies(modlunit modlunit_generated_files) +target_include_directories(modlunit PRIVATE "${PROJECT_BINARY_DIR}/share/nrn/lib") target_compile_definitions(modlunit PRIVATE NRNUNIT=1) cpp_cc_configure_sanitizers(TARGET modlunit) @@ -96,6 +97,7 @@ add_dependencies(generated_source_files nocmodl_generated_files) add_executable(nocmodl ${NRN_NOCMODL_SRC_FILES} "${NRN_NOCMODL_GEN}/lex.cpp" "${NRN_NOCMODL_GEN}/parse1.cpp" "${NRN_NOCMODL_GEN}/diffeq.cpp") +target_include_directories(nocmodl PRIVATE "${PROJECT_BINARY_DIR}/share/nrn/lib") cpp_cc_configure_sanitizers(TARGET nocmodl) add_dependencies(nocmodl nocmodl_generated_files) target_compile_definitions(nocmodl PRIVATE COMPILE_DEFINITIONS NMODL=1 CVODE=1) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 641ba0cd63..de66abe393 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -802,8 +802,14 @@ add_modlunit_test("${PROJECT_SOURCE_DIR}/src/nrnoc/hh.mod") add_modlunit_test("${PROJECT_SOURCE_DIR}/src/nrnoc/stim.mod") add_modlunit_test("${PROJECT_SOURCE_DIR}/src/nrnoc/pattern.mod") add_modlunit_test("${PROJECT_SOURCE_DIR}/test/hoctests/rand.mod") +# Test nocmodl with units +add_test( + NAME nocmodl::no_env + COMMAND $ -o "${CMAKE_CURRENT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/test/coreneuron/mod files/axial.mod" + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}") set_property(TEST modlunit_pattern PROPERTY WILL_FAIL ON) - +cpp_cc_configure_sanitizers(TEST nocmodl::no_env) set_tests_properties(${TESTS} PROPERTIES ENVIRONMENT "${NRN_RUN_FROM_BUILD_DIR_ENV}") cpp_cc_configure_sanitizers(TEST ${TESTS}) # If profiling is enabled, run ringtest with profiler