1

I have a header file for the namespace Segmentation called segmentation.h. The functions declared in the header are defined in the implementation file segmentation.cpp. The namespace is used in mainwindow.cpp and hence it has been included in the said file. But when I am trying to compile project, I get

1 duplicate symbols found for architecture x86_64

I do understand duplicate symbols found for architecture x86_64 errors occur when you try to include a module multiple times during linkage. But I have only included segmentation.h only once in the above mentioned file.

segmentation.h

#ifndef SEGMENTATION_H
#define SEGMENTATION_H

#include <QObject>
#include <opencv2/opencv.hpp>
#include <QPixmap>

namespace Segmentation
{
    int k;
    cv::Mat getSegments(cv::Mat inputImage);
    cv::Mat sampleInput(cv::Mat &inputImage);
}

#endif // SEGMENTATION_H

segmentation.cpp

#include "segmentation.h"
#include <opencv2/opencv.hpp>
#include <iostream>

cv::Mat Segmentation::getSegments(cv::Mat inputImage)
{

    Segmentation::sampleInput(inputImage);

    //Incomplete code

    return inputImage;
}

cv::Mat Segmentation::sampleInput(cv::Mat &inputImage)
{
    std::cout << "Size: " << inputImage.size << std::endl;
    std::cout << "Rows: " << inputImage.rows << std::endl;
    std::cout << "Cols: " << inputImage.cols << std::endl;
    std::cout << "Size rows x cols: " << inputImage.rows * inputImage.cols << std::endl;

    //Incomplete code

    return inputImage;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPixmap>
#include <QGraphicsView>
#include <QLabel>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <opencv2/opencv.hpp>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_loadImageButton_clicked();
    void on_clearScreenButton_clicked();
    void on_segmentButton_clicked();

private:
    Ui::MainWindow *ui;
    cv::Mat _rawInputImage;
    QPixmap _inputImage;
    QPixmap _outputImage;
    QGraphicsScene _scene;
    QGraphicsPixmapItem _inputImagePixmapItem;

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QString>
#include <QDebug>
#include <QRectF>
#include <segmentation.h>

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    MainWindow::setWindowState(Qt::WindowFullScreen);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_loadImageButton_clicked()
{
    QFileDialog fileDialog(this, Qt::Dialog);
    fileDialog.setFileMode(QFileDialog::ExistingFile);
    fileDialog.setNameFilter("*.jpg *.png *.jpeg");
    fileDialog.setViewMode(QFileDialog::Detail);
    fileDialog.exec();

    QStringList selectedFileName = fileDialog.selectedFiles();
    QString selectedFile = selectedFileName.at(0);
    _inputImage.load(selectedFile);
    _rawInputImage = cv::imread(selectedFile.toStdString());

    _inputImagePixmapItem.setPixmap((_inputImage));
    _scene.addItem(&_inputImagePixmapItem);
    this->ui->inputImageViewWidget->setScene(&_scene);
    this->ui->inputImageViewWidget->fitInView(&_inputImagePixmapItem, Qt::KeepAspectRatio);

    fileDialog.saveState();
    return;
}

void MainWindow::on_clearScreenButton_clicked()
{
    _scene.removeItem(&_inputImagePixmapItem);
    return;
}

void MainWindow::on_segmentButton_clicked()
{
    cv::Mat segmentedOutputImage = Segmentation::getSegments(_rawInputImage);
}

Compile output

14:15:59: Running steps for project LaundroBotQt...
14:15:59: Configuration unchanged, skipping qmake step.
14:15:59: Starting: "/usr/bin/make" 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -headerpad_max_install_names -stdlib=libc++ -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -mmacosx-version-min=10.9  -Wl,-rpath,/Users/Vino/Documents/Qt/5.8/clang_64/lib -o LaundroBotQt.app/Contents/MacOS/LaundroBotQt main.o mainwindow.o segmentation.o moc_mainwindow.o   -F/Users/Vino/Documents/Qt/5.8/clang_64/lib -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_features2d -lopencv_ml -lopencv_flann -lopencv_imgproc -lopencv_photo -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL 
duplicate symbol __ZN12Segmentation1kE in:
    mainwindow.o
    segmentation.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [LaundroBotQt.app/Contents/MacOS/LaundroBotQt] Error 1
14:15:59: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project LaundroBotQt (kit: Desktop Qt 5.8.0 clang 64bit)
When executing step "Make"
14:15:59: Elapsed time: 00:01.

GitHub repo link

I am not quite sure how to fix this problem. I have read through StackOverflow, but my issue seems bizarre. Any help is appreciated.

Vino
  • 2,111
  • 4
  • 22
  • 42

1 Answers1

2

The problem is here, in segmentation.h:

namespace Segmentation
{
   int k;
   [...]

Here you are both declaring and defining storage for the variable named k in the Segmentation namespace. The problem with that is that if more than one .cpp file #include's segmentation.h (which will almost certainly happen), then the variable Segmentation::k will have storage declared for it in more than one .cpp file, leading to the duplicate-symbols error you see.

To get around that problem, do this in segmentation.h instead:

namespace Segmentation
{
   extern int k;
   [...]

... and then in one of your .cpp files (probably segmentation.cpp would be the most appropriate one), add the storage separately, like this:

namespace Segmentation
{
   int k;
};

That way storage space for Segmentation::k will be allocated only in that one .cpp file instead of many of them.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234