Installing nio4r via brew install throws an error on macOS catalina
Asked Answered
F

5

7

I understand that this issue has a ton of answers on stack overflow (and other sites) but none of them seem to work for me. Here is where the issue arises. When I tried to run my server, this error popped up:

Could not find nio4r-1.2.1 in any of the sources

So I ran bundle install which threw this error:

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
Make sure that `gem install nio4r -v '1.2.1' --source 'https://rubygems.org/'` succeeds before bundling.

When I do that, this happens:

    ERROR: Failed to build gem native extension.

    current directory: /Users/admin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/nio4r-1.2.1/ext/nio4r
/Users/admin/.rbenv/versions/2.3.1/bin/ruby -r ./siteconf20201129-28103-lmj40x.rb extconf.rb
checking for unistd.h... yes
checking for rb_thread_blocking_region()... no
checking for rb_thread_call_without_gvl()... yes
checking for sys/select.h... yes
checking for poll.h... yes
checking for sys/epoll.h... no
checking for sys/event.h... yes
checking for sys/queue.h... yes
checking for port.h... no
checking for sys/resource.h... yes
creating Makefile

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/admin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-18/2.3.0-static/nio4r-1.2.1/mkmf.log

current directory: /Users/admin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/nio4r-1.2.1/ext/nio4r
make "DESTDIR=" clean

current directory: /Users/admin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/nio4r-1.2.1/ext/nio4r
make "DESTDIR="
compiling monitor.c
compiling nio4r_ext.c
In file included from nio4r_ext.c:7:
./../libev/ev.c:487:48: warning: '/*' within block comment [-Wcomment]
/*#define MIN_INTERVAL  0.00000095367431640625 /* 1/2**20, good till 2200 */
                                               ^
./../libev/ev.c:1829:31: warning: 'extern' variable has an initializer [-Wextern-initializer]
  EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
                              ^
In file included from nio4r_ext.c:7:
In file included from ./../libev/ev.c:2694:
./../libev/ev_poll.c:110:18: warning: expression result unused [-Wunused-value]
        assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3100:12: warning: expression result unused [-Wunused-value]
  assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3103:14: warning: expression result unused [-Wunused-value]
    assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3113:16: warning: expression result unused [-Wunused-value]
      assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3114:16: warning: expression result unused [-Wunused-value]
      assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i])));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3115:16: warning: expression result unused [-Wunused-value]
      assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i]))));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3126:16: warning: expression result unused [-Wunused-value]
      assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3144:14: warning: expression result unused [-Wunused-value]
    assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3157:24: warning: expression result unused [-Wunused-value]
              assert (("libev: io watcher list contains a loop", w != w2));
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3161:20: warning: expression result unused [-Wunused-value]
          assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3162:20: warning: expression result unused [-Wunused-value]
          assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3344:24: warning: expression result unused [-Wunused-value]
              assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.));
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3406:24: warning: expression result unused [-Wunused-value]
              assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3551:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
./../libev/ev.c:3568:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3737:9: error: implicit declaration of function 'rb_thread_call_without_gvl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        rb_thread_call_without_gvl(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
        ^
