asdf-erlang: Cannot build with ODBC support on M1 Macs using ARM-based version of Homebrew
Homebrew installs packages on Intel-based Macs into /usr/local
. It installs packages on M1-based Macs into /opt/homebrew
. The asdf-erlang package currently fails to build support for ODBC (even though the unixodbc package is installed) with the following error:
* odbc : ODBC library - link check failed
I’ve verified that the library files are linked using the brew link
command. I’ve also tried setting my environment to manually point to the ODBC files in /opt/homebrew
, but the asdf-erlang package still can’t seem to find the library files on M1 Macs. It works fine on Intel-based Macs.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 5
- Comments: 15 (1 by maintainers)
Hope this will help anyone.
You need to install unixodbc with
brew install unixodbc
and link itAdd
--with-odbc={path_to_unixodbc}
to .kerlrc like thisAlso we need to set ENVs
After this you can install erlang with
asdf install erlang 24.0.3
After some testing based on @nikneroz’s instructions, I’ve determined that the following pattern works, at least on Apple Silicon Macs with Erlang 25.0.3 when building using
asdf
. I’ve included additional context so that others can understand why this works, and you should be able to use that to adjust the instructions to your needs.The first expectation is that the ODBC library is installed using Homebrew:
brew install unixodbc
.Second, you must link the install directory to
/usr/local/odbc
. The rest of these instructions will fail if you don’t. The following command will link the directory:sudo ln -s $(realpath $(brew --prefix unixodbc)) /usr/local/odbc
. The link must be to the actual directory where UnixODBC is installed, andrealpath
will ensure you get the right location instead of linking to a symlink (which won’t work properly).Then, the following environment variables must be set before triggering the Erlang build system:
Then, you can build Erlang using whatever build pattern you prefer. For example, I use
asdf
which in turn depends onkerl
.The configuration depends on the helper command
brew --prefix
which will output the directory where dependency files can be found. For example, callingbrew --prefix unixodbc
on an Apple Silicon Mac will output/opt/homebrew/opt/unixodbc
.Autoconf is the program that determines how to configure the Erlang build and as part of that process it will try to detect whether dependency libraries are installed for different features. If the library isn’t installed, it disables the feature.
CC
explicitly tells Autoconf which C compiler to use. In this case, we tell it to use the GNU Compiler Collection (GCC) front-end and call it with the-I
flag. This flag tells GNU GCC that we want to include a non-standard directory in the search path for header files. In this case, we are including the directory where the UnixODBC headers are installed.LDFLAGS
is used to pass additional flags to theld
linker called during the build process. The-L
flag instructsld
to look for libraries in a non-standard directory. In this case, we are including the directory where the UnixODBC library is installed. (Note: The referenced documentation is for the GNU linker tool which is part of the GNU Binutils project, but on macOS the Apple LD64 tool will be used instead. The flag is used the same way for both tools.)Note, you do not need to pass
--with-odbc
as part of your configuration for the Erlang build. Autoconf will assume that ODBC support should be included as long as it can discover a supporting library.I didn’t like the solution of having to create a symbolic link so I dug deep into the Erlang Makefiles in an attempt to discover the root of this problem.
In short: the Erlang build system doesn’t recognize it’s building on Darwin in recent versions because it assumes the version string starts with
darwin1*
and we’re now on Darwin 22.5.0 as of Ventura: https://github.com/erlang/otp/blob/f820bad7bed34cc4365bb9cac56eaa84c9a5bddc/lib/odbc/configure.ac#L151-L163This causes it to fall through to a generic case that looks for ODBC libraries and headers in
/usr/local/odbc
: https://github.com/erlang/otp/blob/f820bad7bed34cc4365bb9cac56eaa84c9a5bddc/lib/odbc/configure.ac#L204-L206.It will also check in the directory supplied with
--with-odbc
as a last resort; this is the key to building without the symbolic link.I considered submitting a patch to fix this upstream but I really hate fighting with Autotools and I couldn’t figure out how to make it work generically, and I don’t know what Erlang/OTP’s support policy is for older versions of macOS (I typically only care about the latest because I try to upgrade as soon as possible). The build system also expects macOS to ship with
libiodbc
, which may have been the case fordarwin1x
but doesn’t appear to be the case now, despite being in the open source tree as recently as Ventura 13.2: https://github.com/apple-oss-distributions/distribution-macOS/tree/macos-132. I appear to have alibiodbc
dylib supplied as part of a Rapid Security Response (https://support.apple.com/en-us/HT201224) but it doesn’t include headers so it’s not really relevant here.So in conclusion, to build without linking
unixodbc
, you can set these environment variables after installingunixodbc
(I put them in.zshenv
, but your choice ultimately):Ironically, I’ve still yet to use the ODBC support in Erlang and Elixir, I just hate build errors and having “incomplete” Erlang runtime installs hanging around.
In my case,
sudo ln -s $(realpath $(brew --prefix odbc)) /usr/local/odbc
was not working, asbrew --prefix odbc
returnedError: No available formula with the name "odbc".
.But
brew --prefix unixodbc
returned a path.So I just changed it to
sudo ln -s $(realpath $(brew --prefix unixodbc)) /usr/local/odbc
, and it worked.Thanks, guys!
Updated instructions
You need to install unixodbc with
brew install unixodbc
and link it -Add
--with-odbc={path_to_unixodbc}
to.kerlrc
like thisAlso we need to set ENVs
After this you can install erlang with asdf install erlang 25.1.2
Thanks @leandro-cft! Edited my instructions with your updates.
it worked for me:
CC="/usr/bin/gcc -I/opt/homebrew/Cellar/unixodbc/2.3.9/include -L/opt/homebrew/Cellar/unixodbc/2.3.9/lib" asdf install erlang 23.2.3