Disable OpenMP (without modifying CMakeLists.txt)

I am building a debug build of a project with an existing complicated set of cmake files:
https://sourceforge.net/projects/hugin/

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

This is where Hugin looks for 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?)

This variable should help you:

CMAKE_DISABLE_FIND_PACKAGE_<PackageName>

1 Like

| Josef Angstenberger jtxa
March 12 |

  • | - |

This variable should help you:

CMAKE_DISABLE_FIND_PACKAGE_

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

1 Like

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?)