Hi all,
I am trying to build a library including C and C++ object files, but I need to perform the link with Clang (not Clang++). The basic reason of this is that my real use case also uses Fortran object files, so I never link my libraries with the C++ compiler.
The typical command for building a library is:
$(CC) -shared hellocpp.o -o libhellocpp.dylibHowever, since hellocpp.o is a C++ object file, the link fails because of missing C++ symbols. Using GNU g++ compiler, the solution is straightforward, because g++ can tell me where its libstdc++.so is, e.g.
STDCXX_LIB = $(shell g++ -print-file-name=libstdc++.so)
gcc -shared hellocpp.o -o libhellocpp.so $(STDCXX_LIB)Unfortunately this scheme fails with clang and clang++. The option -print-file-name is documented but not implemented. In other words, this fails:
clang++ -print-file-name=libstdc++.dylibWorse, it seems that I have to link my objects files against libc++.1.dylib, not libstdc++.dylib, i.e. only this link command is successful:
clang -shared hellocpp.o -o libhellocpp.dylib /usr/lib/libc++.1.dylibBut my worry is that this explicit naming is full of assumption (C++ library name and location) and is not portable.
In summary, my need is:
- linking C++ objects files with clang (not clang++),
- no assumption on the location (because I may use a compiler from a non standard location),
- if possible no assumption on the library name.
And my question is: can I ask clang++ what is the C++ library path to be given to clang?
Here is a short hello-world example (use "make hello" or "make clean"):
$ cat helloc.c
#include<stdio.h>
int main()
{
printf("Hello from C.\n");
hellocpp();
printf("Done C.\n");
}$ cat hellocpp.cpp
#include <iostream>
extern "C" void hellocpp()
{
std::cout << "Hello from C++.\n";
std::cout << "Done C++.\n";
}$ cat Makefile
CC = clang
CXX = clang++
SHLIBEXT = dylib
# Option 1: giving nothing (link fails)
# STDCXX_LIB =
# Option 2: asking for libstdc++.dylib location (not implemented)
STDCXX_LIB = $(shell $(CXX) -print-file-name=libstdc++.$(SHLIBEXT))
# Option 3: explicit path (strong assumptions)
# STDCXX_LIB = /usr/lib/libc++.1.dylib
%.o: %.c
$(CC) -c $< -o $@
%.o: %.cpp
$(CXX) -fPIC -c $< -o $@
# Link library with gcc (while object file contains C++ code)
libhellocpp.$(SHLIBEXT): hellocpp.o
$(CC) -shared hellocpp.o -o $@ $(STDCXX_LIB)
hello: helloc.o libhellocpp.$(SHLIBEXT)
$(CC) helloc.o -o $@ -L. -lhellocpp $(STDCXX_LIB)
clean:
rm -f *.o *.$(SHLIBEXT) hello