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

macOS universal2 package installer #1570

Merged
merged 22 commits into from
Feb 24, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
76a270b
On mac arm64 can do a universal2 build for "x86_64 arm64"
nrnhines Jan 1, 2022
f4d0212
fix some typos. bldnrnmacpkgcmake.sh works for universal2
nrnhines Jan 2, 2022
48616e9
doc for universal2 install packages.
nrnhines Jan 2, 2022
e81e026
macOS,arm64 stderr message if mismatched arch for dlopen.
nrnhines Jan 2, 2022
6e80a61
Some doc details about notarization.
nrnhines Jan 3, 2022
d29db7a
Update mac_pkg.md
nrnhines Jan 3, 2022
0de4d4b
macOS x86_64 machine can also build a universal2 package.
nrnhines Jan 4, 2022
abbe04a
Merge branch 'master' into hines/universal2-macos
nrnhines Jan 4, 2022
9c4cb48
Apply suggestions from code review
nrnhines Jan 5, 2022
be6255a
fix brew install instructions
alexsavulescu Jan 5, 2022
54e9009
MACOSX_DEPLOYMENT_TARGET=11
nrnhines Jan 5, 2022
b9a811a
macos version appears in installer name
nrnhines Jan 7, 2022
2e4e3a2
update macos instructions
nrnhines Jan 7, 2022
16cd0ca
Merge branch 'master' into hines/universal2-macos
nrnhines Jan 7, 2022
fb05a84
Merge branch 'master' into hines/universal2-macos
nrnhines Jan 15, 2022
93c9d91
Choose MACOSX_DEPLOYMENT_TARGET consistent with all Pythons
nrnhines Jan 16, 2022
cacb3ee
Merge branch 'master' into hines/universal2-macos
nrnhines Jan 16, 2022
2be921f
Merge branch 'master' into hines/universal2-macos
nrnhines Jan 31, 2022
ced504a
Merge branch 'master' into hines/universal2-macos
alexsavulescu Feb 18, 2022
11e50b1
use sysconfig.get_platform() to determine name of pkg file.
nrnhines Feb 23, 2022
ea91228
Merge branch 'master' into hines/universal2-macos
nrnhines Feb 23, 2022
a09fe20
Latest mingw changed location of crtbegin.o
nrnhines Feb 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ endif()
# Enable MPI
# =============================================================================
if(NRN_ENABLE_MPI)
find_package(MPI REQUIRED)

# find_package(MPI REQUIRED) has a CMAKE_OSX_ARCHITECTURES edge case
nrn_mpi_find_package()
set(NRNMPI 1)
set(PARANEURON 1)
# avoid linking to C++ bindings
Expand Down Expand Up @@ -435,7 +437,7 @@ else()
endif()

# =============================================================================
# Add helpder CMake modules AFTER setting options
# Add helper CMake modules AFTER setting options
# =============================================================================
include(NeuronFileLists)
include(MPIDynamicHelper)
Expand Down Expand Up @@ -643,6 +645,11 @@ file(COPY ${NRN_HEADERS_PATHS} ${PROJECT_BINARY_DIR}/src/oc/nrnpthread.h
DESTINATION ${PROJECT_BINARY_DIR}/include)
install(DIRECTORY ${PROJECT_BINARY_DIR}/include DESTINATION ${CMAKE_INSTALL_PREFIX})

if (NRN_MACOS_BUILD)
# universal build for neurondemo needs to be after, or at end of, install
NRN_MACOS_AFTER_INSTALL()
nrnhines marked this conversation as resolved.
Show resolved Hide resolved
endif()

# =============================================================================
# Copy bash executable for windows
# =============================================================================
Expand Down Expand Up @@ -785,6 +792,9 @@ if(NRN_ENABLE_CORENEURON)
message(STATUS " Legacy Units| ${CORENRN_ENABLE_LEGACY_UNITS}")
endif()
endif()
if (NRN_UNIVERSAL2_BUILD)
message(STATUS "CMAKE_OSX_A...| ${CMAKE_OSX_ARCHITECTURES}")
nrnhines marked this conversation as resolved.
Show resolved Hide resolved
endif()
message(STATUS "Tests | ${NRN_ENABLE_TESTS}")
if(NRN_ENABLE_COVERAGE)
message(STATUS "Coverage | Enabled")
Expand Down
41 changes: 31 additions & 10 deletions bldnrnmacpkgcmake.sh
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
#!/bin/bash
set -ex

