skip to Main Content

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


  1. 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 which sdk directory contains all the stdc++ files. For example, I found that I have all the files in the MacOSX14.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:

    $ sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/include/c++/v1/* /Library/Developer/CommandLineTools/usr/include/c++/v1
    

    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):

    $ sudo ln -s /usr/local/include/c++/v1/* /Library/Developer/CommandLineTools/usr/include/c++/v1
    

    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 by clang 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 enter

    $ echo | clang++ -E -Wp,-v -
    

    it 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.

    Login or Signup to reply.
  2. 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:

    export CPATH=`xcrun --show-sdk-path`/usr/include
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search