Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

1 duplicate symbol for architecture x86_64 with cmake

Tags:

c++

I'm trying to compile a test class using cmake on mac. When I run the cmake and make commands, I end up with this error:

duplicate symbol _main in:
    CMakeFiles/Carm.dir/CMakeFiles/3.7.0/CompilerIdCXX/CMakeCXXCompilerId.cpp.o
    CMakeFiles/Carm.dir/test.cpp.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Carm] Error 1
make[1]: *** [CMakeFiles/Carm.dir/all] Error 2
make: *** [all] Error 2

Telling me that there is a duplicate symbol in main. This code compiles perfectly when I do it with g++ alone.

car.h

#ifndef CAR_H
#define CAR_H

#include <string>

using namespace std;

namespace test {
    class Car {
    private:
            string model;
            int hp;
            int speed;

    public:
            Car(string n_model, int n_hp);
            string getModel();
            int getHp();
            int getSpeed();

    };
}
#endif

car.cpp

#include "car.h"

using namespace test;

Car::Car(string n_model, int n_hp) {
        model = n_model;
        hp = n_hp;
        speed = 0;
}

string Car::getModel() {
        return model;
}

int Car::getHp() {
        return hp;
}

int Car::getSpeed() {
        return speed;
}

test.cpp

#include "car.h"
#include <cstdio>

using namespace std;
using namespace test;

int main() {
        Car car1("BMW", 400);
        Car car2("Hellcat", 707);

        printf("hp-%d speed-%d\n", car1.getHp(), car1.getSpeed());
        printf("hp-%d speed-%d\n", car2.getHp(), car2.getSpeed());

        return 0;
}

And this is my CMakeLists.txt file

cmake_minimum_required(VERSION 2.8)

project(Carm)

file(GLOB_RECURSE Carm_SOURCES "*.cpp")
file(GLOB_RECURSE Carm_HEADERS "*.h")

set(Carm_INCLUDE_DIRS "")
foreach(_headerFile ${Carm_HEADERS})
        get_filename_component(_dir ${_headerFile} PATH)
        list(APPEND Carm_INCLUDE_DIRS ${_dir})
endforeach()
list(REMOVE_DUPLICATES Carm_INCLUDE_DIRS)

include_directories(${Carm_INCLUDE_DIRS})
add_executable(Carm ${Carm_SOURCES})
like image 660
DSchana Avatar asked Dec 24 '22 22:12

DSchana


1 Answers

In your executable you have two main functions (print out Carm_SOURCES by MESSAGE(${Carm_SOURCES})). One is in test.cpp and one in CMakeCXXCompilerId.cpp (which is a file that CMake generates to test if your CXX compiler works correctly). The GLOB_RECURSE finds and adds both of these files to Carm_SOURCES

It is not recommended to use GLOB to collect a list of source files. From the file(GLOB documentation:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.

The recommended way to list project files is to add them by hand to CMakeLists.txt.

like image 140
Cinder Biscuits Avatar answered Jan 31 '23 14:01

Cinder Biscuits