Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ compilation error: multiple definition of `main' but only 1 main function in project

I working on lib and have a unit tests for it based on gtest framework. So setup for unittests compiled fine. However when I try a little bit different setup for measuring code coverage, compilation fails with this error:

[ 10%] Linking CXX executable coverageRun.exe
CMakeFiles/coverageRun.dir/tests/src/main.cpp.o: In function `main':
/cygdrive/d/code/tests/src/main.cpp:24: multiple definition of `main'
CMakeFiles/coverageRun.dir/CMakeFiles/3.6.3/CompilerIdCXX/CMakeCXXCompilerId.cpp.o:/cygdrive/d/code/cmake-build-debug/CMakeFiles/3.6.3/CompilerIdCXX/CMakeCXXCompilerId.cpp:514: first defined here
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/coverageRun.dir/build.make:1215: coverageRun.exe] Error 1
make[2]: *** [CMakeFiles/Makefile2:101: CMakeFiles/coverageRun.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:113: CMakeFiles/coverageRun.dir/rule] Error 2
make: *** [Makefile:175: coverageRun] Error 2

and this is how my main.cpp file looks like:

#include <iostream>
#include <gtest/gtest.h>
#include "helpers/helper.h"
#include "helpers/pathHelper.h"

namespace code{

            bool isPreconditionsOK(){
                auto testRoot = helper::readEnvVar(helper::path::TEST_ROOT);
                bool result = true;
                if(testRoot.empty()){
                    std::cerr << "Env. variable " << helper::path::TEST_ROOT
                                       << " should be set before test start." << std::endl;
                    result = false;
                }
                return result;
            }
}


int main(int argc, char **argv) {
    if(code::isPreconditionsOK()){
        testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    };
}

So what could I try to fix this?


There is how "CmakeCxxCompilerId.cpp" looks like: link

like image 350
silent_coder Avatar asked Dec 02 '22 13:12

silent_coder


2 Answers

I assume you using file(GLOB_RECURSE... in top level directory to get list of sources for your project. That's approach is very dangerous and you really could see it now, since you getting into troubles. But as workaround try something like this:

file(GLOB_RECURSE REMOVE_CMAKE "cmake-build-debug/*")
list(REMOVE_ITEM your_list_of_sources ${REMOVE_CMAKE})

this will solve your immediate problem, but you need to reathink general approach to avoid similar story in future.

Because right know you searching across all the sources in directory and compiler simply find 2 main function, which is ofcourse not allowed in C++ world. Code snippet I provide to you just exclud code in cmake-build-debug folder from compilation.

like image 80
Ph0en1x Avatar answered Dec 20 '22 08:12

Ph0en1x


Look https://public.kitware.com/Bug/view.php?id=11043 Use something like this:

FILE(GLOB TARGET_H "${CMAKE_SOURCE_DIR}/*.h")
FILE(GLOB TARGET_CPP "${CMAKE_SOURCE_DIR}/*.cpp")
SET(TARGET_SRC ${TARGET_CPP} ${TARGET_H})
...

If one will use GLOB_RECURSE instead, it will also check CMakeFiles folder and what is inside. It will find cpp file with main function generated by cmake, that causes multiple definition of "main" function.

like image 22
Evgeny Pogorelov Avatar answered Dec 20 '22 09:12

Evgeny Pogorelov