dimanche 7 mars 2021

SIGABRT: CMake vs manual g++ compilation

I am facing a very weird issue. My source directory contains the following:

❯ tree .
├── CMakeLists.txt
├── main.cpp
└── stoppable_task.hpp

0 directories, 3 files

Where the contents of stoppable_task.hpp is:

#ifndef STOPPABLE_TASK_HPP
#define STOPPABLE_TASK_HPP

#include <future>

enum class TaskState : unsigned char {
    Ready = 0,
    Executing = 1,
    Terminating = 2
};

class StoppableTask {
    std::promise<void>  exit_signal;
    std::future<void>   future_obj;

protected:
    TaskState           task_state;
    virtual void run() = 0;

public:

    StoppableTask() 
    :   future_obj(exit_signal.get_future()), 
        task_state(TaskState::Ready) {}

    StoppableTask(const StoppableTask&) = delete;
    
    StoppableTask& operator=(const StoppableTask&) = delete;

    virtual void operator()() {
        task_state = TaskState::Executing;
        run();
    }

    bool is_stop_requested(int timeout_in_ms = 100) const {
        std::chrono::milliseconds t(timeout_in_ms);
        return (future_obj.wait_for(t) == std::future_status::ready);
    }

    void request_stop() {
        task_state = TaskState::Terminating;
        exit_signal.set_value();
    }

    TaskState get_task_state() {
        return task_state;
    }
};

#endif

and contents of main.cpp is:

#include "stoppable_task.hpp"
#include <iostream>
#include <memory>

class Speak : public StoppableTask {
    int count;
public:
    Speak() : count(0), StoppableTask() {}

    Speak(const Speak&) = delete;
    Speak& operator=(const Speak&) = delete;

    void run() override {
        std::cout << ++count << " -- speaking ... " << std::endl;
    }
};

int main() {
    int i = 10;

    std::unique_ptr<Speak> spk = std::make_unique<Speak>();

    do {
        (*spk)();
        if (--i <= 0) {
            spk->request_stop();
        }
    } while(not spk->is_stop_requested());

    return 0;
}

I am using the following CMakeLists.txt file to compile.

cmake_minimum_required(VERSION 3.16)
project(stoppable_task)

set(CMAKE_CXX_STANDARD 17)

find_package(Threads REQUIRED)

set(SRC_FILES
    main.cpp
)

set(HDR_FILES
    stoppable_task.hpp
)

add_executable(stoppable_task ${SRC_FILES} ${HDR_FILES})

target_link_libraries(stoppable_task Threads::Threads)

On compiling through CMake, the program throuws a SIGABRT error as shown below:

❯ ./stoppable_task
1 -- speaking ...
2 -- speaking ...
3 -- speaking ...
4 -- speaking ...
5 -- speaking ...
6 -- speaking ...
7 -- speaking ...
8 -- speaking ...
9 -- speaking ...
10 -- speaking ...
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
fish: “./stoppable_task” terminated by signal SIGABRT (Abort)

The solution from this page says to manually compile as follows:

❯ g++ -std=c++17 main.cpp -pthread

Surprisingly, the manual compilation works and throws no error. Can anyone explain what is the issue with the first CMake method and how can I resolve that? Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire