Linking libc++ to CMake project on Linux - c++

I want to use libc++ together with clang on Arch Linux in CMake project. I installed libc++ and added following lines to CMakeLists.txt as said on LLVM site in Linux section of "Using libc++ in your programs":
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "-lc++abi")
I have tried just "++abi" in linker's flags, but it didn't help. I need some help in figuring out what i should write in my CMakeLists.txt.

Don't forget to set the compiler to clang++:
set(CMAKE_CXX_COMPILER "clang++")
Also, purge the cmake generated files (delete the folder CMakeFiles and CMakeCache.txt).
Depending on your system, it might also help to set
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")

The "proper" way to do this in CMake at the moment, until a specific base feature is added to switch standard libraries that is, is to use a toolchain file.
In that toolchain file you specify the compiler etc similarly to the other answers here.
BUT what's great about toolchains is they can be swapped out quickly either on the commandline (using -DCMAKE_TOOLCHAIN_FILE=path/to/file) OR in VSCode with CMakeTools extension installed, and probably other editors too.
But having to hand code your own toolchain files is yet another obscure chore! No fun!
Luckily, I stumbled upon this github that maintains a suite of them so you don't have to write them from scratch! Should be a lot less likely to get them wrong.
https://github.com/ruslo/polly

Related

Cant compile c++ on OS X Big Sur, "ld: library not found for -lgcc_s.10.4"

After upgrading my MacBook Pro to OS X 11.1 Big Sur, I am unable to get compilation of c++ programs using gcc to work.
I am using CLion with CMake, and I get the following error when reloading the CMake configuration
ld: library not found for -lgcc_s.10.4
The things that I have tried are installing Xcode, it installed without error.
I have tried to create a symlink as suggested here https://github.com/Paxa/fast_excel/issues/33
$ cd /usr/local/lib
$ sudo ln -s ../../lib/libSystem.B.dylib libgcc_s.10.4.dylib
It appears that the library libSystem.B.dylib is not present. Some sites mention that the libraries starting with Big Sur reside in some "shared cache", which I have no idea of what it is and how to access it, let alone make ld access it on its own.
Any suggestions on how to solve this are very welcome. Thank you!
According to this answer you should use: g++-10 -o main main.cpp
The correct path of brew installed g++ in MacOS is:
$ which g++-10
> /usr/local/bin/g++-10
--
$ which g++
> /usr/bin/g++ //this is alias of clang (same for lyb)
If you use CMakeLists.txt file you will configure it like this:
set(CMAKE_CXX_COMPILER "/usr/local/bin/g++-10" CACHE STRING "C compiler" FORCE)
set(CMAKE_C_COMPILER "/usr/local/bin/gcc-10" CACHE STRING "C++ compiler" FORCE)
set(CMAKE_CXX_STANDARD 17)
In general, gcc tends not to work on more recent versions of Mac OS. The solution is to use the build in C/C++ compilers. To automatically use these, instead of GCC, set these environment variables:
CC="clang"
CXX="clang++"
This will use the built in Mac compilers. Once doing this, I have yet to run into an issue with compiling that wasn't due to the actual code being compiled.
Thank you for all the answers highlighting different things that could solve the issue. What ended up working was to run brew reinstall gcc, and pointing CLion (or plainly CMake as Mike mentioned) to use the correct compiler (something that I had already done, but I want to mention it here if anyone else finds this question and has the same problem), the paths that I use are
/usr/local/Cellar/gcc/10.2.0/bin/gcc-10
/usr/local/Cellar/gcc/10.2.0/bin/g++-10
These paths are actually just the explicit locations that are linked from
/usr/local/bin/g++-10
/usr/local/bin/gcc-10
Also, as Matt Braunstein mentioned, it is possible to use clang that is supplied with Mac OS X, something I did while figuring out how to solve my issues with gcc.
My thoughts on the problem is that somehow, installing gcc with homebrew didnt install everything needed as it appeared to already be installed from a previous version, the reinstall command seemed to rectify this.
Again, thank you for the answers that helped me find this solution, and possible workarounds.
I spent hours trying to solve this compilation problem with cmake, the original statement in CMakeLists.txt for library linkage is!
link_directories(/usr/local/lib)
target_link_libraries(Program libsndfile.dylib)
With error message after make:
ld: library not found for -lsndfile
The solution that works is to add the entire path like this:
target_link_libraries(Program /usr/local/lib/libsndfile.dylib)
There is no need to have this in Ubuntu, but somehow the new MacOS requires it.

How do I designate which compiler is called when running cmake + make?

