rails-sqlserver / tiny_tds

TinyTDS - Simple and fast FreeTDS bindings for Ruby using DB-Library.
Other
606 stars 190 forks source link

Fails to build native extension on Apple M1 Macs, apparently due to looking for libraries/headers in wrong place #484

Closed dtgay closed 8 months ago

dtgay commented 3 years ago

Environment

Operating System

ProductName:    macOS
ProductVersion: 11.1
BuildVersion:   20C69

TinyTDS Version and Information

Compile-time settings (established with the "configure" script)
                            Version: freetds v1.2.18
             freetds.conf directory: /opt/homebrew/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.3
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: yes
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: yes

FreeTDS Version

free-tds-1.2.18.arm64

Description

The gem installation fails on the new Macs with the M1 chip (ARM) when homebrew was used to install freetds:

Fetching tiny_tds 2.1.3.pre
Installing tiny_tds 2.1.3.pre with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

This appears to be because it's looking for the libraries/headers in the wrong place:

current directory:
/Users/david/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/tiny_tds-2.1.3.pre/ext/tiny_tds
/Users/david/.rbenv/versions/2.7.2/bin/ruby -I /Users/david/.rbenv/versions/2.7.2/lib/ruby/2.7.0 -r
./siteconf20201230-18443-1m6z2pa.rb extconf.rb
looking for freetds headers in the following directories:
 - /opt/local/include
 - /opt/local/include/freetds
 - /usr/local/include
 - /usr/local/include/freetds
looking for freetds library in the following directories:
 - /opt/local/lib
 - /opt/local/lib/freetds
 - /usr/local/lib
 - /usr/local/lib/freetds
checking for sybfront.h... no
checking for sybdb.h... no
checking for tdsdbopen() in -lsybdb... no
checking for dbanydatecrack() in -lsybdb... no
Failed! Do you have FreeTDS 0.95.80 or higher installed?
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

It looks like the files it's looking for are actually here:

❯ sudo find /opt -name "*syb*"
/opt/homebrew/include/sybdb.h
/opt/homebrew/include/syberror.h
/opt/homebrew/include/sybfront.h
/opt/homebrew/lib/libsybdb.dylib
/opt/homebrew/lib/libsybdb.a
/opt/homebrew/lib/libsybdb.5.dylib
/opt/homebrew/Cellar/freetds/1.2.18/include/sybdb.h
/opt/homebrew/Cellar/freetds/1.2.18/include/syberror.h
/opt/homebrew/Cellar/freetds/1.2.18/include/sybfront.h
/opt/homebrew/Cellar/freetds/1.2.18/lib/libsybdb.dylib
/opt/homebrew/Cellar/freetds/1.2.18/lib/libsybdb.a
/opt/homebrew/Cellar/freetds/1.2.18/lib/libsybdb.5.dylib

If this isn't the right place for this issue, please let me know where I should report it. Thanks!

dtgay commented 3 years ago

Just for funsies I ran this extremely hacky series of commands to see if the problem would be resolved:

sudo mkdir -p /opt/local/include
sudo mkdir -p /opt/local/lib
sudo ln -s /opt/homebrew/include/sybdb.h /opt/local/include/sybdb.h
sudo ln -s /opt/homebrew/include/syberror.h /opt/local/include/syberror.h
sudo ln -s /opt/homebrew/include/sybfront.h /opt/local/include/sybfront.h
sudo ln -s /opt/homebrew/lib/libsybdb.dylib /opt/local/lib/libsybdb.dylib
sudo ln -s /opt/homebrew/lib/libsybdb.a /opt/local/lib/libsybdb.a
sudo ln -s /opt/homebrew/lib/libsybdb.5.dylib /opt/local/lib/libsybdb.5.dylib
sudo chown -R david:admin /opt/local

It didn't get the gem to install, but it did change the output from:

checking for sybfront.h... no
checking for sybdb.h... no
checking for tdsdbopen() in -lsybdb... no
checking for dbanydatecrack() in -lsybdb... no
Failed! Do you have FreeTDS 0.95.80 or higher installed?

to:

checking for sybfront.h... no
checking for sybdb.h... no
checking for tdsdbopen() in -lsybdb... yes
checking for dbanydatecrack() in -lsybdb... yes
Failed! Do you have FreeTDS 0.95.80 or higher installed?
simonwahlstrom commented 3 years ago

Thanks to your post I got it compiling by adding these symlinks: sudo ln -s /opt/homebrew/lib/ /opt/local/lib sudo ln -s /opt/homebrew/include/ /opt/local/include

dtgay commented 3 years ago

@simonwahlstrom That does indeed work, my only concern being that by linking the entire directory, anything that tries to install into /opt/local/lib/ or /opt/local/include/ will actually install into the respective directory in /opt/homebrew/, which might break... something.

It would be better I think if we can figure out which exact files need to be linked, in order to avoid linking the entire directory. Apparently the list I used in my previous comment was insufficient, and I haven't played around with including other files.

