ld:在 macOS Big Sur 11.4 上为 mysql2 gem Ruby 捆绑安装时找不到 -lzstd 的库

问题描述

在运行 bundle install 时

An error occurred while installing MysqL2 (0.5.3),and Bundler cannot continue.
Make sure that `gem install MysqL2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

Rails 应用 6.1.3

捆绑程序版本 2.2.19

ma​​cOS Big Sur 11.4

在 Gemfile 中

ruby '2.6.6'
gem 'rails','~> 6.1.3','>= 6.1.3.1'
gem 'MysqL2'

在 Gemfile.lock 中 MysqL 在 0.5.3

当我运行 bundle install 时,它会正常崩溃:

enter image description here

检查在输出中较早出现的构建错误,构建错误似乎是:(完整结果如下)

 ld: library not found for -lzstd

bundle install 的完整结果是

jason@MacBook-Air  % bundle install    
Fetching gem Metadata from https://rubygems.org/
Fetching gem Metadata from https://rubygems.org/........
Using rake 13.0.3
Using concurrent-ruby 1.1.8
Using rack 2.2.3
Using nio4r 2.5.7
Using builder 3.2.4
Using marcel 1.0.1
Using mini_portile2 2.5.1
Using multi_json 1.15.0
Using method_source 1.0.0
Using crass 1.0.6
Using thor 1.1.0
Using public_suffix 4.0.6
Using execjs 2.7.0
Using aws-eventstream 1.1.1
Using aws-partitions 1.447.0
Using jmespath 1.4.0
Using bcrypt 3.1.16
Using betterlorem 0.1.2
Using bindex 0.8.1
Using msgpack 1.4.2
Using popper_js 1.16.0
Using ffi 1.15.0
Using tilt 2.0.10
Using bundler 2.2.19
Using byebug 11.1.3
Using regexp_parser 2.1.1
Using childprocess 3.0.0
Using connection_pool 2.2.5
Using rexml 3.2.5
Using orm_adapter 0.5.0
Using diff-lcs 1.4.4
Using unf_ext 0.0.7.7
Using docile 1.3.5
Using e2mmap 0.1.0
Using erubis 2.7.0
Using ffaker 2.18.0
Using finishing_moves 1.0.1
Using raabro 1.4.0
Using temple 0.8.2
Using sexp_processor 4.15.2
Using hashdiff 1.0.1
Using hiredis 0.6.3
Using honeybadger 4.8.0
Using kaminari-core 1.2.1
Using rb-fsevent 0.10.4
Using ruby_dep 1.5.0
Using ruby2_keywords 0.0.4
Fetching MysqL2 0.5.3
Using minitest 5.14.4
Using zeitwerk 2.4.2
Using parslet 1.8.2
Using puma 3.12.6
Using rails_http_options 0.1.0
Using redis 4.2.5
Using rubyzip 2.3.0
Using semantic_range 3.0.0
Using rspec-support 3.10.2
Using simple-random 1.0.3
Using simplecov-html 0.12.3
Using simplecov_json_formatter 0.1.2
Using spring 2.1.1
Using sqlite3 1.4.2
Using stripe 5.32.1
Using vcr 6.0.0
Using i18n 1.8.10
Using tzinfo 2.0.4
Using rack-test 1.1.0
Using sprockets 3.7.2
Using warden 1.2.9
Using rack-attack 6.5.0
Using rack-cors 1.1.1
Using rack-protection 2.1.0
Using rack-proxy 0.6.5
Using sitemap_generator 6.1.2
Using addressable 2.7.0
Using autoprefixer-rails 10.2.4.0
Using aws-sigv4 1.2.3
Using bootsnap 1.7.4
Using sassc 2.4.0
Using crack 0.4.5
Using unf 0.1.4
Using haml 5.2.1
Using ruby_parser 3.15.1
Using rb-inotify 0.10.1
Using mustermann 1.1.1
Using thwait 0.2.0
Using sidekiq 6.2.1
Using websocket-extensions 0.1.5
Using activesupport 6.1.3.2
Using aws-sdk-core 3.114.0
Using simpleidn 0.2.1
Using et-orbi 1.2.4
Using faker 2.17.0
Using sass-listen 4.0.0
Using launchy 2.5.0
Using listen 3.1.5
Using rspec-core 3.10.1
Using rspec-expectations 3.10.1
Using rspec-mocks 3.10.2
Using selenium-webdriver 3.142.7
Using simplecov 0.21.2
Using sinatra 2.1.0
Using webmock 3.12.2
Using erubi 1.10.0
Using mini_mime 1.0.3
Using racc 1.5.2
Using ruby_http_client 3.5.2
Using nokogiri 1.11.3
Using websocket-driver 0.7.3
Using globalid 0.4.2
Using activemodel 6.1.3.2
Using mail 2.7.1
Using aws-sdk-kms 1.43.0
Using dnsruby 1.61.5
Using factory_bot 6.1.0
Using fugit 1.4.5
Using sass 3.7.4
Using jbuilder 2.11.2
Using rspec 3.10.0
Using sendgrid-ruby 6.4.0
Using shoulda-matchers 4.5.1
Using simplecov-rcov 0.2.3
Using split 3.4.1
Using spring-watcher-listen 2.0.1
Using rails-dom-testing 2.0.3
Using loofah 2.9.1
Using activejob 6.1.3.2
Using activerecord 6.1.3.2
Using aws-sdk-s3 1.93.1
Using xpath 3.2.0
Using html2haml 2.2.0
Using roo 2.8.3
Using rspec-wait 0.0.9
Using rufus-scheduler 3.7.0
Using webdrivers 4.6.0
Using rails-html-sanitizer 1.3.0
Using sidekiq-scheduler 3.0.1
Using capybara 3.35.3
Using counter_culture 2.8.0
Using actionview 6.1.3.2
Using kaminari-activerecord 1.2.1
Using actionpack 6.1.3.2
Using kaminari-actionview 1.2.1
Using nonschema_migrations 5.0.2
Using actionmailer 6.1.3.2
Using railties 6.1.3.2
Using sprockets-rails 3.2.2
Using kaminari 1.2.1
Using activestorage 6.1.3.2
Using activerecord-session_store 2.0.0
Using font_awesome5_rails 1.4.0
Using actioncable 6.1.3.2
Using haml-rails 2.0.1
Using sass-rails 5.1.0
Using jquery-rails 4.4.0
Using rspec-rails 5.0.1
Using web-console 4.1.0
Using webpacker 5.2.1
Using actionmailBox 6.1.3.2
Using actiontext 6.1.3.2
Using sassc-rails 2.1.2
Using responders 3.0.1
Using bootstrap 4.4.1
Using rails 6.1.3.2
Using factory_bot_rails 6.1.0
Using devise 4.7.3
Using turbo-rails 0.5.9 from https://github.com/hotwired/turbo-rails.git (at main@2945dcb)
Using stimulus-rails 0.2.3
Using stripe-rails 2.3.0
Using universal-track-manager 0.6.1.alpha
Using paranoia 2.4.3
Using spf-query 0.1.5 from https://github.com/trailofbits/spf-query.git (at master@6dac502)
Installing MysqL2 0.5.3 with native extensions
Using hot-glue 0.1.1
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/jason/.rvm/gems/ruby-2.6.6/gems/MysqL2-0.5.3/ext/MysqL2
/Users/jason/.rvm/rubies/ruby-2.6.6/bin/ruby -I /Users/jason/.rvm/rubies/ruby-2.6.6/lib/ruby/site_ruby/2.6.0 -r
./siteconf20210604-8580-1kmtwzs.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using MysqL_config at /opt/homebrew/bin/MysqL_config
-----
checking for MysqL.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_disABLED in MysqL.h... yes
checking for SSL_MODE_PREFERRED in MysqL.h... yes
checking for SSL_MODE_required in MysqL.h... yes
checking for SSL_MODE_VERIFY_CA in MysqL.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in MysqL.h... yes
checking for MysqL.net.vio in MysqL.h... yes
checking for MysqL.net.pvio in MysqL.h... no
checking for MysqL_ENABLE_CLEARTEXT_PLUGIN in MysqL.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in MysqL.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in MysqL.h... yes
checking for SERVER_QUERY_WAS_SLOW in MysqL.h... yes
checking for MysqL_OPTION_MULTI_STATEMENTS_ON in MysqL.h... yes
checking for MysqL_OPTION_MULTI_STATEMENTS_OFF in MysqL.h... yes
checking for my_bool in MysqL.h... no
-----
Don't kNow how to set rpath on your system,if MysqL libraries are not in path MysqL2 may not load
-----
-----
Setting libpath to /opt/homebrew/Cellar/MysqL/8.0.25_1/lib
-----
creating Makefile

current directory: /Users/jason/.rvm/gems/ruby-2.6.6/gems/MysqL2-0.5.3/ext/MysqL2
make "DESTDIR=" clean

current directory: /Users/jason/.rvm/gems/ruby-2.6.6/gems/MysqL2-0.5.3/ext/MysqL2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling MysqL2_ext.c
compiling result.c
compiling statement.c
linking shared-object MysqL2/MysqL2.bundle
ld: library not found for -lzstd
clang: error: linker command Failed with exit code 1 (use -v to see invocation)
make: *** [MysqL2.bundle] Error 1

make Failed,exit code 2

Gem files will remain installed in /Users/jason/.rvm/gems/ruby-2.6.6/gems/MysqL2-0.5.3 for inspection.
Results logged to /Users/jason/.rvm/gems/ruby-2.6.6/extensions/-darwin-20/2.6.0/MysqL2-0.5.3/gem_make.out

An error occurred while installing MysqL2 (0.5.3),and Bundler cannot continue.
Make sure that `gem install MysqL2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  MysqL2
jason@MacBook-Air  % 

