Determine flags for linking C++ standard library

I have posted this question on StackOverflow a few days ago, but received no answer so far.

I am trying to use CMake to generate a pkg-config file for a library with a C interface. This library is partially written in C++, so C programs that use it need to also link in the C++ standard library. How do I determine what the necessary linking flags are, using CMake, so I can include them in the generated pkg-config file?

To elaborate, suppose I have a C program, prog, that uses my library mylib. One way to link prog is to use the C++ linker:

c++ prog.o -lmylib -o prog

This is what CMake normally does (i.e. when prog is built with CMake).

Another way is to use the C linker. In this case, we need to explicitly link in the C++ standard library. The linking command might look like this:

cc prog.o -lmylib -lstdc++

The correct flags for linking the C++ standard library will differ from system to system, and from compiler to compiler. How can I use CMake to determine these linking flags?

I would like to include these flags in the Libs.private section of mylib's pkg-config file. As far as I know, pkg-config has no way to indicate that the C++ linker should be used (or show the name of the appropriate linking program). All it can do is list the required linking flags. Thus the usual solution would be to include these in the mylib.pc.

In practice, this choice comes down to deciding whether to use -lstdc++ (most Linux and older macOS) or -lc++ (newer macOS, maybe some Linux, maybe some BSD).

Right now we basically hard-code -lc++ on macOS and use -lstdc++ on all other systems, but this will obviously not be correct in some cases.

UPDATE In practice, it would be useful to have a limited solution that simply chooses between “libstdc++” / “libc++” / “neither” when the compiler is either GCC or Clang. This covers the vast majority of cases when it actually makes sense to generate a pkg-config file.

I think you’ll likely have to detect the stdlib in some try_compile (or similar) mechanism to decipher what is going on. CMake generally just lets the compiler deal with the stdlib (though I’ve had discussions about abstracting out the runtime library as follow-on work to CMP0091.

Thanks for the response. Do you mean trying to parse verbose compiler output or similar?

I think looking for -lstdc++ or -lc++ in the verbose output of c++ -v foo.cpp (where foo.cpp is a trivial main() { return 0; }) would work in most practically relevant cases (after verifying that the compiler is either Clang or GCC). Can try_compile give me this output, or would I need to use something like execute_process instead?

You can use check_symbol_exists for _LIBCPP_VERSION (libc++) or __GLIBCXX__ (libstdc++).