Skip to content

R/compilers can't find libintl.h on MacOS X

15 messages · Simon Urbanek, Gavin Simpson, Peter Dalgaard +3 more

#
Dear list

I seem to be running into a new issue after upgrading to R 4.5.0 that
seems related to this

* configure is now able to find an external libintl on macOS (the code
from an older GNU gettext distribution failed to try linking with the
macOS Core Foundation framework).

I'm pretty new to MacOS and I have installed R from homebrew, and
typically use the MacOS X binaries kindly provided by CRAN. However,
for a couple of packages I make extensive use of, I want to make use
of openMP, and so I have been following the excellent instructions on
the mac.r-project.org pages to install the relevant fortran compiler
and libomp.

Specifically, I am trying to in compile the latest mgcv sources with
openMP support. I have been doing this successfully for some time for
the 4.3 and 4.4 releases of R. But after upgrading to R 4.5.0,
compiling mgcv now throws an compilation error

In file included from magic.c:27:
./general.h:4:10: fatal error: 'libintl.h' file not found
    4 | #include <libintl.h>
      |          ^~~~~~~~~~~

(The full compile log is included below if neccessary.)

I do have gettext installed and I do have libintl.h on my system

% find /opt -name "libintl.*" -print
/opt/homebrew/include/libintl.h
/opt/homebrew/lib/libintl.dylib
/opt/homebrew/lib/libintl.8.dylib
/opt/homebrew/lib/libintl.a
/opt/homebrew/Cellar/gettext/0.24/include/libintl.h
/opt/homebrew/Cellar/gettext/0.24/lib/libintl.dylib
/opt/homebrew/Cellar/gettext/0.24/lib/libintl.8.dylib
/opt/homebrew/Cellar/gettext/0.24/lib/libintl.a

My $PATH is

% print $PATH
/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/X11/bin:/usr/local/laps:/usr/local/munki:/usr/local/munkireport:/Applications/quarto/bin:/Users/au690221/.local/bin:/Users/au690221/.local/bin

I have edited ./src/Makevars in mgcv's sources  such that it reads

% cat ./repo/src/Makevars
PKG_LIBS =  $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)

PKG_LIBS += -lomp
PKG_CPPFLAGS = -Xclang -fopenmp
## *Both* the above must be *uncommented* for release

#PKG_CFLAGS = -g -O0 -Wall -pedantic $(SHLIB_OPENMP_CFLAGS)
## Actually it now seems that you need to reset optimization flag in
## cd /usr/local/lib/R/etc/
## sudo pico Makeconf
## This file can add flags but not modify what's in the above!
## `#' out previous line for release (but not without uncommenting openMP)

But I have tried it with the final pair of PKG_LIBS definitions that
add omp support commented out also.

My system details are
R version 4.5.0 (2025-04-11)
Platform: aarch64-apple-darwin20
Running under: macOS Sequoia 15.4.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;
 LAPACK version 3.12.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Copenhagen
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] compiler_4.5.0

and

% clang -v
Apple clang version 17.0.0 (clang-1700.0.13.3)
Target: arm64-apple-darwin24.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

