I want to avoid OpenMP for the debug build. I strongly prefer to NOT accomplish that by editing the CMakeLists.txt or other cmake files provided in the project repository (even if I could figure out how to do it by editing those, which so far I can’t).
So the answer, in the earlier thread with the same name as this thread, doesn’t help me.
I am using a shell script to give the cmake command to prepare to build the project. What might I put in that command or preceding that command in that shell script to stop cmake from finding OpenMP or otherwise stop the build files it creates from using OpenMP
# Check for OpenMP
IF(APPLE)
#we need a special search routine for mac, see changes in file CMakeModules/FindOpenMPMac.cmake
FIND_PACKAGE(OpenMPMac)
ELSE()
FIND_PACKAGE(OpenMP)
ENDIF()
IF(OPENMP_FOUND)
MESSAGE(STATUS "Compiler supports OpenMP. Activating support for it.")
ADD_COMPILE_OPTIONS(${OpenMP_CXX_FLAGS})
SET(HAVE_OPENMP TRUE)
IF(OpenMP_CXX_FLAGS AND NOT MSVC)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}")
ENDIF()
ELSE()
MESSAGE(WARNING "Compiler does not support OpenMP. OpenMP is required for multi-threaded processes. So only single threaded execution is compiled now.")
ENDIF()
As you may see, the checks are unconditional. If OpenMP can be found, it’ll be activated. You could either make it unfindable (no idea how to do that) or modify this part (I’d just add an option and maybe try to contribute that back to the project?)
That solved it. Please ignore the previous version of this reply (if you saw it before this edit). I had done something careless and was invoking the wrong project’s source code the whole time I thought I was testing your solution.
I added: -DCMAKE_DISABLE_FIND_PACKAGE_OpenMP=TRUE to the command line and that made it not use OpenMP
I’m now convinced that this IS the solution of this topic. But for a novice CMaker the solution is a little compact. I took me some time to understand it, and for that I had to resource to a minimal working example (like always). Thus for another beginner that could come this way, I leave my 2 cents in the solution:
Consider a parallel hello world! example in C++17:
#include <iostream>
#include <vector>
#ifdef HAVE_OMP
#include <omp.h>
#else
#include <thread>
#endif
int main() {
#ifdef HAVE_OMP
std::cout << "OMP solution" << std::endl;
#pragma omp parallel
{
int thread_id = omp_get_thread_num();
int total_threads = omp_get_num_threads();
std::cout << "Hello World from thread " << thread_id
<< " of " << total_threads << std::endl;
}
#else
std::cout << "C++17 solution" << std::endl;
int num_threads = std::thread::hardware_concurrency();
std::vector<std::thread> threads(num_threads);
for (int i = 0; i < num_threads; i++) {
threads[i] = std::thread([i, num_threads] {
std::cout << "Hello World from thread " << i
<< " of " << num_threads << std::endl;
});
}
for (auto& thread : threads) {
thread.join();
}
#endif
return 0;
}
A minimal CMakeLists.txt to compile such source might read:
cmake_minimum_required(VERSION 3.9)
project(hellow_parallel LANGUAGES CXX)
# Set build options
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
# Set C++17 standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS False)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Find Packages
find_package(OpenMP) # NON-REQUIRED
if(OpenMP_CXX_FOUND)
message(STATUS "Compiling with OpenMP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(DEPENDENCIES OpenMP::OpenMP_CXX)
add_definitions(-DHAVE_OMP) # to help the code know that OpenMP is enabled
else()
message(STATUS "OpenMP not found, compiling without OpenMP")
endif()
# Add the executable
add_executable(${PROJECT_NAME} main.cpp)
if(OpenMP_CXX_FOUND)
target_link_libraries(${PROJECT_NAME} PUBLIC ${DEPENDENCIES})
endif()
compiling this code can be done simply as
# Build with OpenMP
mkdir build && cd build
cmake ..
make
# Build without OpenMP
mkdir build && cd build
cmake -DCMAKE_DISABLE_FIND_PACKAGE_OpenMP=true ..
make
The typical output with OpenMP would look like:
$ ./hellow_parallel
OMP solution
Hello World from thread Hello World from thread Hello World from thread Hello World from thread 6 of 78 of 8
Hello World from thread 1 of 8
5 of 8
3 of 8
Hello World from thread 0 of 8
Hello World from thread 2 of 8
Hello World from thread 4 of 8
The typical output without OpenMP would look like:
$ ./hellow_parallel
C++17 solution
Hello World from thread 0 of 8
Hello World from thread 1 of 8
Hello World from thread 2 of 8
Hello World from thread 3 of 8
Hello World from thread 4 of 8
Hello World from thread 5 of 8
Hello World from thread 6 of 8
Hello World from thread 7 of 8
At this point, my question is:
Is there a more elegant way to do this?
(Perhaps there is a preprocessing definition already available to use inside my cpp code?)