How to run c program using GCC not using clang in mac - macos

When I check the version of clang
❯ clang --version
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.3.0
when I check the version of gcc
❯ gcc --version
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.3.0
Here I am not able to use the gcc compiler that I installed using homebrew
❯ ls -l /opt/homebrew/Cellar/gcc
total 0
drwxr-xr-x 15 kumar admin 480 Feb 5 20:30 12.2.0
Please tell me how can I use the gcc(installed using Homebrew) for running any c program.
When I compile any program by writing gcc hello.c ,Then it is similar to clang hello.c Whereas I want to compile the file hello.c with the gcc that is installed using homebrew at /opt/homebrew/Cellar/gcc

You can't "run" any program using gcc, you can only compile and link using gcc.
Your shell determines which program to run according to your PATH. If your PATH contains /usr/bin before /opt/homebrew/bin then you will be running Apple's gcc rather than the homebrew one. You can check your PATH with:
echo $PATH
You can check which gcc will be run when you type gcc without a path by running:
type gcc
Pretty much all homebrew packages link their binaries into /opt/homebrew/bin, so firstly you should set your PATH like this:
export PATH=/opt/homebrew/bin:PATH
That makes your shell look for homebrew packages before Apple ones. You should do that in your login profile so it is set every time you login.
Then you need to check what name your homebrew GCC package has installed gcc under, it might be gcc-10 or gcc-11. You can check with:
ls /opt/homebrew/bin/gcc*
If it is gcc-11, you would compile with:
gcc-11 -o prog program.c
Note that if your code is C++, you will need:
g++-11 -o prog program.cpp

Related

Mac clang installation seems to override GCC install

Mac 10.13.6 High Sierra here. New to C development and I'm trying to get myself setup with the latest stable/recommended GCC version, which I believe (keep me honest here) is 10.2.
When I go to the terminal to see what I have installed:
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ gcc -dumpversion
4.2.1
OK...surprised to see LLVM/clang-related stuff in the output. So I try this:
$ clang --version
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
So its almost as if... I have both clang and gcc installed, but my clang installation has assimilated my GCC installation?! Why else would the gcc --version output reference clang?
Is this typical for Mac setups?
What do I need to do to get GCC 10.2 properly installed on my machine?
Here are some simple truths, statements and observations to try and explain what's going on:
Apple ships the clang/LLVM compiler with macOS. Clang is a "front-end" that can parse C, C++ and Objective-C down to something that LLVM (referred to as a "back-end") can compile
Clang/LLVM is located in /Applications/Xcode.app/somewhere
Apple also ships a /usr/bin/gcc which just runs clang. I have no idea why they do that - it doesn't seem very helpful to me - but they don't answer my questions
Apple puts its binaries (programs) in /usr/bin. That is an integral part of macOS and you should never touch or change anything in there - you are asking for problems if you do. This warning applies to Python too.
If you want the real, lovely GNU Compiler Collection (GCC) which includes the gcc, g++ and gfortran compilers, your best bet, IMHO, is to get them from homebrew. I will not put the installation instructions here because they could become outdated, so you should use the ones on the homebrew site.
Once you have homebrew installed, you can install the GNU Compiler Collection (GCC) with:
brew install gcc
After that, you will have all the lovely GNU Compiler Collection (GCC) of tools in /usr/local/bin, so you should put that in your PATH, near the beginning, and in any case before /usr/bin, using:
export PATH=/usr/local/bin:$PATH
In general, you should also add a similar line into your login profile, or into the system login profile, so it is set up every time you or any other user logs in.
Let's take a look:
ls /usr/local/bin/gcc* /usr/local/bin/g++*
/usr/local/bin/gcc-10
/usr/local/bin/g++-10
Depending on the versions and updates, you will then have these programs available:
gcc-10 # the real GNU C compiler
g++-10 # the real GNU C++compiler
gfortran # GNU fortran compiler
And you can check their versions with:
gcc-10 -v
g++-10 -v
gfortran -v
Now you know about homebrew, here are some more simple truths and observations:
folks (who are not the supplier of the operating system) who supply binaries (programs) for you should put their stuff in /usr/local to show that it is just a locally installed program rather than a part of the core macOS operating system
homebrew is well-behaved and installs its binaries (programs) in /usr/local/Cellar and then usually makes symbolic links from /usr/local/bin/PROGRAM to the Cellar. None of this interferes with Apple-supplied stuff.
if you want to run the homebrew version of a command, you should have /usr/local/bin first on your PATH
Let's have a look at those symbolic links:
ls -l /usr/local/bin/g*10
lrwxr-xr-x 1 mark admin 31 21 Aug 16:41 /usr/local/bin/g++-10 -> ../Cellar/gcc/10.2.0/bin/g++-10
lrwxr-xr-x 1 mark admin 31 21 Aug 16:41 /usr/local/bin/gcc-10 -> ../Cellar/gcc/10.2.0/bin/gcc-10
If you want to know what you are actually running when you enter a command, use the type command like this.
type gcc
gcc is hashed (/usr/bin/gcc)
That tells you that if you run gcc you will actually be running /usr/bin/gcc which we know is from Apple - because it is in /usr/bin
Now try this:
type gcc-10
gcc-10 is hashed (/usr/local/bin/gcc-10)
That tells you that if you run gcc-10 you will actually be running /usr/local/bin/gcc-10 which we know is from homebrew - because it is in /usr/local/bin

