How to stop qmake from emiting certain flag - c++

I am using qmake on OSX with clang. I try to use c++11 with the following flags in the .pro file
QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++
However qmake generates the follow flag in the makefile
CXXFLAGS = ... -mmacosx-version-min=10.5 ...
This flag causes clang to raise an error
invalid deployment target for -stdlib=libc++ (requires OS X 10.7 or later)
Changing the flag to 10.7 fixed the problem
CXXFLAGS = ... -mmacosx-version-min=10.7 ...
Is there any way to stop qmake from emitting this flag in the makefile?

you can install other compiler for example gcc4.7.
There are few easy ways macports:
1. http://www.macports.org/install.php
2. Applications > Utilities > Terminal
3. In terminal: sudo port selfupdate
4. sudo port install gcc47
5. Now add new compiler in Qt (Projects tab)
6. In profile change QMAKE_CXXFLAGS += -std=c++0x
Other way brew:
1. Applications > Utilities > Terminal
2. In terminal: ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
3. In terminal: brew doctor
4. In terminal: brew install gcc
5. Now add new compiler in Qt (Projects tab)
6. In profile change QMAKE_CXXFLAGS += -std=c++0x

Specify the target version via QMAKE_MACOSX_DEPLOYMENT_TARGET, e.g.:
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
If you would totally get rid of the flag, you would get some message like:
ld: warning: -macosx_version_min not specified, assuming 10.8
So, your compiler will automatically add it anyway.
That flag is there for a reason. It's written into your binary. And when you try to load that binary on an older system, it will abort.
Now, if you really want MacOSX 10.5 compatibility, you cannot use -stdlib=libc++ because that libc++ is simply not available before MacOSX 10.7.
If you need libc++ (e.g. some C++11 features) + you want to make it work on <10.7, that's not so easy. See here for a related question.

Related

Configuring compilers on Mac M1 (Big Sur, Monterey) for Rcpp and other tools

