I believe this is because OSX changed their regular expression libraries somewhere after 10.7, specifically as it relates to the function regcomp() which gained an alternate version, regcomp_l() sometime after 10.7.
Per this link: https://www.unix.com/man-page/osx/3/regcomp/
The regex implementation in Mac OS X 10.8 and later is based on a heavily modified subset of
TRE (http://laurikari.net/tre/). This provides improved performance, better conformance and
additional features. However, both API and binary compatibility have been maintained with
previous releases, so binaries built on previous releases should work on 10.8 and later, and
binaries built on 10.8 and later should be able to run on previous releases (as long as none
of the new variants or new features are used.
If you look at source code for OSX 10.8, https://opensource.apple.com/release/mac-os-x-1084.html , and download LibC you will find the TRE source code, and regcomp_l is inside of Libc-825.26/regex/TRE/lib/regcomp.c
If you compare this with OSX 10.7 source code, https://opensource.apple.com/release/mac-os-x-1075.html , you will see that 10.7 is just using old fashioned FreeBSD regex, Libc-763.13/regex/regcomp-fbsd.c which does not contain the ‘regcomp_l’ variation.
Now, if you look at the sauce code for rust Cargo, https://github.com/rust-lang/cargo, there is no direct call to regcomp_l or even regcomp so it may be using it inadvertently through a dependency library its using. So I notice it’s using the ‘regex’ crate (i think?) but the https://github.com/rust-lang/regex crate also doesnt call regcomp. Maybe https://github.com/rust-lang/libc ? nope. OK what about https://github.com/rust-lang/regex-syntax ? OK im striking out…
OK so if you actually do something like cd /tmp; git clone https://github.com/rust-lang/cargo ; cd cargo; cargo build ; you can get an idea of all the crates it pulls down. It stores them under $HOME/.cargo/registry/src/github.com-…/ so… if we run
grep -r regcomp_l ~/.cargo/registry/src
we have a hit
don@oysters:/tmp/cargo$ grep -r regcomp_l ~/.cargo/registry/src/github.com-1ecc6299db9ec823/
/home/don/.cargo/registry/src/github.com-1ecc6299db9ec823/libgit2-sys-0.7.6/libgit2/src/CMakeLists.txt:CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
/home/don/.cargo/registry/src/github.com-1ecc6299db9ec823/libgit2-sys-0.7.6/libgit2/src/unix/posix.h: return regcomp_l(preg, pattern, cflags, (locale_t) 0);
I can cut that down a bit to make it clearer
~$ grep -r regcomp_l ~/.cargo/registry/src
...libgit2/src/CMakeLists.txt:CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
...libgit2/src/unix/posix.h: return regcomp_l(preg, pattern, cflags, (locale_t) 0);
So basically there is one line in one file in one package in this whole tree that is calling regcomp_l, but here is the thing.
its not even using the locale feature. its forcing it to 0
Remember our old friend at unix.com, the manpage for regcomp https://www.unix.com/man-page/osx/3/regcomp/ lets just compare the function signatures of ‘old’ regcomp and ‘new and improved’ regcomp_l
int regcomp_l(regex_t *restrict preg,
const char *restrict pattern,
int regcomp(regex_t *restrict preg,
const char *restrict pattern,
We can see the only difference in the parameters is ‘locale_t restrict’ which in Cargo’s dependency libgit2-sys is simply being set to 0.
I don’t know enough to say if this call to regcomp_l() can simply be changed to ‘regcomp()’ without any effects, as it would take a good bit of testing, but… lets look at this package in question some more. It is called libgit2-sys. Now lets look at how it builds on linux, ubuntu 18. After running cargo build, i can run a grep:
don@oysters:/tmp/cargo$ grep -ri regcomp .
There are a ton of hits, but basically what they are saying is stuff like this, from a CMake error log:
Determining if the regcomp_l exist failed with the following output:
So on linux ubuntu 18, we apparently are building without regcomp_l ? Like I said it would take a lot more testing to see how much an impact use of regcomp_l actually has on cargo.