MacPorts GCC compiler, -Wa,-q and "(/opt/local/bin/clang) not installed"

I have a MacPorts GCC compiler installed, and I have a MacPorts Clang installed for the integrated assembler:
$ port installed | egrep -i '(gcc|g\+\+|clang)'
clang-3.8 #3.8-r262722_1+analyzer (active)
clang_select #1.0_0 (active)
gcc49 #4.9.3_0 (active)
gcc_select #0.1_8 (active)
libgcc #6.1.0_0 (active)
When I attempt to compile an empty program using the integrated assembler:
$ cat test.cc
int main(int argc, char* argv[])
{
return argc;
}
It results in an error:
$ /opt/local//bin/gcc-mp-4.9 -Wa,-q -march=native test.cc -o test.exe
/opt/local/bin/as: assembler (/opt/local/bin/clang) not installed
And:
$ ls /opt/local/bin/clang
ls: /opt/local/bin/clang: No such file or directory
It appears there more to using the integrated assembler than just -Wa,-q. If I omit -Wa,-q, then the real program experiences a failure similar to How to use AVX/pclmulqdq on Mac OS X.
How do I tell the GCC compiler to use the integrated assembler from the installed Clang? I.e., clang++ -Wa,-q -Wa,as=/opt/local/bin/clang-mp-3.8
Or, do these things need to be installed in pairs where the version numbers matter? I.e., something like GCC 4.9 (JAN 2016) needs Clang 3.7 (JAN 2016)?
Or, what compiler does MacPorts normally place at /opt/local/bin/clang? E.g., Clang 3.5 is normally placed at /opt/local/bin/clang
For completeness, this MacBook has MacPorts, but its not on path. I use the MBP for OS X testing, and a second role is [soon to be] MacPorts testing. However, I've refrained from putting MacPorts on path to avoid tainting OS X testing.
You can simply do sudo port select clang mp-clang-3.8. I did not like this, because it makes this the default when simply calling clang (only if MacPorts is on the PATH, of course).
What I ended up doing is to replace /opt/local/bin/as with the following simple script:
#!/bin/sh
clang -c -x assembler $# -
And then I don't use the -Wa,-q arguments to gcc.
One doesn't need to mess with the compiler options (-Wa,-q) in order to switch to the clang integrated assembler. The same behaviour can be triggered setting the AS_INTEGRATED_ASSEMBLER environment variable as I explained here.
I am pretty sure the versions don't need to match. But I'm afraid that Macports has to be on the path for these to work. More so, I'm afraid you'd have to "port select" gcc...
Here's my setup that works:
$ port select --list clang
Available versions for clang:
apple-clang (active)
mp-clang-3.7
none
uri-clang
$ ll /opt/local/bin/clang
lrwxr-xr-x 1 root admin 14 Jan 21 2015 /opt/local/bin/clang# -> /usr/bin/clang
$ port select --list gcc
Available versions for gcc:
apple-gcc
mp-gcc6 (active)
none
$ ll /opt/local/bin/gcc
lrwxr-xr-x 1 root admin 23 May 6 17:13 /opt/local/bin/gcc# -> /opt/local/bin/gcc-mp-6
$ file /opt/local/bin/as
/opt/local/bin/as: Mach-O 64-bit executable x86_64
$ port provides /opt/local/bin/as
/opt/local/bin/as is provided by: cctools
$ $ port dependents cctools
gcc6 depends on cctools
libgcc depends on cctools
$
Try just symlink'ing /usr/bin/clang to /opt/local/bin/clang (same for /usr/bin/clang++) and see if it helps. And make sure cctools port is installed (though I can't imagine it not being there, as either gcc or clang depends on it).
And AFAIK, "-Wa,-q" is the way to tell GCC to use the native assembler (at least it has been working for me since Xcode-6 and GCC-4.8).

