Undefined reference to custom MAVSDK plugin

Hello,

I made simple custom plugin to getting current distance from sensors, but when I want to use it in my program after installation, compiling fails with error:

undefined reference to `mavsdk::Distance::subscribe_current_distance(std::function<void (unsigned int)>)'
CMakeFiles/MAVLINK_avoiding.dir/main.cpp.o: In function `void __gnu_cxx::new_allocator<mavsdk::Distance>::construct<mavsdk::Distance, mavsdk::System&>(mavsdk::Distance*, mavsdk::System&)':

I tried defining subscribe_current_distance in implementation files, but it would ended with failure in compiling MAVSDK (gcc complains about function being already defined in distance.cpp)
What I should do?

plugin usage example ending in failure:

distance->subscribe_current_distance([](uint32_t currentDistance){
        cout<<currentDistance<<endl;
    });

distance.proto

syntax = "proto3";

//get distance from sensors
service DistanceService{
    rpc SubscribeCurrentDistance(SubscribeCurrentDistanceRequest) returns(stream CurrentDistanceResponse){}
}
message SubscribeCurrentDistanceRequest{}

message CurrentDistanceResponse{
    uint32 distance = 1;
}

distance.cpp:

// WARNING: THIS FILE IS AUTOGENERATED! As such, it should not be edited.
// Edits need to be made to the proto files
// (see https://github.com/mavlink/MAVSDK-Proto/blob/master/protos/distance/distance.proto)

#include <iomanip>

#include "distance_impl.h"
#include "plugins/distance/distance.h"

namespace mavsdk {



Distance::Distance(System& system) : PluginBase(), _impl{new DistanceImpl(system)} {}

Distance::~Distance() {}



void Distance::subscribe_current_distance(CurrentDistanceCallback callback)
{
    _impl->current_distance_async(callback);
}




uint32_t
Distance::current_distance() const
{
    return _impl->current_distance();
}





} // namespace mavsdk

distance.h

// WARNING: THIS FILE IS AUTOGENERATED! As such, it should not be edited.
// Edits need to be made to the proto files
// (see https://github.com/mavlink/MAVSDK-Proto/blob/master/protos/distance/distance.proto)

#pragma once

#include <array>
#include <cmath>
#include <functional>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "plugin_base.h"

namespace mavsdk {

class System;
class DistanceImpl;

/**
 * @brief get distance from sensors
 */
class Distance : public PluginBase {
public:
    /**
     * @brief Constructor. Creates the plugin for a specific System.
     *
     * The plugin is typically created as shown below:
     *
     *     ```cpp
     *     auto distance = std::make_shared<Distance>(system);
     *     ```
     *
     * @param system The specific system associated with this plugin.
     */
    explicit Distance(System& system);

    /**
     * @brief Destructor (internal use only).
     */
    ~Distance();






        
    /**
    * @brief Callback type for subscribe_current_distance.
    */
        
    using CurrentDistanceCallback = std::function<void(uint32_t)>;

    /**
     * @brief 
     */
    void subscribe_current_distance(CurrentDistanceCallback callback);



    /**
     * @brief Poll for 'uint32_t' (blocking).
     *
     * @return One uint32_t update.
     */
    uint32_t current_distance() const;




    /**
     * @brief Copy constructor (object is not copyable).
     */
    Distance(const Distance&) = delete;

    /**
     * @brief Equality operator (object is not copyable).
     */
    const Distance& operator=(const Distance&) = delete;

private:
    /** @private Underlying implementation, set at instantiation */
    std::unique_ptr<DistanceImpl> _impl;
};

} // namespace mavsdk

distance_impl.cpp:

#include "distance_impl.h"

namespace mavsdk {

DistanceImpl::DistanceImpl(System& system) : PluginImplBase(system)
{
    _parent->register_plugin(this);
}

DistanceImpl::~DistanceImpl()
{
    _parent->unregister_plugin(this);
}

void DistanceImpl::init() {
    using namespace std::placeholders;

    _parent->register_mavlink_message_handler(
            MAVLINK_MSG_ID_DISTANCE_SENSOR,
            std::bind(&DistanceImpl::process_distance_sensor,this,_1),
            this);
}

void DistanceImpl::deinit() {
    _parent->unregister_all_mavlink_message_handlers(this);
}

void DistanceImpl::enable() {}

void DistanceImpl::disable() {}

/*uint32_t Distance::current_distance() const {
    return _impl->current_distance();
}

void Distance::subscribe_current_distance(CurrentDistanceCallback callback)
{
    _impl->current_distance_async(callback);
}*/

uint32_t
DistanceImpl::current_distance() const
{
    return _current_distance;
}

void DistanceImpl::process_distance_sensor(const mavlink_message_t& message){
    uint32_t currentDistance;
    currentDistance = mavlink_msg_distance_sensor_get_current_distance(&message);
    set_current_distance(currentDistance);

    if(_current_distance_subscription){
        auto callback = _current_distance_subscription;
        auto arg = current_distance();
        _parent->call_user_callback([callback,arg](){callback(arg);});
    }
}

void DistanceImpl::set_current_distance(uint32_t distance){
    _current_distance = distance;
};

void DistanceImpl::current_distance_async(Distance::CurrentDistanceCallback &callback) {
    _current_distance_subscription=callback;
}

} // namespace mavsdk

distance_impl.h:

#pragma once

#include "plugins/distance/distance.h"
#include "plugin_impl_base.h"

namespace mavsdk {

class DistanceImpl : public PluginImplBase {
public:
    DistanceImpl(System& system);
    ~DistanceImpl();

    void init() override;
    void deinit() override;

    void enable() override;
    void disable() override;

    void subscribe_current_distance(Distance::CurrentDistanceCallback callback);

    uint32_t current_distance() const;
    void current_distance_async(Distance::CurrentDistanceCallback& callback);
    DistanceImpl(const DistanceImpl&)= delete;
    DistanceImpl& operator=(const DistanceImpl&)= delete;
private:
    void set_current_distance(uint32_t distance);
    void process_distance_sensor(const mavlink_message_t& message);
    std::atomic_uint32_t _current_distance {0};
    Distance::CurrentDistanceCallback _current_distance_subscription{nullptr};
};

} // namespace mavsdk

Shouldn’t you remove that from distance_impl.h, as it is not implemented in distance_impl.cpp?

removing it didn’t fix undefined reference problem; uncommenting commented block

uint32_t Distance::current_distance() const {
    return _impl->current_distance();
}

void Distance::subscribe_current_distance(CurrentDistanceCallback callback)
{
    _impl->current_distance_async(callback);
}

in distance_impl.cpp ends with CMake error:

CMakeFiles/mavsdk_distance.dir/distance_impl.cpp.o: In function `mavsdk::Distance::current_distance() const':
/home/kris/MAVSDK/src/plugins/distance/distance_impl.cpp:32: multiple definition of `mavsdk::Distance::current_distance() const'
CMakeFiles/mavsdk_distance.dir/distance.cpp.o:/home/kris/MAVSDK/src/plugins/distance/distance.cpp:30: first defined here
CMakeFiles/mavsdk_distance.dir/distance_impl.cpp.o: In function `mavsdk::Distance::subscribe_current_distance(std::function<void (unsigned int)>)':
/home/kris/MAVSDK/src/plugins/distance/distance_impl.cpp:37: multiple definition of `mavsdk::Distance::subscribe_current_distance(std::function<void (unsigned int)>)'
CMakeFiles/mavsdk_distance.dir/distance.cpp.o:/home/kris/MAVSDK/src/plugins/distance/distance.cpp:21: first defined here

damn, I just forgot about updating CMake list xD