I'm trying to use packages that require Rcpp in R on my M1 Mac, which I was never able to get up and running after purchasing this computer. I updated it to Monterey in the hope that this would fix some installation issues but it hasn't. I tried running the Rcpp check from this page but I get the following error:
> Rcpp::sourceCpp("~/github/helloworld.cpp")
ld: warning: directory not found for option '-L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0'
ld: warning: directory not found for option '-L/opt/R/arm64/gfortran/lib'
ld: library not found for -lgfortran
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [sourceCpp_4.so] Error 1
clang++ -arch arm64 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I../inst/include -I"/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/RcppArmadillo/include" -I"/Users/afredston/github" -I/opt/R/arm64/include -fPIC -falign-functions=64 -Wall -g -O2 -c helloworld.cpp -o helloworld.o
clang++ -arch arm64 -std=gnu++14 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/opt/R/arm64/lib -o sourceCpp_4.so helloworld.o -L/Library/Frameworks/R.framework/Resources/lib -lRlapack -L/Library/Frameworks/R.framework/Resources/lib -lRblas -L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0 -L/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
Error in Rcpp::sourceCpp("~/github/helloworld.cpp") :
Error 1 occurred building shared library.
I get that it can't "find" gfortran. I installed this release of gfortran for Monterey. When I type which gfortran into Terminal, it returns /opt/homebrew/bin/gfortran. (Maybe this version of gfortran requires Xcode tools that are too new—it says something about 13.2 and when I run clang --version it says 13.0—but I don't see another release of gfortran for Monterey?)
I also appended /opt/homebrew/bin: to PATH in R so it looks like this now:
> Sys.getenv("PATH")
[1] "/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Library/TeX/texbin:/Applications/RStudio.app/Contents/MacOS/postback"
Other things I checked:
Xcode command line tools is installed (which clang returns /usr/bin/clang).
Files ~/.R/Makevars and ~/.Renviron don't exist.
Here's my session info:
R version 4.1.1 (2021-08-10)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Monterey 12.1
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.1.1 tools_4.1.1 RcppArmadillo_0.10.7.5.0
[4] Rcpp_1.0.7
Background
Currently (2023-02-20), CRAN builds R 4.2 binaries for Apple silicon using Apple Clang from Command Line Tools for Xcode 13.1 and using an experimental fork of GNU Fortran 12.
If you obtain R from CRAN (i.e., here), then you need to replicate CRAN's compiler setup on your system before building R packages that contain C/C++/Fortran code from their sources (and before using Rcpp, etc.). This requirement ensures that your package builds are compatible with R itself.
A further complication is the fact that Apple Clang doesn't support OpenMP, so you need to do even more work to compile programs that make use of multithreading. You could circumvent the issue by building R itself, all R packages, and all external libraries from sources with LLVM Clang, which does support OpenMP, but that approach is onerous and "for experts only".
There is another approach that has been tested by a few people, including Simon Urbanek, the maintainer of R for macOS. It is experimental and also "for experts only", but it works on my machine and is much simpler than learning to build R and other libraries yourself.
Instructions for obtaining a working toolchain
Warning: These come with no warranty and could break at any time. Some level of familiarity with C/C++/Fortran program compilation, Makefile syntax, and Unix shells is assumed. Everyone is encouraged to consult official documentation, which is more likely to be maintained than answers on SO. As usual, sudo at your own risk.
I will try to address compilers and OpenMP support at the same time. I am going to assume that you are starting from nothing. Feel free to skip steps you've already taken, though you might find a fresh start helpful.
I've tested these instructions on a machine running Big Sur, but they should also work on Monterey and Ventura.
Download an R 4.2 binary from CRAN here and install. Be sure to select the binary built for Apple silicon.
Run
$ sudo xcode-select --install
in Terminal to install the latest release version of Apple's Command Line Tools for Xcode, which includes Apple Clang. You can obtain earlier versions from your browser here. However, the version that you install should not be older than the one that CRAN used to build your R binary.
Download the GNU Fortran binary provided here and install by unpacking to root:
$ curl -LO https://mac.r-project.org/tools/gfortran-12.0.1-20220312-is-darwin20-arm64.tar.xz
$ sudo tar xvf gfortran-12.0.1-20220312-is-darwin20-arm64.tar.xz -C /
$ sudo ln -sfn $(xcrun --show-sdk-path) /opt/R/arm64/gfortran/SDK
The last command updates a symlink inside of the installation so that it points to the SDK inside of your Command Line Tools installation.
Download an OpenMP runtime suitable for your Apple Clang version here and install by unpacking to root. You can query your Apple Clang version with clang --version. For example, I have version 1300.0.29.3, so I did:
$ curl -LO https://mac.r-project.org/openmp/openmp-12.0.1-darwin20-Release.tar.gz
$ sudo tar xvf openmp-12.0.1-darwin20-Release.tar.gz -C /
After unpacking, you should find these files on your system:
/usr/local/lib/libomp.dylib
/usr/local/include/ompt.h
/usr/local/include/omp.h
/usr/local/include/omp-tools.h
Add the following lines to $(HOME)/.R/Makevars, creating the file if necessary.
CPPFLAGS += -I/usr/local/include -Xclang -fopenmp
LDFLAGS += -L/usr/local/lib -lomp
Test that you are able to use R to compile a C or C++ program with OpenMP support while linking relevant libraries from the GNU Fortran installation (indicated by the -l flags in the output of R CMD CONFIG FLIBS).
The most transparent approach is to use R CMD SHLIB directly. In a temporary directory, create an empty source file omp_test.c and add the following lines:
#ifdef _OPENMP
# include <omp.h>
#endif
#include <Rinternals.h>
SEXP omp_test(void)
{
#ifdef _OPENMP
Rprintf("OpenMP threads available: %d\n", omp_get_max_threads());
#else
Rprintf("OpenMP not supported\n");
#endif
return R_NilValue;
}
Compile it:
$ R CMD SHLIB omp_test.c $(R CMD CONFIG FLIBS)
Then call the compiled C function from R:
$ R -e 'dyn.load("omp_test.so"); invisible(.Call("omp_test"))'
OpenMP threads available: 8
If the compiler or linker throws an error, or if you find that OpenMP is still not supported, then one of us has made a mistake. Please report any issues.
Note that you can implement the same test using Rcpp, if you don't mind installing it:
library(Rcpp)
registerPlugin("flibs", Rcpp.plugin.maker(libs = "$(FLIBS)"))
sourceCpp(code = '
#ifdef _OPENMP
# include <omp.h>
#endif
#include <Rcpp.h>
// [[Rcpp::plugins(flibs)]]
// [[Rcpp::export]]
void omp_test()
{
#ifdef _OPENMP
Rprintf("OpenMP threads available: %d\\n", omp_get_max_threads());
#else
Rprintf("OpenMP not supported\\n");
#endif
return;
}
')
omp_test()
OpenMP threads available: 8
References
Everything is a bit scattered:
R Installation and Administration manual [link]
Writing R Extensions manual [link]
R for macOS Developers web page [link]
I resolved this issue by adding a path to the homebrew installation of gfortran to my ~/.R/Makevars following these instructions: https://pat-s.me/transitioning-from-x86-to-arm64-on-macos-experiences-of-an-r-user/#gfortran
I just avoided the issue until MacOS had things working more smoothly. so I either Windows Developer Virtual Machine (VM) or run my code development in another environment. I'm not too impressed with the updated and "faster" chipset, but that it doesn't work with much. Slow to implement and work-a-rounds often are a must.
Tested the following process for making multithread data.table work in a M2 MacBook Pro (macOS Monterey)
Steps are mostly the same with this answer by the user inferator.
Download and install R from CRAN
Download and install RStudio with developer tools
Run the following commands in terminal to install OpenMP
curl -O https://mac.r-project.org/openmp/openmp-12.0.1-darwin20-Release.tar.gz
sudo tar fvxz openmp-12.0.1-darwin20-Release.tar.gz -C /
Add compiler flags to connect clan w/ OpenMP. In terminal, write the following:
cd ~
mkdir .R
nano .R/Makevars
Inside the opened Makevars file paste the following lines. Once finished, hit command+O and then Enter to save. Do a command+X to close the editor.
CPPFLAGS += -Xclang -fopenmp
LDFLAGS += -lomp
Download and run the installer for gfortran by downloading gfortran-ARM-12.1-Monterey.dmg from the respective GitHub repo
This concludes the steps regarding enabling OpenMP and (hopefully) Rcpp in R under a M2 chip system.
Now, for testing that everything works with data.table I did the following
Open RStudio and run
install.packages("data.table", type = "source")
If everything is done correctly, the package should compile without any errors and return the following when running getDTthreads(verbose = TRUE):
OpenMP version (_OPENMP) 201811
omp_get_num_procs() 8
R_DATATABLE_NUM_PROCS_PERCENT unset (default 50)
R_DATATABLE_NUM_THREADS unset
R_DATATABLE_THROTTLE unset (default 1024)
omp_get_thread_limit() 2147483647
omp_get_max_threads() 8
OMP_THREAD_LIMIT unset
OMP_NUM_THREADS unset
RestoreAfterFork true
data.table is using 4 threads with throttle==1024. See ?setDTthreads.
[1] 4

Macports on OSX 10.11 - compile "older" ports with -stdlib=libstdc++ [duplicate]

In OSX 10.9 the default -stdlib option for clang++ is libc++, so that's what Macport uses when building packages.
Is there any way to tell Macports to use libstdc++ instead?
In particular I would like to build OpenCV through Macports so it's using libstdc++, but I imagine I'll run into a need to do so for other packages as well
The option is simply: -stdlib=libstdc++
If you need finer control over the build process for various ports, you can always set variables like:
CXX = "clang -std=c++11 -stdlib=libc++, CXXFLAGS = "-Wall -O2 -march=core2", etc.
And build <port> from source:
sudo port -s install <port> -universal \
configure.cc="${CC}" configure.cxx="${CXX}" \
configure.cflags="${CFLAGS}" configure.cxxflags="${CXXFLAGS}"
The other alternative, is to install the gcc48 (or above) port, and use it as the compiler. Don't use the old gcc-4.2.1 installed with older versions of Xcode. It's rubbish.
One way to accomplish this appears to be to build opencv from source, and use the configure.cxx_stdlib variable to specify libstdc++ as your C++ runtime.
Try out the following:
sudo port install -s opencv configure.cxx_stdlib="libstdc++"

How to replace boost/thread/tss.hpp on Mac OSX El Capitan?

I recently upgraded my Mac OSX from Yosemite to El Capitan and updated Xcode to v7.1. After the upgrades, I found that my C++ application no longer compiles due to a header file that cannot be found:
../../src/dir/sysArea.h:39:10: fatal error: 'boost/thread/tss.hpp' file not found
#include <boost/thread/tss.hpp>
The clang invocation is like this:
clang -g -std=c++11 -fno-inline -Wall -Werror -Wextra -D_LARGEFILE_SOURCE \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c \
-o ARCH.darwin_15_i86/debug/file.o file.cpp
I searched my Macintosh using the finder and the file tss.hpp no longer appears to be present. How do I port my application to El Capitan, what is the replacement of Boost's tss.hpp? I tried updating my Boost version from the prior v1.53 to the latest v1.58, but it had no impact, I get the same error when compiling.
export PATH=/usr/local/bin:$PATH
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
sudo chmod o+w /usr/local/opt /usr/local/include /usr/local/lib
brew unlink boost
brew install boost
sudo chmod o-w /usr/local/opt /usr/local/include /usr/local/lib
My C++03 application is including tss.hpp so that it can use the thread_specific_ptr<> feature:
static boost::thread_specific_ptr<Botan::AutoSeeded_RNG> _rng;
for thread local storage (e.g. each thread gets its own version of the static variable.)
The finder was not searching everywhere (would be nice if it did), I do have tss.hpp under /usr/local/include.
I tried adding -stdlib=libc++ and -stdlib=libstdc++ to the clang invocation, but neither got the complier to look in /usr/local/include for the Boost headers. What compiler flags will instruct it to look there other than hardcoding -I/user/local/include?
Note that clang says thread_local is not available as discussed here.
Doing xcode-select --install as per this answer, seems to have told clang to look in the /usr/local/include directory for headers and resolves the issue.

Macports on OSX 10.9 - compile with -stdlib=libstdc++

In OSX 10.9 the default -stdlib option for clang++ is libc++, so that's what Macport uses when building packages.
Is there any way to tell Macports to use libstdc++ instead?
In particular I would like to build OpenCV through Macports so it's using libstdc++, but I imagine I'll run into a need to do so for other packages as well
The option is simply: -stdlib=libstdc++
If you need finer control over the build process for various ports, you can always set variables like:
CXX = "clang -std=c++11 -stdlib=libc++, CXXFLAGS = "-Wall -O2 -march=core2", etc.
And build <port> from source:
sudo port -s install <port> -universal \
configure.cc="${CC}" configure.cxx="${CXX}" \
configure.cflags="${CFLAGS}" configure.cxxflags="${CXXFLAGS}"
The other alternative, is to install the gcc48 (or above) port, and use it as the compiler. Don't use the old gcc-4.2.1 installed with older versions of Xcode. It's rubbish.
One way to accomplish this appears to be to build opencv from source, and use the configure.cxx_stdlib variable to specify libstdc++ as your C++ runtime.
Try out the following:
sudo port install -s opencv configure.cxx_stdlib="libstdc++"

C++11 on Mac with Clang or GCC

I have Xcode 4.5.2 on Moutain Lion, and I have install the lastest "Command Line Tools" but when I tried to compile with g++ or clang++ (and the options -std=c++11 -stdlib=libc++) I get an error.
With g++:
cc1plus: error: unrecognized command line option "-std=c++11"
cc1plus: error: unrecognized command line option "-stdlib=libc++"
With clang++:
clang: error: invalid deployment target for -stdlib=libc++ (requires OS X 10.7 or later)
It's in a Qt project.
So how can I used the C++11 on my Mac ?
As you found, g++ does not support those command line options.
It sounds like you're using Xcode.
For clang, you should look at the project settings, and make sure that the "Deployment Target" is set to 10.7 (or 10.8)
What the error message is telling you is that libc++ is not available for 10.6 and before.
I installed gcc-4.7 on my Mac to make C++11 work. GCC in its current version is fairly good at supporting C++11, so this should be a fair choice.
The installation can be done by Homebrew and is not that complicated (at least I was able to do it...)
To install Homebrew if you do not already have it:
ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
Now run
brew doctor
and fix whatever problems come up (there is something written in the hombrew documentation for that). Finally, install current gcc:
brew install gcc
If everything goes well you should be able to access g++-4.7, which allows -std=c++0x.
Try -std=c++0x if c++11 doesn't work. Support for the -std=c++11 option is relatively new in GCC and you might not have a recent enough version.
I'd trust Marshall on the libc++ issue.