default_pythons="python3.8 python3.9 python3.10"
# distribution built with
# bash bldnrnmacpkgcmake.sh python3.6 python3.7 python3.8 python3.9
# without args, default is the 5 pythons above.
# bash bldnrnmacpkgcmake.sh
# without args, default are the pythons above.


CPU=`uname -m`

universal="yes" # changes to "no" if any python not universal

args="$*"
if test "$args" = "" ; then
if test "$CPU" = "x86_64" ; then
args="python3.6 python3.7 python3.8 python3.9"
else # arm64
args="python3 python3.9"
fi
args="$default_pythons"
fi

#10.7 possible if one builds with pythons that are consistent with that.
Expand All @@ -36,14 +37,26 @@ mkdir -p $NRN_BLD
rm -r -f $NRN_BLD/*
cd $NRN_BLD

PYVS="py" # will be part of package file name, eg. py-27-35-36-37-38
PYVS="py" # will be part of package file name, eg. py-37-38-39-310
pythons="" # will be arg value of NRN_PYTHON_DYNAMIC
for i in $args ; do
PYVER=`$i -c 'from sys import version_info as v ; print (str(v.major) + str(v.minor)); quit()'`
PYVS=${PYVS}-${PYVER}
pythons="${pythons}${i};"
pypath="`which $i`"
archs="`lipo -archs $pypath`"
if test "$archs" != "x86_64 arm64" ; then
universal="no"
fi
done

archs_pkg="" # will be part of the package file name, eg. -arm64-x86_64
archs_cmake="" # arg for CMAKE_OSX_ARCHITECTURES, eg. arm64;x86_64
if test "$universal" = "yes" ; then
archs_pkg="-arm64-x86_64"
archs_cmake='-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64'
fi

# The reason for the "-DCMAKE_PREFIX_PATH=/usr/X11" below
# is to definitely link against the xquartz.org installation instead
# of the one under /opt/homebrew/ (which I think came
Expand All @@ -57,11 +70,19 @@ cmake .. -DCMAKE_INSTALL_PREFIX=$NRN_INSTALL \
-DIV_ENABLE_X11_DYNAMIC=ON \
-DNRN_ENABLE_CORENEURON=OFF \
-DNRN_RX3D_OPT_LEVEL=2 \
-DCMAKE_OSX_ARCHITECTURES="$CPU" \
$archs_cmake \
-DCMAKE_PREFIX_PATH=/usr/X11 \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

make -j install

if test "$universal" = "yes" ; then
_temp="`lipo -archs $NRN_INSTALL/share/nrn/demo/release/$CPU/special`"
if test "$_temp" != "x86_64 arm64" ; then
echo "universal build failed. lipo -archs .../special is \"$_temp\" instead of \"x86_64 arm64\""
exit 1
fi
fi
$NRN_INSTALL/bin/neurondemo -c 'quit()'

chk () {
Expand Down Expand Up @@ -99,7 +120,7 @@ done
# upload package to neuron.yale.edu
ALPHADIR='[email protected]:/home/htdocs/ftp/neuron/versions/alpha'
describe="`sh $NRN_SRC/nrnversion.sh describe`"
PACKAGE_FULL_NAME=nrn-${describe}-osx-${CPU}-${PYVS}.pkg
PACKAGE_FULL_NAME=nrn-${describe}-osx${archs_pkg}-${PYVS}.pkg
PACKATE_DOWNLOAD_NAME=$ALPHADIR/$PACKAGE_FULL_NAME
PACKAGE_FILE_NAME=$NRN_BLD/src/mac/build/NEURON.pkg
echo "
Expand Down
20 changes: 20 additions & 0 deletions cmake/MacroHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,23 @@ macro(nrn_install_dir_symlink source_dir symlink_dir)
# create symbolic link
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${source_dir} ${symlink_dir})")
endmacro(nrn_install_dir_symlink)

# ========================================================================
# There is an edge case to 'find_package(MPI REQUIRED)' in that we can
# still build a universal2 macos package on an arm64 architecture even if
# the mpi library has no slice for x86_64.
# ========================================================================
macro(nrn_mpi_find_package)
if ("arm64" IN_LIST CMAKE_OSX_ARCHITECTURES
AND "x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES
AND NRN_ENABLE_MPI_DYNAMIC)
set(_temp ${CMAKE_OSX_ARCHITECTURES})
unset(CMAKE_OSX_ARCHITECTURES CACHE)
find_package(MPI REQUIRED)
set(CMAKE_OSX_ARCHITECTURES ${_temp} CACHE INTERNAL "" FORCE)
set(NRN_UNIVERSAL2_BUILD ON)
else()
find_package(MPI REQUIRED)
endif()
endmacro()

74 changes: 67 additions & 7 deletions docs/install/install_instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,84 @@ pip3 install neuron
Python wheels are provided via [pypi.org](https://pypi.org/project/NEURON/). Note that Python2
wheels are provided for the 8.0.x release series exclusively.

Like Windows, you can also use a binary installer to install NEURON. You can download alpha or recent
releases from below URLs:
Like Windows, you can also use a binary installer to install NEURON.
Recent releases are at

* [Alpha releases](https://neuron.yale.edu/ftp/neuron/versions/alpha/)
* [Recent Releases](https://neuron.yale.edu/ftp/neuron/versions/)
* [Recent Releases](https://github.com/neuronsimulator/nrn/releases)

You can download legacy versions from:

Mac OS installers have name in the format of `nrn-<version-id>-osx-36-37-38-39.pkg`. Like windows
installer, `py-36-37-38-39` string in the installer name indicates that the given installer is
* [Legacy Versions](https://neuron.yale.edu/ftp/neuron/versions/)

Earlier Mac OS pkg installers have name in the format of
`nrn-<version-id>-osx-36-37-38-39.pkg`.
Like windows installers,
the, `py-36-37-38-39` string in the installer name indicates that the given installer is
compatible with Python versions 3.6, 3.7, 3.8 and 3.9. Note that if you double-click the installer
then you might see warning like below. In this case you have to right-click on the installer and then
click `Open`. You can then see an option to `Open` installer:

The latest Mac OS pkg installers (as of 2022-01-01) are universal2 installers
(for arm64 and x86_64) and extend the name convention to specify which
architectures they run on.
`nrn-<version-id>-osx-<archs>-py-<pythonversions>.pkg`
e.g.
`nrn-8.0a-690-g3ddaecc21-osx-arm64-x86_64-py-38-39-310.pkg`

![Installer Warning](../_static/osx_installer_warning_solution.png "Mac OS Warning")

This will install NEURON under directory `/Applications/NEURON-<version>/` directory. For GUI support you
The latest pkg installers will install NEURON under the directory `/Applications/NEURON/` directory.
Uninstallng consists of dragging that folder to the trash. For GUI support you
have to install [XQuartz](https://www.xquartz.org/) separately. Once you start Terminal application, NEURON
binaries (`nrniv`, `neurondemo` etc.) should be available to start.

* Universal2 installers generally "just work" on either an x86_64 or arm64
architecture.

```
python
from neuron import h
```
and ```nrnivmodl``` will by default create an nmodl mechanism library
specifically for the architecture you run on.

But it may be the case on Apple M1 that you install a python that can
only run as an x86_64 program under Rosetta2.
E.g. The latest Anaconda Python3.9 (though it seems likely that the next
distribution will be universal2).
In this case, if you wish to launch nrniv, force nrniv to launch as an x86_64
program. E.g.
```
arch -arch x86_64 nrniv -python
from neuron import h
```
Furthermore, be sure to run nrnivmodl in such a way that it compiles as an
x86_64 library. e.g.
```
arch -arch x86_64 nrnivmodl
```
although this constructs an arm64 folder, it will compile and link as x86_64.
```
% lipo -archs arm64/libnrnmech.dylib
x86_64
```
Alternatively, one can get a universal2 result with
```
nrnivmodl -incflags '-arch x86_64 -arch arm64' -loadflags '-arch x86_64 -arch arm64'
```

If, at runtime there is architecture mismatch between python, MPI,
libnrnmech.so, or libnrniv.dylib, you will see an error message similar
to
```
Could not dlopen NRN_PYLIB: /Users/hines/opt/anaconda3/lib/libpython3.9.dylib
libnrniv.dylib running as arm64
but /Users/hines/opt/anaconda3/lib/libpython3.9.dylib can only run as x86_64
```

Note: there is an environment variable called `ARCHPREFERENCE`. See
`man arch`.

#### Linux

Like Mac OS, since 7.8.1 release python wheels are provided and you can use `pip` to install NEURON as:
Expand Down
Loading