(So I have installed LLVM 18.1.8 from https://mac.r-project.org/openmp/ )

I suspect I will need to solve this by adding the homebrew lib
location to my LD_PATH or similar, but I'm not very familiar with this
process in general and especially so on MacOS X.

I'd appreciate any help with resolving this issue.

TIA

Gavin

% R CMD INSTALL mgcv_1.9-3.tar.gz
* installing to library ?/Users/au690221/Library/R/arm64/4.5/library?
* installing *source* package ?mgcv? ...
** this is package ?mgcv? version ?1.9-3?
** using staged installation
** libs
using C compiler: ?Apple clang version 17.0.0 (clang-1700.0.13.3)?
using SDK: ?MacOSX15.4.sdk?
clang -arch arm64
-I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG
-I/opt/R/arm64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -c
coxph.c -o coxph.o
clang -arch arm64
-I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG
-I/opt/R/arm64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -c
davies.c -o davies.o
clang -arch arm64
-I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG
-I/opt/R/arm64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -c
discrete.c -o discrete.o
clang -arch arm64
-I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG
-I/opt/R/arm64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -c
gdi.c -o gdi.o
clang -arch arm64
-I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG
-I/opt/R/arm64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -c
init.c -o init.o
clang -arch arm64
-I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG
-I/opt/R/arm64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -c
magic.c -o magic.o
In file included from magic.c:27:
./general.h:4:10: fatal error: 'libintl.h' file not found
    4 | #include <libintl.h>
      |          ^~~~~~~~~~~
1 error generated.
make: *** [magic.o] Error 1
ERROR: compilation failed for package ?mgcv?
* removing ?/Users/au690221/Library/R/arm64/4.5/library/mgcv?
* restoring previous ?/Users/au690221/Library/R/arm64/4.5/library/mgcv?
#
Looks like you'd be better off with libintl from Simon's gettext binaries on mac.r-project.org. The compiler is looking for include files in /opt/R/arm64/include and not /opt/homebrew/include.

-pd

  
    
#
Gavin,

there are few issues here with different possible solutions.

In general, you cannot mix R from Homebrew and CRAN - they use different toolchains and libraries so you have to pick one.


1) Despite what you said, what you are showing below is output from CRAN R, so one option (which I'd recommend) is to go the CRAN way. First, simply remove (or rename) /opt/homebrew so it doesn't break things (may or may not be necessary). Then the error you see is because mgcv seems to require gettext so install it from https://mac.r-project.org/bin/ - either follow the instructions there (which will work even from more complex cases) or in your case you can simply use

curl https://mac.r-project.org/bin/darwin20/arm64/gettext-0.22.5-darwin.20-arm64.tar.xz | tar xz -C /

(if you don't have write permissions in /opt/R either run "sudo chown -R $USER /opt/R" or put "sudo" before the tar above).

Once you got whatever you needed compiled you can rename /opt/homebrew back since we only need to remove it for compilation. The above works, because R itself already has the necessary static library built-in (as it uses it itself) so all you need are the gettext headers to appease mgcv.


2) If you want to go fully the Homebrew way then you have to make sure you are picking up R from Homebrew and not CRAN. Then you cannot use CRAN binaries, you are entirely on your own since we don't support that setup, so I do NOT recommend it, but it's possible. Typically, that requires you to install the full compiler toolchain from Homebrew as well as well compiling all R packages from sources. In that scenario you don't use anything from mac.R-project.org but instead rely fully on Homebrew. This includes OpenMP, because the compilers in Homebrew are not from Apple so they use their own OpenMP.


3) If the mgcv package on CRAN does not come with OpenMP support then I'd contact the maintainers and ask them why they don't enable it. Packages that benefit significantly from OpenMP typically enable it for their CRAN binaries (good example is data.table), so if it is not enabled it may mean that the authors don't recommend it or there is no significant benefit.


Cheers,
Simon
#
Thanks Simon, some comments to selected aspects
That's what Homebrew installs (now? perhaps it was different in the
past?), I didn't install R by hand and certainly got this R from
Homebrew, and reading the ruby script it runs, it is grabbing the
latest binary from CRAN.

I think in the short term I'll try this route of renaming
/opt/homebrew out of the way temporarily just to get working again
with mgcv.
The CRAN binary certainly doesn't work with omp out of the box on Mac
(Note, this is using the package shipped with R, not the one I was
trying to compile, and I just nuked mgcv on my system and reinstalled
from the CRAN binary to the same effect):
[1] FALSE

OpenMP is the way Simon enables parallel computation of GAMs in
`gam()` and `bam()` - which is kind of the point of at least `bam()`.

./src/Makevars does have

PKG_LIBS =  $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)

which includes openMP-related things, but this seemingly(?) isn't
sufficient to get it to work on MacOS X as with the CRAN binary of
mgcv's test for working omp returns FALSE, and mgcv never uses more
than a single thread - which is why I was trying to compile the
package myself in the first place. FWIW, glmmTMB::omp_check() is also
`FALSE` on my machine, so something seems to be off broadly.

I'll email Simon after investigating how data.table does things so I
have something concrete to suggest to him - that said enabling openmp
seems very convoluted if the configure script in data.table is
anything to go by, which I presume is important because even though
*I* don't need to do very much on my computer to enable compilation
using openmp, getting it to work on other systems seems decidedly
non-trivial in general.

I was perhaps operating under the false assumption that openMP wasn't
supported *at all* on Mac because of the issue with Apple's clang -
which is why I went down this route in the first place.

Going entirely with CRAN's R for Mac seems to resign a user to having
to manage the rest of their software on their machine by hand. If I
understand correctly then, I'm likely to run into problems using
CRAN's R binary alongside a package I compile manually using libraries
I have installed via homebrew (i.e. gettext, which I note in homebrew
is a couple of versions ahead of the one in your recipes, even if it
is the same gnu gettext)?

This is not meant as a complaint; I am very grateful that the binaries
exist - it has been quite the revelation from my decades on Linux
where I endured hours of update time at each new R release recompiling
all the R packages I had been using.

I am however revealing my naivety regarding the Mac platform and
trying to understand what is best for me longer-term - I really don't
want to have to manually install and maintain all the other software I
need besides R. From what you are saying, it seems I'll need to go
back to my Linux-like days and install R and R packages from sources,
and use a package manager to manage installing the needed libraries
and tools.

Anyway, thanks for the comments and suggestions.

When I get chance, I'll see if the same opm issues persist if I remove
all the homebrew stuff and retry with CRAN's mac binary directly and
then follow back up here and also with the respective package
maintainers.