./../libev/ev.c:3752:22: warning: expression result unused [-Wunused-value]
            assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3926:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_io_start called with negative fd", fd >= 0));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3927:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3936:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3951:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3971:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:3999:14: warning: expression result unused [-Wunused-value]
    assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:4061:16: warning: expression result unused [-Wunused-value]
      assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:4093:14: warning: expression result unused [-Wunused-value]
    assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:4130:12: warning: expression result unused [-Wunused-value]
  assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:4133:12: warning: expression result unused [-Wunused-value]
  assert (("libev: a signal must not be attached to two different loops",
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:4251:12: warning: expression result unused [-Wunused-value]
  assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
In file included from nio4r_ext.c:7:
./../libev/ev.c:4830:14: warning: expression result unused [-Wunused-value]
    assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
30 warnings and 1 error generated.
make: *** [nio4r_ext.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/admin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/nio4r-1.2.1 for inspection.
Results logged to /Users/admin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-18/2.3.0-static/nio4r-1.2.1/gem_make.out

The things I have tried so far are:

  1. Updating xcode and accepting terms. - sudo xcodebuild -license accept
  2. Installing nio4r using this command - bundle config build.nio4r --with-cflags="-std=c99" then gem install nio4r -v '1.2.1' -- with-cflags="-std=c99"
  3. Tried installing libgmp3-dev for mac via brew install gmp
  4. There was a stack answer which mentioned postgres file port.h which needed to be deleted. That didn't work for me either.

I am running Mac OS Catalina(Recently upgraded). When I upgraded I also had to upgrade my Xcode - Version 12.2 (12B45b) I am running ruby version 2.3.1

If anyone has experienced this after catalina upgrade and has a solution, please help. I'd be happy to provide more info if needed.

Farias answered 30/11, 2020 at 5:36 Comment(0)
U
44

You can disable this error with option -Wno-error=implicit-function-declaration

So try this

gem install nio4r -v '1.2.1' -- --with-cflags="-Wno-error=implicit-function-declaration"

You can add the same option for bundler:

bundle config --local build.nio4r --with-cflags="-Wno-error=implicit-function-declaration"
# and then
bundle install
Unleash answered 30/11, 2020 at 12:27 Comment(4)
The command worked, but on bundle install I still get the other errors for some reason. Success message: ``` Building native extensions with: '--with-cflags=-Wno-error=implicit-function-declaration' This could take a while... Successfully installed nio4r-1.2.1 Parsing documentation for nio4r-1.2.1 Done installing documentation for nio4r after 0 seconds 1 gem installed ```Farias
@Farias If I get you right, you get same error but when using bundle. You can add the same option for bundle: bundle config --local build.nio4r --with-cflags="-Wno-error=implicit-function-declaration"Unleash
That worked!! Thank you, omg! So the same error occurred for another gem and I used bundle config on that gem too. Once it ran, i was able to bundle install and everything was green :) One question for you - What is the wno-error doing and what does that command do? I am trying to understand the error and the solution.Farias
These options are for C compiler that is required for building some gems. Authors of gems could use older compiler versions or Apple could updated the built-in compiler. It could lead some warnings to become errors. So if you using older versions of gems, you can get those error because they were written in times when compiler was less strict.Unleash
U
12

I had to use

gem install nio4r -v '2.5.8' --source 'https://rubygems.org/' -- --with-cflags="-Wno-error=implicit-function-declaration -Wno-error=incompatible-function-pointer-types"
Building native extensions with: '--with-cflags=-Wno-error=implicit-function-declaration -Wno-error=incompatible-function-pointer-types'
This could take a while...
Successfully installed nio4r-2.5.8
Parsing documentation for nio4r-2.5.8
Installing ri documentation for nio4r-2.5.8
Done installing documentation for nio4r after 0 seconds
1 gem installed

23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:11:05 PDT 2024; root:xnu-10063.101.17~1/RELEASE_X86_64 x86_64

Uxoricide answered 3/5 at 21:54 Comment(2)
This works for me. I am on M1 Sonoma 14.5.Stereopticon
Worked for me on M3 Pro Sonoma 14.5Legman
T
6

I'm on a M1 Mac running Sonoma 14.4 and ruby 2.7.5.

I had to add more to the cflags to get nio4r to install:

bundle config --local build.nio4r --with-cflags="-Wno-error=implicit-function-declaration -Wno-error=incompatible-function-pointer-types"

Toritorie answered 21/3 at 19:18 Comment(2)
Works on M3 too.Schulein
Tried this on Ruby 2.7.7 installed via rbenv on macOS Sonoma 14.4.1 and it failed for nio4r 2.5.8. This is an Macboko Pro M3. Any ideas?Haddix
F
1

This issue was fixed in nio4r v2.5.9 (ref).

I just faced this issue and fixed it by updating the gem version.

(Relevant StackOverflow answer: https://mcmap.net/q/669405/-unable-to-bundle-install-nio4r-on-a-new-mac-m3)

Felonry answered 12/8 at 13:6 Comment(0)
M
-1

Over here I'm running ruby 3.1.3 on a new install of Ubuntu 24.04 LTS. The rails gem build is failing on the nio4r gem (2.7.3).

The gem's mkmf.log lists lots of "undefined reference" failures - the variables all follow a '_@GLIBC_PRIVATE' format.

For example: '__libc_siglongjmp@GLIBC_PRIVATE'.

I could attempt to duplicate @anthony_sallows' fix listed above, but the -Wflags list in the compiler is pretty extensive. I'm not sure of a next move.

Manheim answered 25/5 at 20:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.