OpenMP support for Mac using clang or gcc - c++

I am using Mac OS and I created a toy CMake project with OpenMP.
main.cpp:
#include <iostream>
#include "omp.h"
using namespace std;
int main() {
cout << "Hello, World!" << endl;
#pragma omp parallel
cout << "Hello OpenMP from thread " << omp_get_thread_num() << endl;
return 0;
}
CMakeList.txt:
cmake_minimum_required(VERSION 3.12)
project(omp_test)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
add_executable(omp_test main.cpp)
When I tried mkdir build && cd build && cmake .. && make -j to build the project, I got clang: error: unsupported option '-fopenmp'. It works well on Ubuntu. How can I change the CMakeList.txt to enable OpenMP support? Or If the problem can be solved using g++, how to do it?
Thanks for your help!

I have solved my problem by changing the default compiler to g++. (Note: I have already installed gcc/g++ and the OpenMP library from Homebrew.)
I did not change main.cpp and CMakeList.txt, but when I built the project, I use
mkdir build && cd build && cmake -DCMAKE_CXX_COMPILER=g++-9 .. && make -j
then the error clang: error: unsupported option '-fopenmp' disappeared. Specifically, I added the option -DCMAKE_CXX_COMPILER=g++-9 to change the default compiler. Maybe the g++ version on your computer is not g++-9, then you can check it under the path /user/local/bin/.

Related

Include flag (ncurses) in CMAKE project on MAC OS X [duplicate]

This question already has answers here:
How to add "-l" (ell) compiler flag in CMake
(2 answers)
Closed 3 years ago.
I'm trying to familiarize myself with ncurses.
When I compile this code on my IDE (cLion), it gives me the error:
"Error opening terminal: unknown"
I'm using Mac OSX.
If I compile using the terminal with:
"g++ -lncurses main.cpp -o hello"
It compiles and runs successfully.
But I'd like to figure out how to compile and run it on cLion.
I've checked around every on this forum and haven't been able to fix the issue. I've modified the CMakeLists.txt file various ways and none worked.
Where is the issue?
main.cpp
#include <ncurses.h>
using namespace std;
int main() {
initscr();
printw("Hello");
refresh();
int c = getch();
printw("%d", c);
getch();
endwin();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(ncurses)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "-lncurses")
add_executable(lncurses main.cpp)
CMAKE_CXX_FLAGS is the variable that contains compiler flags, not linker flags or libraries.
Use the target_link_libraries command to add libraries to link with:
target_link_libraries(lncurses ncurses)

wxWidgets runtime error (Mismatch version)

I have a problem at start the program:
Fatal Error: Mismatch between the program and library build versions detected.
The library used 3.0 (wchar_t,compiler with C++ ABI 1010,wx containers,compatible with 2.8),
and your program used 3.0 (wchar_t,compiler with C++ ABI 1009,wx containers,compatible with 2.8).
My cmake settings:
cmake_minimum_required(VERSION 3.0)
project(simple)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${wxWidgets_CXX_FLAGS} -Wall -std=c++14")
find_package(wxWidgets COMPONENTS net gl core base)
include("${wxWidgets_USE_FILE}")
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})
Version of wxWidgets 3.0.3.
If your desire is to have __GXX_ABI_VERSION=1002, specify -fabi-version=2 to GCC. To do this in your CMakeLists.txt, add:
add_definitions(-fabi-version=2)
This is a preferred approach compared to manually redefining __GXX_ABI_VERSION, which would violate C++ standards and potentially cause undefined behavior.
Note: -fabi-version=2 may not always correspond to __GXX_ABI_VERSION=1002 in future releases of GCC. Compile and run this quick C++ program to check it:
#include <iostream>
int main(void) {
std::cout << "__GXX_ABI_VERSION=" << __GXX_ABI_VERSION << std::endl;
return 0;
}
Compile this way:
g++ -fabi-version=2 -o check_fabi_version check_fabi_version.cpp
Run this way:
./check_fabi_version
Example output as of GCC 8.2.0:
__GXX_ABI_VERSION=1002
You can try to add to your program
#define __GXX_ABI_VERSION 1010
or just
sudo apt-get purge wx2.8-headers wx2.9-headers
I had two version of wxWidgets instaled. I deleted one of them and it works great.

Can clang static analyzer (scan-build) be used with cmake --build?