All the best and "God P?ske" as they say in my parts (Happy Easter)

Gavin
On Sat, 19 Apr 2025 at 23:40, Simon Urbanek <simon.urbanek at r-project.org> wrote:

  
    
3 days later
#
I am getting the same missing libintl.h error on my MacOS Github action. 
  What do you recommend as the fix?  My current script is here:

 
https://github.com/dmurdoch/parseLatex/blob/main/.github/workflows/R-CMD-check.yaml

I've tried a couple of things (install using brew:  fails because it is 
already installed, but R isn't looking there; install using the curl 
command below:  fails because of permissions.

Duncan Murdoch
On 2025-04-19 5:40 p.m., Simon Urbanek wrote:
#
If you are using Simon's tools and libs, just install gettext and make sure that CPPFLAGS includes  
-I/opt/R/x86_64/include and LDFLAGS -L/opt/R/x86_64/lib (mutatis mutandis for ARM, of course).

-pd

  
    
#
It's the "just install gettext" part that's giving me trouble.  How do 
you do that in a Github action?

Duncan Murdoch
On 2025-04-23 1:04 p.m., peter dalgaard wrote:
#
For the latter - did you forget sudo in front of the tar?

Without exact output we can only guess ...

Cheers,
Simon
#
I didn't use sudo, but adding it doesn't help.

Here's the latest failed run:

https://github.com/dmurdoch/parseLatex/actions/runs/14634872157/job/41063801330

It fails to create opt/R/arm64.  I also tried x86_64, with similar results.

Duncan Murdoch
On 2025-04-23 4:17 p.m., Simon Urbanek wrote:
#
ICBW, but you seem to be sudo-ing the curl but not the tar? 

Maybe curl ..... | sudo tar ... ?

- Peter

  
    
#
That's it!  It's the tar that needs the sudo.

I may switch to using the R script method to avoid hard-coding 
architecture and version, but I've got something that works now.

Thanks!

Duncan Murdoch
On 2025-04-24 4:47 a.m., peter dalgaard wrote:
#
To finish this thread, here's the action I ended up with:

       - name: Install dependencies on MacOS
         if: runner.os == 'macOS'
         run: |
           sudo Rscript -e 
"source('https://mac.R-project.org/bin/install.R'); install.libs('gettext')"


This needs to come after R has been set up so that Rscript will be 
available.

Duncan Murdoch
On 2025-04-24 5:19 a.m., Duncan Murdoch wrote:
#
Hi Gavin,

If you want to use gettext from Homebrew, you need to make sure the
compiler include paths are set up correctly. As a reference, R
installations from Homebrew use (among other tweaks, but I think these
are the most relevant):

    CPPFLAGS = -I/opt/homebrew/opt/gettext/include
-I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/xz/include
-I/opt/homebrew/include
    LDFLAGS = -L/opt/homebrew/opt/gettext/lib
-L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/xz/lib
-L/opt/homebrew/lib

in their etc/Makeconf, so you probably need something similar in your
own Makevars file (or wherever else is appropriate for you to set
these).

You might also be able to use `-I/opt/homebrew/include`, but that's a
bit more dangerous since (depending on what you've installed with
Homebrew) you could end up unintentionally shadowing certain header
files that were expected to be found in other locations. Adding `-H`
to CPPFLAGS can be useful in this scenario; it will tell the compiler
to dump the include paths used when resolving headers.

Caveat emptor and all that, but I've had success using CRAN R releases
on macOS with Homebrew-installed libraries. The main wrinkles come
when /usr/local/include gets full of "junk" that messes up compiler
header searches, but that's less of an issue on arm64 since Homebrew
stuff gets placed in /opt/homebrew, and /opt/homebrew/include is not
added to the compiler include search paths by default.

Best,
Kevin

On Wed, Apr 23, 2025 at 11:27?PM Duncan Murdoch
<murdoch.duncan at gmail.com> wrote:
#
I don't know about Gavin, but all I wanted was to be able to install my 
package from source on Github without an error.

Duncan Murdoch
On 2025-04-24 12:18 p.m., Kevin Ushey wrote:
#
I also got that missing libintl.h file issue on Mac Silicon. Instead of messing up with Homebrew and its non-standard directories, I installed gettext from Simon Urbanek recipies. This is really simple and libintl.h is then automatically found by the compiler without requiring special compilation flags. You need to start R in sudo mode.

sudo R

Then in R:

source("https://mac.R-project.org/bin/install.R")
install.libs("gettext")

And that?s it. No more libintl.h problem.
Best,

Philippe
..............................................<?}))><........
 ) ) ) ) )
( ( ( ( (    Prof. Philippe Grosjean
 ) ) ) ) )
( ( ( ( (    Numerical Ecology
 ) ) ) ) )   Mons University, Belgium
( ( ( ( (
..............................................................