Weird though that linking all *syb* files is not sufficient to clear the "checking for sybfront.h" and "checking for sybdb.h" checks.

arthurcouto commented 3 years ago

Hi, i have the same problem but couldn't get it to work with the last solution... Is there a plan for fixing tiny_tds for macs with M1 in the near future?

ldlsegovia commented 3 years ago

this worked for me: gem install tiny_tds -- --with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib

gisborne commented 3 years ago

I have this problem and none of the above has helped.

% gem install tiny_tds -- --with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib
Building native extensions with: '--with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib'
This could take a while...
ERROR:  Error installing tiny_tds:
    ERROR: Failed to build gem native extension.

    current directory: /Users/gisborne/.rvm/gems/ruby-2.5.3/gems/tiny_tds-2.1.5/ext/tiny_tds
/Users/gisborne/.rvm/rubies/ruby-2.5.3/bin/ruby -r ./siteconf20210526-63505-1vycvz1.rb extconf.rb --with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib
looking for freetds headers in the following directories:
 - /opt/local/include
 - /opt/local/include/freetds
 - /usr/local/include
 - /usr/local/include/freetds
looking for freetds library in the following directories:
 - /opt/local/lib
 - /opt/local/lib/freetds
 - /usr/local/lib
 - /usr/local/lib/freetds
checking for sybfront.h... yes
checking for sybdb.h... yes
checking for tdsdbopen() in -lsybdb... no
checking for dbanydatecrack() in -lsybdb... no
Failed! Do you have FreeTDS 0.95.80 or higher installed?
*** extconf.rb failed ***

The log shows:

find_library: checking for tdsdbopen() in -lsybdb... -------------------- no

"gcc -o conftest -I/Users/gisborne/.rvm/rubies/ruby-2.5.3/include/ruby-2.5.0/x86_64-darwin18 -I/Users/gisborne/.rvm/rubies/ruby-2.5.3/include/ruby-2.5.0/ruby/backward -I/Users/gisborne/.rvm/rubies/ruby-2.5.3/include/ruby-2.5.0 -I. -I/opt/local/include -I/opt/local/include/freetds -I/usr/local/include -I/usr/local/include/freetds  -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl@1.1/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens  -fno-common -pipe conftest.c  -L. -L/Users/gisborne/.rvm/rubies/ruby-2.5.3/lib -L/opt/local/lib -L/opt/local/lib/freetds -L/usr/local/lib -L/usr/local/lib/freetds -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl@1.1/lib -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl@1.1/lib     -lruby.2.5.3 -lsybdb  -lpthread -lgmp -ldl -lobjc "
conftest.c:13:57: error: use of undeclared identifier 'tdsdbopen'
int t(void) { void ((*volatile p)()); p = (void ((*)()))tdsdbopen; return !p; }
saratscheff commented 3 years ago

/gisborne

Did you run brew install freetds before that?

gisborne commented 3 years ago

Yes. On Jun 25, 2021, 10:08 -0700, Pedro Saratscheff @.***>, wrote:

/gisborne Did you run brew install freetds before that? — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

shireeshj commented 3 years ago

This worked for me

brew install freetds
bundle config build.tiny_tds --with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib
bundle install
daveomcd commented 2 years ago

bundle config build.tiny_tds --with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib

I tried this option but am still getting the following. Is there something else wrong that someone can see?

current directory: /Users/mcdonaldd/Documents/bane/vendor/bundle/ruby/2.6.0/gems/tiny_tds-2.1.2/ext/tiny_tds
/Users/mcdonaldd/.rbenv/versions/2.6.1/bin/ruby -I /Users/mcdonaldd/.rbenv/versions/2.6.1/lib/ruby/2.6.0 -r
./siteconf20220723-16653-s8qewo.rb extconf.rb --with-freetds-include\=/opt/homebrew/include\
--with-freetds-lib\=/opt/homebrew/lib
checking for sybfront.h... no
checking for sybdb.h... no
checking for tdsdbopen() in -lsybdb... no
checking for dbanydatecrack() in -lsybdb... no
Failed! Do you have FreeTDS 0.95.80 or higher installed?
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options

FreeTDS seems to be installed and working.

Compile-time settings (established with the "configure" script)
                            Version: freetds v1.3.12
             freetds.conf directory: /opt/homebrew/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.3
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: yes
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: yes
januszm commented 2 years ago

bundle config build.tiny_tds --with-freetds-include=/opt/homebrew/include --with-freetds-lib=/opt/homebrew/lib

solves the problem when installing tiny_tds with bundle install, this should be enough for people working with Rails applications. Ideally, you'd come up with a set of LD_LIBRARY_...style or CPP flags that need to be set in order to be able to install tiny_tds with gem install and in other workflows.

andyundso commented 8 months ago

Fix has been merged with #545 (original PR: #531) and was released with 2.1.6. It should no longer be necessary to pass --with-freetds-include or --with-freetds-lib on Macs with Apple Silicon.