I am trying to compile and run a very basic C++ program on Mac, such as the following "Hello World" program, but I am constantly running into various issues with it not compiling.
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!" << endl;
return 0;
}
This is on MacOS Sonoma 14.0 and the following is the output of "gcc -v":
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: x86_64-apple-darwin23.0.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Upon compiling this very basic "Hello World" code snippet (I named the file "sample.cpp"), I get a whole bunch of errors, with the following being the first one:
$ g++ sample.cpp
In file included from sample.cpp:1:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/iostream:43:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/ios:221:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__locale:15:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/cctype:43:5: error: <cctype> tried including <ctype.h> but didn't find libc++'s <ctype.h> header.
This usually means that your header search paths are not configured properly.
The header search paths should contain the C++ Standard Library headers before any C Standard Library.
# error <cctype> tried including <ctype.h> but didn't find libc++'s <ctype.h> header.
^
OK, so from what I’ve read online so far, we can print out g++’s search path when compiling with "g++ -v sample.cpp", and upon doing that, this is what it reports:
#include <...> search starts here:
/usr/local/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1
/Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
/Library/Developer/CommandLineTools/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
In my /usr/local/include directory, there are some suspicious .h files that I suspect might be the cause of this issue. I do see a "ctype.h" file there but I suspect it might be the C standard library version one instead of the C++ standard library version. So, maybe the solution is to force g++ to search in the /Library/Developer/CommandLineTools/SDKs/MacOSx.sdk/usr/include/c++/v1 directory first?
OK, so according to this answer, maybe we can force g++ to include the …/c++/v1 directory first using the -I switch. Unfortunately, g++ -v prints out
ignoring duplicate directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1"
as it is a non-system directory that duplicates a system directory"
… and ends up searching in the same order as above.
On the same link, it also says that there’s an option called --nostdinc
that will ignore standard C include directories. So I gave that a try. Now, g++ -v
does report that only the …/c++/v1 directory is being included in the header file search, but yet another problem appears:
In file included from sample.cpp:1:
In file included from... (truncated):
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/wchar.h:143:77: error: use of undeclared identifier 'wcschr'
wchar_t* __libcpp_wcschr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcschr(__s, __c);}
This brought me to another answer here that suggested I use the Command Line Tools instead of xcode. So I went ahead and downloaded that while deleting Xcode. However, that doesn’t help in this situation, even though I’ve verified that my output of xcode-select -p
results in /Library/Developer/CommandLineTools
.
I’ve also done what I saw on some other non-Stack Overflow sites, such as completely uninstalling Xcode and reinstalling Command Line Tools to no avail.
Any insight as to what could be wrong here, and which path seems the best to fix this. I think somehow changing the order of the header search paths to move …/c++/v1 ahead of /usr/local/include is somehow the way to go here.
2
Answers
I had the same problem when I updated to macOS Sonoma 14.3 and it was, for some reason, because my
/Library/Developer/CommandLineTools/usr/include/c++/v1/
directory was missing the majority of the C++ standard library header files.Browse your
/Library/Developer/CommandLineTools/SDKs/
directory and see whichsdk
directory contains all thestdc++
files. For example, I found that I have all the files in theMacOSX14.2.sdk/usr/include/c++/v1/
directory.If this is the case, make sure
xcode-select -p
outputs/Library/Developer/CommandLineTools
(just in case you changed your settings since asking the question), then create a symlink from/Library/Developer/CommandLineTools/usr/include/c++/v1
to the directory that has all the files. If the directory does not exist, create it. If it does, CAREFULLY delete everything in the directory and proceed. For my case where my files all exist in the mentioned directory, the command to create a symlink would be:If the compilation now works, the following steps are optional.
If the compilation still fails, symlink everything in the
/usr/local/include/c++/v1/
directory to the directory that you just symlinked (again, if the directory does not exist, create it and if it does, empty it):Symlink to
/usr/local/include/c++/v1/
is good to do even if filling the/Library/Developer/CommandLineTools/usr/include/c++/v1
directory resolved the issue because the/usr/local/include/
directory is the first to be searched byclang
and since it probably will not exist by default, it will only contain the C++ headers you just added. This means that the compiler will search through C++ headers before C headers to avoid issues brought up in this question (if you’re curious). If you enterit will show the search paths of
clang
in order, and you will see that/usr/local/include/
is first, which means it will be searched first.I’ve ran into this issue even on other Mac versions, and it’s also problematic immediately after changing xcode version, so just use this in my .bashrc: