At work, I have a machine with Ubuntu 20.04, where I'd prefer not to install any new packages. There are a bunch of clang and cmake versions present in a common path provided by IT. I am trying to compile a program with clang from this path and doing it through cmake. If I use the default gcc on this system (or MSVC on windows), I am able to compile the program. However, when I add clang to the PATH and specify CC/CXX as clang/clang++, I end up with a compile error: "features.h not found". The requirement is to use C++17 (due to some code that uses the fetures/filesystem library). To use this "non standard" clang, I am using below clang (I have removed reference to the actual source and headers, but as I said, I am able to compile with the system provided gcc and also MSVC on Windows):
cmake_minimum_required(VERSION 3.5)
project(myProj)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
#Check and set CLANG paths
if(NOT ${CLANG_PATH} EQUAL "")
set(CMAKE_C_COMPILER "${CLANG_PATH}/bin/clang")
set(CMAKE_CXX_COMPILER "${CLANG_PATH}/bin/clang++")
set(CLANG_INCLUDE_PATH "${CLANG_PATH}/include/c++/v1")
set(CLANG_LIB_PATH "${CLANG_PATH}/lib")
set(CMAKE_BUILD_RPATH "${CLANG_PATH}/lib")
add_compile_options(-std=c++17)# -stdlib=libc++)
add_compile_options(-nostdinc++ -I${CLANG_INCLUDE_PATH})
message("Using clang from ${CMAKE_C_COMPILER}")
add_compile_options(-isystem ${CLANG_INCLUDE_PATH})
endif()
add_executable(myExe)
if(NOT ${CLANG_PATH} EQUAL "")
# target_link_options(myExe PRIVATE -nolibc)
# target_link_options(myExe PRIVATE -nostdlib)
target_link_options(myExe PRIVATE -nodefaultlibs)
target_link_options(myExe PRIVATE -nostdlib++)
target_link_options(myExe PRIVATE -L${CLANG_LIB_PATH})
target_link_options(myExe PRIVATE -Wl,-rpath ${CLANG_LIB_PATH})
endif()
if(WIN32)
add_compile_definitions(_WINDOWS=1)
else() #for linux
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_BUILD_TYPE DEBUG)
add_compile_definitions(_LINUX=1)
add_compile_definitions(g_strlcpy=strncpy)
add_compile_definitions(strlcpy=strncpy)
add_compile_definitions(sprintf_s=snprintf)
add_compile_definitions(errno_t=int)
add_compile_options(-fPIC -g -Wno-unused-value -O0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes")
if(NOT ${CLANG_PATH} EQUAL "")
target_link_options(myExe PRIVATE -lc++)
else()
target_link_options(myExe PRIVATE -lstdc++ -g)
endif()
target_link_options(myExe PRIVATE -ldl)
target_link_options(myExe PRIVATE -lm)
target_link_options(myExe PRIVATE -lpthread)
target_link_options(myExe PRIVATE -fPIC)
target_compile_options(myExe PRIVATE -fpermissive)
endif()
target_sources(myExe
PRIVATE
source.cpp
)
if(WIN32)
target_link_libraries(myExe
PRIVATE
<req_libs>)
else()
target_link_libraries(myExe
PRIVATE
<req_libs>
m
pthread
dl)
endif(WIN32)
install(TARGETS myExe DESTINATION bin)
With this cmake, and using CC=clang CXX=clang++ cmake -DCLANG_PATH=/pkg/qct/software/clang/13.0.0/ .. && make -k to compile, I get linker errors:
- undefined reference to symbol 'fflush@@GLIBC_2.2.5; and
- /usr/bin/ld: libtgt1.a(mySrc.cpp.o): in function
std::__1::__hash_table<std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, paramType*>,std::__1::__unordered_map_hasher<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >,paramType*>, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>,std::__1::__unordered_map_equal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, paramType*>,std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>,std::__1::allocator<std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, paramType*> > >::rehash(unsigned long)':customeClang13.0.0//include/c++/v1/__hash_table:2312: undefinedreference tostd::__1::__next_prime(unsigned long)' /usr/bin/ld: customeClang13.0.0//include/c++/v1/__hash_table:2322: undefined reference tostd::__1::__next_prime(unsigned long)' /usr/bin/ld: libtgt1.a(mySrc1.cpp.o): in functionpair<const std::__1::string &, 0UL>': customeClang13.0.0//include/c++/v1/tuple:1521: undefined reference to `std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >::basic_string(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&)'
This CMake was working till a few days ago, before I got the system upgraded from Ubuntu 16 to Ubuntu 20. I am guessing I'm missing some libraries, but I'm not sure what.
Any directions/solutions would be great.