我已经成功运行了 brew install MysqL ...如果我再次运行它会告诉我:

警告:MysqL 8.0.25_1 已经安装并且是最新的。 要重新安装 8.0.25_1,请运行: brew 重新安装MysqL

解决方法

尝试在 M1 上安装 mysql2 -v 0.4.1 时出现同样的错误
--已解决--

cd /opt/homebrew/bin
ls -la

我的路径是 -> /opt/homebrew/bin/zstd
你需要检查 zstd 从哪里链接

/opt/homebrew/Cellar/zstd/1.5.0/lib

zstd -> ../Cellar/zstd/1.5.0/bin/zstd
所以你需要得到 zstd lib 的路径,我是:

bundle config --local build.mysql2 "--with-ldflags=-L/opt/homebrew/Cellar/zstd/1.5.0/lib"
bundle install

gem list my                                                                                                 

*** LOCAL GEMS ***

mysql2 (0.4.10)

然后用一些魔法做经典组合

<!doctype html>

<html lang="en">

<head>
    <meta charset="utf-8">

    <title>The HTML5 Herald</title>
    <meta name="description" content="The HTML5 Herald">
    <meta name="author" content="SitePoint">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="https://momentjs.com/downloads/moment.js"></script>

</head>

<body>

    <div id="timetable" class="clearfix">
        <div class="timetable_content">
            <ul class="months clearfix">
                <li data-month="8" data-year="2015">August</li>
                <li data-month="9" data-year="2015">September</li>
                <li data-month="10" data-year="2015">October</li>
                <li data-month="11" data-year="2015">November</li>
                <li data-month="12" data-year="2015">December</li>
                <li data-month="1" data-year="2016">January</li>
                <li data-month="2" data-year="2016">February</li>
                <li data-month="3" data-year="2016">March</li>
                <li data-month="4" data-year="2016">April</li>
                <li data-month="5" data-year="2016">May</li>
                <li data-month="6" data-year="2016">June</li>
                <li data-month="7" data-year="2016">July</li>
            </ul>
            <ul class="timeslots">
                <li>
                    <span class="timeslot" data-date-start="2015-8-10" data-date-end="2015-10-12">BDO</span>
                    <span class="button"></span>
                </li>
                <li>
                    <span class="timeslot" data-date-start="2015-10-10" data-date-end="2016-2-12">BDO</span>
                    <span class="button"></span>
                </li>
                <li>
                    <span class="timeslot" data-date-start="2015-12-10" data-date-end="2016-2-12">BDO</span>
                    <span class="button"></span>
                </li>
                <li>
                    <span class="timeslot" data-date-start="2015-09-10" data-date-end="2016-7-12">BDO</span>
                    <span class="button"></span>
                </li>
                <li>
                    <span class="timeslot" data-date-start="2015-1-10" data-date-end="2015-3-12">BDO</span>
                    <span class="button"></span>
                </li>
            </ul>
        </div>
    </div>
