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

Cannot build with ODBC support on M1 Macs using ARM-based version of Homebrew #191

Open
cdeyoung opened this issue Mar 16, 2021 · 15 comments

Comments

@cdeyoung
Copy link

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.

@jeno007
Copy link

jeno007 commented Apr 12, 2021

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

@nikneroz
Copy link

@cdeyoung Did you find a way to build it with ODBC support?

@nikneroz
Copy link

nikneroz commented Jul 25, 2021

Hope this will help anyone.

You need to install unixodbc with brew install unixodbc and link it

sudo ln -s /opt/homebrew/Cellar/unixodbc/2.3.9_1/ /usr/local/odbc                                                                                                                        
sudo chown -R $(whoami) /usr/local/odbc/

Add --with-odbc={path_to_unixodbc} to .kerlrc like this

KERL_CONFIGURE_OPTIONS="--enable-darwin-64bit --disable-hipe --enable-vm-probes --with-dynamic-trace=dtrace --disable-native-libs --enable-kernel-poll --enable-threads --enable-smp-support --with-wx --with-odbc=/opt/homebrew/Cellar/unixodbc/2.3.9_1"
GREP_OPTIONS=''

Also we need to set ENVs

export CC="/usr/bin/gcc -I/opt/homebrew/Cellar/unixodbc/2.3.9_1/include"
export LDFLAGS="-L/opt/homebrew/Cellar/unixodbc/2.3.9_1/lib"

After this you can install erlang with asdf install erlang 24.0.3

@Stratus3D
Copy link
Member

@cdeyoung did you ever get your build working?

@nikneroz is there anything we should change in the docs or the code to make this easier in the future? PRs welcomed!

@cdeyoung
Copy link
Author

@cdeyoung did you ever get your build working?

Sorry for the very late reply, @Stratus3D. I've been down with health issues and just got back to this.

No, I have not compiled Erlang with ODBC support yet on an M1 but I haven't tried @nikneroz's suggestion either. I'll try it.

@dylan-chong
Copy link

dylan-chong commented Dec 20, 2021

@nikneroz This didn't work for me (erlang 24.1.7), mac os 12.1 M1 (terminal kitty, in x86 mode)

@carlogilmar
Copy link

Worked fine 🚀

I just needed:

  1. Uninstall my Erlang and elixir versions
  2. Install the unixodbc using brew
  3. Link it
  4. Export the variables
  5. Reinstall again Erlang and elixir (in my case)

@Johnius
Copy link

Johnius commented Apr 11, 2022

What is worked for me: CFLAGS="-O2 -g -I/opt/homebrew/Cellar/unixodbc/2.3.9_1/include" LDFLAGS="-L/opt/homebrew/Cellar/unixodbc/2.3.9_1/lib" ./configure --with-odbc="/opt/homebrew/Cellar/unixodbc/2.3.9_1"

@austinarbor
Copy link

@carlogilmar which variables are you referring to in step 4?

@jrasanen
Copy link

jrasanen commented Jun 23, 2022

The environment variables that were mentioned above. Worked for me too.

@DavidAntaramian
Copy link

DavidAntaramian commented Aug 5, 2022

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, and realpath 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:

export CC="/usr/bin/gcc -I$(brew --prefix unixodbc)/include"
export LDFLAGS="-L$(brew --prefix unixodbc)/lib"

Then, you can build Erlang using whatever build pattern you prefer. For example, I use asdf which in turn depends on kerl.

The configuration depends on the helper command brew --prefix which will output the directory where dependency files can be found. For example, calling brew --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 the ld linker called during the build process. The -L flag instructs ld 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.

@leandro-cft
Copy link

leandro-cft commented Sep 14, 2022

In my case, sudo ln -s $(realpath $(brew --prefix odbc)) /usr/local/odbc was not working, as brew --prefix odbc returned Error: 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!

@DavidAntaramian
Copy link

Thanks @leandro-cft! Edited my instructions with your updates.

@noslav
Copy link

noslav commented Mar 8, 2023

Hope this will help anyone.

You need to install unixodbc with brew install unixodbc and link it

sudo ln -s /opt/homebrew/Cellar/unixodbc/2.3.9_1/ /usr/local/odbc                                                                                                                        
sudo chown -R $(whoami) /usr/local/odbc/

Add --with-odbc={path_to_unixodbc} to .kerlrc like this

KERL_CONFIGURE_OPTIONS="--enable-darwin-64bit --disable-hipe --enable-vm-probes --with-dynamic-trace=dtrace --disable-native-libs --enable-kernel-poll --enable-threads --enable-smp-support --with-wx --with-odbc=/opt/homebrew/Cellar/unixodbc/2.3.9_1"
GREP_OPTIONS=''

Also we need to set ENVs

export CC="/usr/bin/gcc -I/opt/homebrew/Cellar/unixodbc/2.3.9_1/include"
export LDFLAGS="-L/opt/homebrew/Cellar/unixodbc/2.3.9_1/lib"

After this you can install erlang with asdf install erlang 24.0.3

Updated instructions

You need to install unixodbc with brew install unixodbc and link it -

sudo ln -sfn $(realpath $(brew --prefix unixodbc)) /usr/local/odbc                                                                                                                  
sudo chown -R $(whoami) /usr/local/odbc/

Add --with-odbc={path_to_unixodbc} to .kerlrc like this

KERL_CONFIGURE_OPTIONS="--enable-darwin-64bit --disable-hipe --enable-vm-probes --with-dynamic-trace=dtrace --disable-native-libs --enable-kernel-poll --enable-threads --enable-smp-support --with-wx --with-odbc=/opt/homebrew/Cellar/unixodbc/2.3.9_1"
GREP_OPTIONS=''

Also we need to set ENVs

export CC="/usr/bin/gcc -I/opt/homebrew/Cellar/unixodbc/2.3.11/include"
export LDFLAGS="-L/opt/homebrew/Cellar/unixodbc/2.3.11/lib"

After this you can install erlang with asdf install erlang 25.1.2

@bklebe
Copy link

bklebe commented Jun 20, 2023

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-L163

$ uname -a
Darwin <hostname> 22.5.0 Darwin Kernel Version 22.5.0: Mon Apr 24 20:52:24 PDT 2023; root:xnu-8796.121.2~5/RELEASE_ARM64_T6000 arm64

This 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 for darwin1x 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 a libiodbc 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 installing unixodbc (I put them in .zshenv, but your choice ultimately):

export CPPFLAGS="${CPPFLAGS+"$CPPFLAGS "}-I/opt/homebrew/opt/unixodbc/include"
export LDFLAGS="${LDFLAGS+"$LDFLAGS "}-L/opt/homebrew/opt/unixodbc/lib"
export KERL_CONFIGURE_OPTIONS="--with-odbc=/opt/homebrew/opt/unixodbc"

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests