Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the same depends solver for nrn and crnrn #2864

Closed
wants to merge 14 commits into from
58 changes: 1 addition & 57 deletions cmake/CMakeListsNrnMech.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,67 +16,11 @@ string(JOIN " " NRN_NOCMODL_SANITIZER_ENVIRONMENT_STRING ${NRN_NOCMODL_SANITIZER

# extract link defs to the whole project
get_target_property(NRN_LINK_LIBS nrniv_lib LINK_LIBRARIES)
if(NOT NRN_LINK_LIBS)
set(NRN_LINK_LIBS "")
endif()

# Interview might have linked to libnrniv but we don't want to link to special
list(REMOVE_ITEM NRN_LINK_LIBS "interviews")

function(get_link_libraries libs)
# CMake does some magic to transform sys libs to -l<libname>. We replicate it
foreach(link_lib ${libs})
# skip static readline library as it will be linked to nrniv (e.g. with wheel) also stub
# libraries from OSX can be skipped
if("${link_lib}" MATCHES "(libreadline.a|/*.tbd)")
continue()
endif()

get_filename_component(dir_path ${link_lib} DIRECTORY)
if(TARGET ${link_lib})
get_property(
sublink_flag
TARGET ${link_lib}
PROPERTY INTERFACE_LINK_LIBRARIES)
set(description
"Extracting link flags from target '${link_lib}', beware that this can be fragile.")
# Not use it yet because it can be generator expressions get_property(compile_flag TARGET
# ${link_lib} PROPERTY INTERFACE_COMPILE_OPTIONS) string(APPEND NRN_COMPILE_DEFS
# ${compile_flag})
foreach(sublink_lib ${sublink_flag})
if(TARGET ${sublink_lib})
message(NOTICE "For '${link_lib}' going to see TARGET '${sublink_lib}' recursively.")
get_link_libraries(${sublink_lib})
else()
set(link_flag "${link_flag} ${sublink_flag}")
endif()
endforeach()
elseif(NOT dir_path)
set(link_flag "-l${link_lib}")
set(description
"Generating link flags from name '${link_lib}', beware that this can be fragile.")
# avoid library paths from special directory /nrnwheel which used to build wheels under docker
# container
elseif("${dir_path}" MATCHES "^/nrnwheel")
continue()
elseif("${dir_path}" MATCHES "^(/lib|/lib64|/usr/lib|/usr/lib64)$")
# NAME_WLE not avaialble with CMake version < 3.14
get_filename_component(libname ${link_lib} NAME)
string(REGEX REPLACE "\\.[^.]*$" "" libname_wle ${libname})
string(REGEX REPLACE "^lib" "" libname_wle ${libname_wle})
set(link_flag "-l${libname_wle}")
set(description
"Extracting link flags from path '${link_lib}', beware that this can be fragile.")
else()
set(link_flag "${link_lib} -Wl,-rpath,${dir_path}")
set(description "Generating link flags from path ${link_lib}")
endif()
message(NOTICE "${description} Got: ${link_flag}")
string(APPEND NRN_LINK_DEFS " ${link_flag}")
endforeach()
endfunction(get_link_libraries)

get_link_libraries("${NRN_LINK_LIBS}")
get_link_libraries(NRN_LINK_DEFS "${NRN_LINK_LIBS}")

# Compiler flags depending on cmake build type from BUILD_TYPE_<LANG>_FLAGS
string(TOUPPER "${CMAKE_BUILD_TYPE}" _BUILD_TYPE)
Expand Down
63 changes: 63 additions & 0 deletions cmake/MacroHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,66 @@ macro(nrn_mpi_find_package)
find_package(MPI REQUIRED)
endif()
endmacro()

function(get_link_libraries link_defs libs)
if(NOT libs)
set(${link_defs}
""
PARENT_SCOPE)
return()
endif()
set(all_defs "")
# CMake does some magic to transform sys libs to -l<libname>. We replicate it
foreach(link_lib ${libs})
# skip static readline library as it will be linked to nrniv (e.g. with wheel) also stub
# libraries from OSX can be skipped
if("${link_lib}" MATCHES "(libreadline.a|/*.tbd)")
continue()
endif()

get_filename_component(dir_path ${link_lib} DIRECTORY)
if(TARGET ${link_lib})
get_property(
sublink_flag
TARGET ${link_lib}
PROPERTY INTERFACE_LINK_LIBRARIES)
set(description
"Extracting link flags from target '${link_lib}', beware that this can be fragile.")
# Not use it yet because it can be generator expressions get_property(compile_flag TARGET
# ${link_lib} PROPERTY INTERFACE_COMPILE_OPTIONS) string(APPEND NRN_COMPILE_DEFS
# ${compile_flag})
foreach(sublink_lib ${sublink_flag})
if(TARGET ${sublink_lib})
message(NOTICE "For '${link_lib}' going to see TARGET '${sublink_lib}' recursively.")
get_link_libraries(${sublink_lib})
else()
set(link_flag "${link_flag} ${sublink_flag}")
endif()
endforeach()
elseif(NOT dir_path)
set(link_flag "-l${link_lib}")
set(description
"Generating link flags from name '${link_lib}', beware that this can be fragile.")
# avoid library paths from special directory /nrnwheel which used to build wheels under docker
# container
elseif("${dir_path}" MATCHES "^/nrnwheel")
continue()
elseif("${dir_path}" MATCHES "^(/lib|/lib64|/usr/lib|/usr/lib64)$")
# NAME_WLE not avaialble with CMake version < 3.14
get_filename_component(libname ${link_lib} NAME)
string(REGEX REPLACE "\\.[^.]*$" "" libname_wle ${libname})
string(REGEX REPLACE "^lib" "" libname_wle ${libname_wle})
set(link_flag "-l${libname_wle}")
set(description
"Extracting link flags from path '${link_lib}', beware that this can be fragile.")
else()
set(link_flag "${link_lib} -Wl,-rpath,${dir_path}")
set(description "Generating link flags from path ${link_lib}")
endif()
message(NOTICE "${description} Got: ${link_flag}")
string(APPEND all_defs " ${link_flag}")
endforeach()
set(${link_defs}
"${all_defs}"
PARENT_SCOPE)
endfunction(get_link_libraries)
61 changes: 4 additions & 57 deletions cmake/coreneuron/MakefileBuildOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,63 +35,10 @@ set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_FLAGS " -lcorenrnmec
if(NOT CORENRN_ENABLE_SHARED)
set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_FLAGS " -Wl,--no-whole-archive")
endif()
# Essentially we "just" want to unpack the CMake dependencies of the `coreneuron-core` target into a
# plain string that we can bake into the Makefiles in both NEURON and CoreNEURON.
function(coreneuron_process_library_path library)
get_filename_component(library_dir "${library}" DIRECTORY)
if(NOT library_dir)
# In case target is not a target but is just the name of a library, e.g. "dl"
set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_DEP_FLAGS " -l${library}")
elseif("${library_dir}" MATCHES "^(/lib|/lib64|/usr/lib|/usr/lib64)$")
# e.g. /usr/lib64/libpthread.so -> -lpthread TODO: consider using
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.html, or
# dropping this special case entirely
get_filename_component(libname ${library} NAME_WE)
string(REGEX REPLACE "^lib" "" libname ${libname})
set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_DEP_FLAGS " -l${libname}")
else()
# It's a full path, include that on the line
set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_DEP_FLAGS
" -Wl,-rpath,${library_dir} ${library}")
endif()
endfunction()
function(coreneuron_process_target target)
if(TARGET ${target})
if(NOT target STREQUAL "coreneuron-core")
# This is a special case: libcoreneuron-core.a is manually unpacked into .o files by the
# nrnivmodl-core Makefile, so we do not want to also emit an -lcoreneuron-core argument.
get_target_property(target_inc_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES)
if(target_inc_dirs)
foreach(inc_dir_genex ${target_inc_dirs})
string(GENEX_STRIP "${inc_dir_genex}" inc_dir)
if(inc_dir)
set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_EXTRA_COMPILE_FLAGS " -I${inc_dir}")
endif()
endforeach()
endif()
get_target_property(target_imported ${target} IMPORTED)
if(target_imported)
# In this case we can extract the full path to the library
get_target_property(target_location ${target} LOCATION)
coreneuron_process_library_path(${target_location})
else()
# This is probably another of our libraries, like -lcoreneuron-cuda. We might need to add -L
# and an RPATH later.
set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_DEP_FLAGS " -l${target}")
endif()
endif()
get_target_property(target_libraries ${target} LINK_LIBRARIES)
if(target_libraries)
foreach(child_target ${target_libraries})
coreneuron_process_target(${child_target})
endforeach()
endif()
return()
endif()
coreneuron_process_library_path("${target}")
endfunction()
coreneuron_process_target(coreneuron-core)
get_property(CORENRN_LIB_LINK_DEP_FLAGS GLOBAL PROPERTY CORENRN_LIB_LINK_DEP_FLAGS)

get_target_property(target_libraries coreneuron-core LINK_LIBRARIES)
get_link_libraries(CORENRN_LIB_LINK_DEP_FLAGS ${target_libraries})

set_property(GLOBAL APPEND_STRING PROPERTY CORENRN_LIB_LINK_FLAGS " ${CORENRN_LIB_LINK_DEP_FLAGS}")
# In static builds then NEURON uses dlopen(nullptr, ...) to look for the corenrn_embedded_run
# symbol, which comes from libcoreneuron-core.a and gets included in libcorenrnmech.
Expand Down