I'd like to use the clang static analyzer command line tool scan-build with the convenience of cmake --build.
Most of the resources I found online seem to indicate you need a two-step process:
scan-build cmake .
scan-build make
For example for this small example program with a bug that scan-build catches:
#include <iostream>
int fun() {
int x;
return x; # main.cpp:5:5: warning: Undefined or garbage value returned to caller
}
int main() {
int a = fun();
std::cout << "Hello, World! " << a << std::endl;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(test_program)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(test_program ${SOURCE_FILES})
If I run scan-build cmake --build cmake-build-release/ it does not find the bug, even though the binary is built. Is there anyway to get scan-build to work in a one step process with CMake?
If you want to use the Clang Static Analyzer, you should just set CMAKE_EXPORT_COMPILE_COMMANDS=YES. This will create a compilation database that CSA can read. You don't even need to build your project. The file is located at: /path/to/build/compile_commands.json.
scan-build is designed for projects that can't create a compilation database themselves.
Then you can run:
analyze-build --cdb /path/to/build/compile_commands.json \
--use-analyzer /path/to/clang \
--output /path/to/output
It's worth noting that clang-tidy has all of the CSA checks now. You can use this same compilation database technique to run clang-tidy on your codebase.

CMake project for Emscripten

I want to make CMake and Emscripten friends. Didn't find more or less informative documentation on the Emscripten project website, but they provide CMake toolchain file so I think it should be possible.
So far very basic compilation without advanced parameters works fine, but I have issues while using embind and preloading files.
Linking process seems to miss Emscripten "binaries" and produces warnings for all embind related functions like this one: warning: unresolved symbol: _embind_register_class which results in respective errors while loading compiled JS file in rowser.
No .data file is generated during the compilation.
I've created a minimalistic example which includes two targets: one "normal" (client) and one manual (manual-client) which simply runs emcc as I expect it to be run: https://github.com/xwaffelx/minimal-cmake-emscripten-project/blob/master/README.md
Although manual way works, I don't think it is a proper way to do it...
--- Update ---
As requested, here is even more short example:
CMakeLists.txt file
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0015 NEW)
project(emtest)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build.emscripten)
include_directories("lib/assimp/include")
link_directories("lib/assimp/lib-js")
link_libraries("assimp")
file(GLOB_RECURSE CORE_HDR src/.h)
file(GLOB_RECURSE CORE_SRC src/.cpp)
add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
add_executable(client ${CORE_SRC} ${CORE_HDR})
Result should be equivalent to running the following command manualy:
emcc
-Ilib/assimp/include
-s DEMANGLE_SUPPORT=1
--preload-file assets
--bind
Application.cpp
lib/assimp/lib-js/libassimp.so
-o client.js
Here is the Application.cpp:
#include "Application.h"
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
void Application::Initialize() {
std::cout << "Initializing application." << std::endl;
Assimp::Importer importer; // For test purpose
}
void Application::SayHello() {
std::cout << "Hello!" << std::endl;
}
and Application.h:
#ifndef APPLICATION_H
#define APPLICATION_H
#include <emscripten/html5.h>
#include <emscripten/bind.h>
namespace e = emscripten;
class Application {
public:
void Initialize();
void SayHello();
};
EMSCRIPTEN_BINDINGS(EMTest) {
e::class_<Application>("Application")
.constructor()
.function("Initialize", &Application::Initialize)
.function("SayHello", &Application::SayHello);
}
#endif
THen I run cmake as follows:
cmake -DCMAKE_TOOLCHAIN_PATH=path/to/Emscripten.cmake .. && make
However, warnings like warning: unresolved symbol: _embind_register_class are produced during linking and running the code and no preloaded data in client.data file is created while compiling CMake project. At the same time no warnings and everything runs OK while compiling manually.
The solution was to specify all the flags during the linking by providing following CMake instruction:
set_target_properties(client PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")
Thanks to developers of emscripten who helped in the github issues tracker.

C++11 CMake: Regex fails

I ran into the problem that gcc/g++ <= 4.8.X does not support RegEx (my first reaction was: WHAT?!).
After installing (Ubuntu 14.04 LTS) gcc-4.9 and g++-4.9 (which is supposed to support RegEx properly) I still the get same error:
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
[1] 13608 abort (core dumped)
My CMakeLists.txt looks like this (working with Jetbrains CLion as IDE):
set(CMAKE_CXX_COMPILER g++-4.9)
cmake_minimum_required(VERSION 3.1)
project(project1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(project1 ${SOURCE_FILES})
My code looks like this:
#include <iostream>
#include <string>
#include <fstream>
#include <regex>
using namespace std;
(...)
char encryptChar(char cinput)
{
std::string s = std::string(1, cinput);
// simplified regex (also crashes)
std::regex e = std::regex("[a-z]");
if(std::regex_match(s, e))
{
// do some stuff, if string matches conditions
}
return cinput;
}
Compiler/Linker do not complain about anything. Program runs fine without the regex-lines.
> g++-4.9 --version
>>> g++-4.9 (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2
>>> Copyright (C) 2014 Free Software Foundation, Inc.
EDIT: After manually compiling the code with g++-4.9 -std=c++11 main.cpp the regex works. Why does the IDE/CMake version fails?
Finally, I found the problem:
My CMake version was 2.8-ish so CMake itself failed, Jetbrains CLion uses a custom CMake (shipped with the IDE) which is some 3.1-ish but also failed with RegEx.
I downloaded CMake 3.2.2 (newest version) and installed it (installation notes). Now compiling with CMake uses g++-4.9 properly and RegEx runs fine. In CLion I had to change the settings to ignore the custom CMake and use my systems CMake 3.2.2, now compiling with the IDE uses g++-4.9 properly, too and RegEx runs fine.