I'm trying to compile a c++ project with cmake and make on OSX but it looks like make is using CXX or clang when I want to use g++ (gcc) so I can follow the answer here to tell the compiler where to find header files (#includes) for tbb used in the project: Need help getting intel TBB working?
brew list shows that I have up to date versions of cmake, make, gcc, and swig installed.
Here's the project I'm trying to compile for reference: https://github.com/nmoehrle/mvs-texturing/blob/master/README.md
I came across this related answer and was able to get the project working! MacOS, CMake and OpenMP
I updated the cmakelists.txt with the following commands to set llvm as the compiler. Note, I needed to update the llvm file path to match the version number I have installed.
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang++")
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/5.0.1/lib")
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/5.0.1/include")
Then I was also having issues with OpenMP so I added this section to configure the OpenMP include directories and link directories.
if (OPENMP_FOUND)
include_directories("${OPENMP_INCLUDES}")
link_directories("${OPENMP_LIBRARIES}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif(OPENMP_FOUND)
I'm a novice dev and wish I had more insight into why this worked but it fixed my issues!

link qt5 libraries automatically pass extra fPIC flag to nvcc compiler by cmake cause error

I have a project based on cuda10.1, qt5. And I use cmake to manage the compilation. However the same cmake script work fine in Windows, but in Linux, I got error "Unknown option 'fPIC'" when compiling .cu files. I look into makefile, then find there is a extra error flag "-fPIC" passed to nvcc compiler. Spending hours of testing, I find linking qt5 libraries will automatically pass extra fPIC flag which causes this error. I don't know this is bug or feature of cmake?
cmake_minimum_required(VERSION 3.10)
project(PyPhysLeo LANGUAGES CXX CUDA)
find_package(Qt5 COMPONENTS Core Widgets)
if(Qt5_FOUND)
message("Find QT5")
link_libraries(Qt5::Widgets Qt5::Core Qt5::Gui)
endif()
set(CMAKE_CXX_STANDARD 14 CACHE STRING "CXX STANDARD VERSION 11,14,17")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON CACHE BOOL "DEFAULT SET SEPERABLE COMPILATION MODE")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch=sm_60")
include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE})
add_executable(test test.cu)
if you try above cmake script with any sample cuda code, you will get "nvcc fatal" error because it doesn't recognize fPIC flag.
It is a problem with qt5.cmake. Thanks to Robert Crovella for commenting (see above) about the related information gitlab.kitware.com/cmake/cmake/issues/16915. There is no perfect solution so far. But...
One solution, if you can separate your project into a library and an executable sub-projects, then you can cleanly avoid the issue altogether. Try to put all the .cu files in a library sub-project and only link qt5 in an executable sub-project. This is one way to avoid this problem.
Otherwise, you can try to modify the variable defined by qt5.cmake, for that solution please refer to cmake issue 16915.

Static Compilation for wxWidgets C++

As a starter I would like to point out that I have spent few hours trying to resolve the problem with no success. I wrote a small project using wxWidgets library for C++ in Clion on Mac. Since majority of my classmates have done their projects in VisualStudio on Windows, nobody could help me out. The project must be handed in in a form of an executable which will work on any computer. I suppose that the solution I should be looking for is static compilation which would staticly link all of the libraries to the executable file. I tried adding some flags like the one below to the Cmake:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")
but it did not help whatsoever. I have absolutely no knowledge on how CMake works and I would greatly appreciate any help.
The whole cmake file which I currently have:
cmake_minimum_required(VERSION 3.9)
project(Lab3)
set(EXECUTABLE_NAME "Indexer")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra -DWX_PRECOMP")
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
include_directories(include/ ${wxWidgets_INCLUDE_DIRS})
file(GLOB SOURCES "src/*.cpp")
add_executable(${PROJECT_NAME} main.cpp Source.cpp Source.h)
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})
EDIT: I guess I didn't specify the problem clearly enough. The program compiles fine- everything works. It's just that whenever I try to copy the executable file (the end application) to a different computer it just doesn't work or shows up as a text file with corrupted characters instead of an application with a GUI etc..
You're not copying the right thing across. What you believe to be the application is probably just some kind of launcher.
Mac GUI applications do not consist of just a single file. Your Indexer app is actually what Apple call a bundle. The Finder presents this to the user as a single entity but it's really a folder.
You can look inside a bundle by right-clicking on it (or Ctrl+click) and selecting Show package contents. If you want to understand a bit more about what's in there, Apple document it here.
A good way to get a bundle from A to B might be to ZIP it. Once you have done that you will find out whether your efforts to statically link it have been successful. What I don't know is where your build system has put it, but maybe this post will help. It will be called Indexer.app, maybe Spotlight can find it.
To build wxWidgets with as few dependencies as possible, you should configure it with not only --disable-shared, but also --disable-sys-libs, to prevent it from using any third party libraries (e.g. libz, libpng, ...) that might be installed on your system.
After building your application using wxWidgets, you should confirm that otool -L YourApp.app/Contents/MacOS/YourApp doesn't show any non-system libraries.

Cmake: how to choose C++ headers

I want to choose between using gcc and clang and also want to choose between libstdc++ and libc++. This site explains how to mix compilers and standard libraries. I can choose between compilers by calling cmake like CC=gcc CCX=g++ cmake... or with CC=clang....
The problem is that with libstdc++ I need to use the flag -I/usr/include/c++/5 and with libc++ the -I/usr/include/c++/v1.
For portability reasons I do not want to include the above paths neither in CMakeListst.txt, neither as a command line argument. Is there a way to do this and let cmake autodetect it?
Maybe you already know this, find_package boost or openssl are also see certain environment variable such as BOOST_ROOT and OPENSSL_ROOT_DIR. So you need such hint variable also.
Like cpprestsdk cmake script,
I think your CMakeLists.txt is
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message("-- Setting clang option")
include_directories(${Your_path})
...
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message("-- Setting gcc options")
include_directories(${Your_path})
...
else()
message("-- Unknown compiler, success is doubtful.")
message("CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}")
endif()