omp.h not found, OS X Yosemite not using newest gcc version

I am trying to build GraphChi on OS X Yosemite but get the following error:
fatal error: 'omp.h' file not found
From this question - How to include omp.h in OS X? - I learned that Yosemite uses Clang instead of gcc, which does not include omp.h.
$ which gcc
/usr/bin/gcc
$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
Next, I installed gcc via Homebrew
$ brew info gcc
gcc: stable 4.9.2 (bottled)
http://gcc.gnu.org
/usr/local/Cellar/gcc/4.9.2_1 (1092 files, 177M)
Built from source with: --without-multilib
and updated $PATH to include the path to the new gcc version
$ echo $PATH
/usr/local/Cellar/gcc/4.9.2_1:usr/local/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
however, gcc -v and which gcc still point to the old version, and building GraphChi still doesn't work due to the missing omp.h file
Does anyone know what else I need to do?
Update
locate omp.h returned:
/usr/local/Cellar/apple-gcc42/4.2.1-5666.3/lib/gcc/i686-apple-darwin11/4.2.1/include/omp.h
/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.1.0/4.9.2/include/omp.h
/usr/local/Cellar/gfortran/4.8.2/gfortran/lib/gcc/x86_64-apple-darwin13.0.0/4.8.2/include/omp.h
my ~/.profile:
export PATH=/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.1.0/4.9.2/include:/usr/local/Cellar/gcc/4.9.2_1/bin:usr/local/bin:/opt/local/bin:/opt/local/sbin:$PATH
I solved this with installing gcc with homebrew:
brew install gcc --without-multilib
and then building the source code with
CC=gcc-5 CXX=g++-5 cmake ..
CC=gcc-5 CXX=g++-5 make -j7
Once you have installed gcc-4.9 with homebrew, it will automatically be in your path. To use OpenMP, you just need to make sure you are using the newly installed gcc-4.9, and it will be able to find omp.h.
In the case of GraphChi, you will have to go change line 3 of the Makefile to be gcc-4.9. From there, running make should just work. They describe this in their README, but at least the version they describe is out of date https://github.com/GraphChi/graphchi-cpp#problems-compiling-on-mac.
clang does not support OpenMP yet. Also gcc by default links to Apple's LLVM clang compiler (not the GCC installed from brew).
Instead gcc-4.9 would link to GCC. I think if -fopenmp is specified omp.h is included automatically.
It is possible to manually build a version of clang with OpenMP support, see http://clang-omp.github.io
You shouldn't add the include path to PATH; instead, specify it as CFLAGS, including the -I option. You can export the CFLAGS variable, or set it on the fly.
Depending on how you compile things, you could do
CFLAGS=-I/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.1.0/4.9.2/include/omp.h gcc <whatever>
Of course, in this case you can specify it directly on the gcc command (as -I/usr/local/....), but the CFLAGS variable also works with configure (as configure often won't have an option to specify where it should look for specific include files); probably with make, or even for those installing a Python package: CFLAGS=-I... pip install <some-package>.
Other flags to consider are
CXXFLAGS: C++ specific pre-processor flags
LDFLAGS: linker specific flags (e.g. LDFLAGS=-L/some/path/... for linking with dynamic libraries).
CC: specify the C compiler to use. This is an easy way to avoid the built-in gcc alias for clang on OS X. Just use CC=/usr/local/bin/gcc-4 make or similar.
CXX: specify the C++ compiler to use.

Installation of gcc-4.7 on Fedora 16 still shows gcc-4.6

I built and installed gcc-4.7 on Fedora 16 from source. But when i go to the installation directory (/opt/gcc-4.7.0/bin) and query for the version g++ -v, i get gcc version 4.6.3 .... I did not use any suffix like -4.7 during the configuration, so my installed binary is g++. Is there any other configuration required post installation?
Did you check the path?
which gcc
/usr/bin/gcc
To change it to /opt/gcc... you can either set the PATH variable:
export PATH=/opt/gcc-4.7.0/bin:$PATH
..or create an alias, or set the CC and CXX variable to point to you gcc and g++ and then any ./configure / cmake / jam / etc should get the gcc declared in CC/CXX.

GLIBCXX_3.4.9 not found

I have a problem concerning libstdc++.so.
I installed a new version of gcc and tried to compile C++ code. The compiling worked, but when I try to execute the binary (m5.opt is its name) I've got the following error:
build/ALPHA_SE/m5.opt: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by build/ALPHA_SE/m5.opt).
Do I need to replace libstdc++.so? And if so, where can I download the version I want? On the GCC-website they say libstdc++ is a part of gcc now.
Details
GCC:
I had gcc 4.1.2 before, but I downloaded gcc 4.2.4. From the untarred gcc-directory I executed ./configure; make; sudo make install`.
When I tried to use gcc or g++ to compile, it's default version was still 4.1.2. To overcome this I replaced some links:
mv /usr/bin/gcc /usr/bin/gcc_bak
ln -s /usr/local/bin/gcc gcc
mv /usr/bin/g++ /usr/bin/g++_bak
ln -s /usr/local/bin/g++ g++
GLIBC(++) -- libstdc++:
/usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.8
/usr/local/lib/libstdc++.so -> libstdc++.so.6.0.9
/lib/libc.so.6 -> libc-2.5.so -> libc-2.5.so
Linux-version:
uname -a gives:
Linux madmax 2.6.18-128.4.1.el5 #1 SMP Tue Aug 4 12:51:10 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
The problem is that you built your new GCC incorrectly: on Linux you should use
./configure --prefix=/usr
The default installation prefix is /usr/local, which is why make install put gcc and g++ binaries into /usr/local/bin, etc.
What's happening to you now is that you compile and link using the new (symlinked) GCC 4.2.4, but at runtime your program binds to the old /usr/lib64/libstdc++.so.6 (version 6.0.8, instead of required 6.0.9). You can confirm that by running ldd build/ALPHA_SE/m5.opt: you should see that it uses /usr/lib64/libstdc++.so.6.
There are several fixes you could do.
env LD_LIBRARY_PATH=/usr/local/lib64 ldd build/ALPHA_SE/m5.opt
should show you that setting LD_LIBRARY_PATH is sufficient to redirect the binary to correct library, and
LD_LIBRARY_PATH=/usr/local/lib64 build/ALPHA_SE/m5.opt
should just run. You could "bake" this path into m5.opt binary by relinking it with -Wl,-rpath=/usr/local/lib64.
A more permanent solution is to fix the libraries the same way you fixed the binaries:
cd /usr/lib64 && mv libstdc++.so.6 libstdc++.so.6_bak &&
ln -s /usr/local/lib64/libstdc++.so.6 .
An even better solution is to reconfigure the new GCC with --prefix=/usr, and then make all install.
I know this is a very old question, but ...
It's not usually a good idea to replace the system compiler (i.e. the one in /usr) because the entire system will have been built with it and depend on it.
It's usually better to install the new compiler to a separate location and then see the libstdc++ FAQ How do I insure that the dynamically linked library will be found? and Finding Dynamic or Shared Libraries in the manual for how to ensure the correct libstdc++.so is found at runtime.
The other answers here should be fine, but the 'quick and easy' solution if you do happen to have gcc installed to /usr/local/ is to just add the new libs to the LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
You can also check the to see if you have the right versions of GLIBC installed using
strings /usr/lib/libstdc++.so.6 | grep GLIBC
strings /usr/local/lib64/libstdc++.so.18 | grep GLIBC
I got this last tip from another forum so credits due where credits due!

Resources