</body>
<style type="text/css">
#timetable {
     width: 100%;
     height: auto;
     max-width: 768px;
     overflow-y: hidden;
     border: 1px solid #ccc;
}
 #timetable ul {
     padding-left: 0;
     list-style: none;
     margin: 0 0 0 0;
}
 #timetable .timetable_content {
     width: 1024px;
}
 .months {
     max-height: 50px;
     overflow: hidden;
}
 .months li {
     width: 110px;
     text-align: center;
     float: left;
     display: inline-block;
     border-right: 1px solid #ccc;
     padding: 1em;
}
 .timeslots li {
     border-top: 1px solid #ccc;
     padding: 0.5em;
}
 .timeslots .timeslot {
     background: lightblue;
     padding: 0.5em;
     display: inline-block;
}
 .clearfix:after {
     content: "";
     display: table;
     clear: both;
}

</style>
<script>
    (function() {

        var firstMonthsLiElWidth = $('.months li:first').innerWidth() + 1;

        var monthItems = 0;
        $('.months li').each(function(index) {
            monthItems += firstMonthsLiElWidth;
        });

        $('.months,.timeslots,.timetable_content').width(monthItems);
        console.log('<================== start slots =============================>');
        $('.timeslots li').each(function(index) {

            var element = $(this).children('span.timeslot'),startDate = element.data().dateStart,endDate = element.data().dateEnd,startMonthAmountDaysInMonth = moment(startDate,"YYYY-MM-DD").daysInMonth(),endMonthAmountDaysInMonth = moment(endDate,"YYYY-MM-DD").daysInMonth();

            var startDateMoment = moment(startDate,'YYYY-MM-DD');
            var endDateMoment = moment(endDate,'YYYY-MM-DD');
            var daysInPorject = endDateMoment.diff(startDateMoment,'days') // 1

            console.log('daysInPorject: ',daysInPorject);
            console.log('startMonthAmountDaysInMonth: ',startMonthAmountDaysInMonth);
            console.log('endMonthAmountDaysInMonth: ',endMonthAmountDaysInMonth);

            var startDateMonth = startDate.split("-")[1];
            var endDateMonth = endDate.split("-")[1];

            if (endDateMonth.indexOf('0') === 0) {
                endDateMonth = parseInt(endDateMonth,10);
            }

            if (startDateMonth.indexOf('0') === 0) {
                startDateMonth = parseInt(startDateMonth,10);
            }

            console.log('Months',startDateMonth + ' & ' + endDateMonth);

            var startDateEl = $(".months li[data-month='" + startDateMonth + "']").offset().left;
            var endDateEl = $(".months li[data-month='" + endDateMonth + "']").offset().left;
            var endDateElEnd = endDateEl + 110;
            var timeSlotWidth = endDateElEnd - startDateEl;
            var pixelsPerDay = (Math.round(firstMonthsLiElWidth / startMonthAmountDaysInMonth) * daysInPorject + 'px');

            console.log('Month start: ',startDateEl);
            console.log('pixelsPerDay: ',pixelsPerDay);
            console.log('Month end: ',endDateEl);
            console.log('Day end: ',endDateEl);
            console.log('Element length: ',timeSlotWidth);

            element.css('margin-left',startDateEl);
            element.width(pixelsPerDay);
            console.log('=============================');

        });

        console.log('Moment',moment("2012-02","YYYY-MM").daysInMonth());

    })();
</script>

</html>
,

这对我在 M1 上有用。

首先确保你已经安装了 mysql 并使用 Homebrew 安装了 openssl

brew install mysql
brew install openssl

然后手动设置这些值以安装 mysql2。我的 zstd 路径与 Octocats 相同,因此请务必按照他们的说明进行操作并适当更改 --with-ldflags 选项。

bundle config --local build.mysql2 "--with-opt-dir="$(brew --prefix openssl) --with-ldflags=-L/opt/homebrew/Cellar/zstd/1.5.0/lib""
,

感谢此处提供的所有帮助,没有一个解决方案对我有用,因为 bundler 无法正确读取配置,而是使用此处找到的所有信息并使用以下命令

gem install mysql2 -v '0.5.3' -- --with-opt-dir=$(brew --prefix openssl) --with-ldflags=-L/opt/homebrew/Cellar/zstd/1.5.0/lib

相应地更改您的 mysql1 版本