0

Visual Studio is aweomse. It works, but I like using CLION and has no debug feature, so I try to use MINGW, but I get this weird undefined reference errors.

My CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)
project (fai C CXX)

#set(Boost_ARCHITECTURE "-x64")
set(Boost_DEBUG ON)
set(BOOST_NO_SYSTEM_PATHS ON)
set(BOOST_USE_MULTITHREADED  ON)
set(BOOST_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(BOOST_ALL_DYN_LINK OFF)

if (MSVC)
    set(BOOST_ROOT "C:/boost_1_69_0")
    set(Boost_INCLUDE_DIRS ${BOOST_ROOT})
    set(Boost_LIBRARY_DIRS ${BOOST_ROOT}/stage/lib/)
else()
    set(BOOST_ROOT "C:/boost_1_69_0")
    set(Boost_INCLUDE_DIRS ${BOOST_ROOT})
    set(Boost_LIBRARY_DIRS ${BOOST_ROOT}/stage/lib/)
    #set(BOOST_USE_WINAPI_VERSION 0x0601)
    #set(BOOST_ROOT "C:/boost_1_69_0")
    #set(BOOST_INCLUDEDIR ${BOOST_ROOT})
    #set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib/)
    #set(BOOST_ROOT "C:/MinGW")
    #set(BOOST_INCLUDEDIR ${BOOST_ROOT}/include)
    #set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib/)
    #find_package(BOOST 1.69.0 COMPONENTS chrono filesystem system REQUIRED )
endif (MSVC)

include_directories(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})

MESSAGE("Boost information:")
MESSAGE("  Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
MESSAGE("  Boost_LIBRARIES: ${Boost_LIBRARIES}")
MESSAGE("  Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}")


include_directories(${CMAKE_JS_INC})

#file(GLOB SOURCE_FILES "src/native/test/.cc" "src/native/pi-worker.cc" "src/native/arrayfire/pi-worker.cc" "src/native/arrayfire/test.cc")

add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${Boost_INCLUDE_DIRS} src/native/test/test1.cpp src/native/component/Index.cpp src/native/component/Index.h)

set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")

target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB}  )

target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api")


if (CMAKE_JS_VERSION)
else()
    add_executable (test1 src/native/test/test1.cpp src/native/component/Index.cpp src/native/component/Index.h)
endif()

So now from this part it builds and works with Visual Studio, but given I try to debug with CLION, I try to use with MingW (besides I tried CYGWIN as well, but getting the exact error!!!!).

So this is the error:

====================[ Build | test1 | Debug ]===================================
"C:\Program Files\JetBrains\CLion 2018.3.4\bin\cmake\win\bin\cmake.exe" --build C:\Users\patrikx3\Projects\sygnus\financial-ai-workspace\financial-ai-electron\cmake-build-debug --target test1 -- -j 4
Scanning dependencies of target test1
[ 66%] Building CXX object CMakeFiles/test1.dir/src/native/test/test1.cpp.obj
[ 66%] Building CXX object CMakeFiles/test1.dir/src/native/component/Index.cpp.obj
[100%] Linking CXX executable test1.exe
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(test1.cpp.obj): in function `boost::timer::cpu_timer::cpu_timer()':
C:/boost_1_69_0/boost/timer/timer.hpp:61: undefined reference to `boost::timer::cpu_timer::start()'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(test1.cpp.obj): in function `boost::timer::cpu_timer::format[abi:cxx11](short) const':
C:/boost_1_69_0/boost/timer/timer.hpp:69: undefined reference to `boost::timer::cpu_timer::elapsed() const'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/boost_1_69_0/boost/timer/timer.hpp:69: undefined reference to `boost::timer::format[abi:cxx11](boost::timer::cpu_times const&, short)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::path_traits::convert(char const*, char const*, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&)':
C:/boost_1_69_0/boost/filesystem/path.hpp:981: undefined reference to `boost::filesystem::path::codecvt()'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/boost_1_69_0/boost/filesystem/path.hpp:981: undefined reference to `boost::filesystem::path_traits::convert(char const*, char const*, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, std::codecvt<wchar_t, char, int> const&)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::is_directory(boost::filesystem::path const&)':
C:/boost_1_69_0/boost/filesystem/operations.hpp:453: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::create_directory(boost::filesystem::path const&)':
C:/boost_1_69_0/boost/filesystem/operations.hpp:574: undefined reference to `boost::filesystem::detail::create_directory(boost::filesystem::path const&, boost::system::error_code*)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::remove_all(boost::filesystem::path const&)':
C:/boost_1_69_0/boost/filesystem/operations.hpp:673: undefined reference to `boost::filesystem::detail::remove_all(boost::filesystem::path const&, boost::system::error_code*)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::detail::dir_itr_imp::~dir_itr_imp()':
C:/boost_1_69_0/boost/filesystem/operations.hpp:874: undefined reference to `boost::filesystem::detail::dir_itr_close(void*&)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::directory_iterator::directory_iterator(boost::filesystem::path const&)':
C:/boost_1_69_0/boost/filesystem/operations.hpp:905: undefined reference to `boost::filesystem::detail::directory_iterator_construct(boost::filesystem::directory_iterator&, boost::filesystem::path const&, boost::system::error_code*)'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\test1.dir/objects.a(Index.cpp.obj): in function `boost::filesystem::directory_iterator::increment()':
C:/boost_1_69_0/boost/filesystem/operations.hpp:941: undefined reference to `boost::filesystem::detail::directory_iterator_increment(boost::filesystem::directory_iterator&, boost::system::error_code*)'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\test1.dir\build.make:102: test1.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:109: CMakeFiles/test1.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:121: CMakeFiles/test1.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:130: test1] Error 2

Given I use both Visual Studio and GCC, it is a little bit different, because it uses cmake:

add_executable (test1 src/native/test/test1.cpp src/native/component/Index.cpp src/native/component/Index.h)
    if (MSVC)
    else()
        target_link_libraries(test1 boost_filesystem boost_timer boost_chrono boost_system)
    endif (MSVC)
dbush
  • 205,898
  • 23
  • 218
  • 273
Patrik Laszlo
  • 4,906
  • 8
  • 24
  • 36
  • 2
    You're obviously not linking with the required Boost libraries. – Sam Varshavchik Feb 04 '19 at 13:59
  • but what i am not linking? with visual studio with cmake it works with clion, but with mingw it is not linking, so weird! – Patrik Laszlo Feb 04 '19 at 14:07
  • i already linked here: include_directories(${Boost_INCLUDE_DIRS}) LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) – Patrik Laszlo Feb 04 '19 at 14:09
  • I believe you have to use different binaries for mingw than you do for Visual Studio. – drescherjm Feb 04 '19 at 14:57
  • You should decide on which language and compiler to use. If you are using C++, then use `g++`. For C language, use `gcc`. The C++ language allows function overloading, and many compilers use *name mangling* to handle this. The *name mangling* may interfere with the linking of external functions; this is why you should decide on whether you are using C or C++ and edit your language tags appropriately. – Thomas Matthews Feb 04 '19 at 15:02
  • 1
    Possible duplicate of [Undefined reference to boost::timer::auto\_cpu\_timer](https://stackoverflow.com/q/14689657/608639), [Undefined reference to boost::timer::auto_cpu_timer](https://stackoverflow.com/q/10565117/608639), etc. – jww Feb 04 '19 at 15:17
  • 1
    `LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}` specifies only the directories where library files are searched for. The compiler is not going to guess which libraries you want to link with. You have to specify it yourself, explicitly, by the name of each library, typically with the `-l` option. – Sam Varshavchik Feb 04 '19 at 17:23
  • 1
    By default Visual Studio will automatically link to boost using a `#pragma` I don't think this (auto linking) is done for any other compiler so you would need to specify the libraries with [target_link_libraries()](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) – drescherjm Feb 04 '19 at 17:41
  • 1
    Related: https://stackoverflow.com/questions/1685206/pragma-commentlib-xxx-lib-equivalent-under-linux – drescherjm Feb 04 '19 at 17:45
  • Do you guys how to add a -l option with cmake? I added like target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ${BOOST_LIBRARIES} boost_filesystem boost_timer boost_chrono boost_system), but i can see the Makefile is not generated with the -l option. then it would fixed this issue – Patrik Laszlo Feb 04 '19 at 18:23
  • BTW `target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ${BOOST_LIBRARIES})` probably should have worked if you did not comment out the `find_package(BOOST 1.69.0 ...)` – drescherjm Feb 04 '19 at 18:43
  • i tried that as well, for some reason i set Boost_DEBUG on, and it find the include and lib dirs and the Boost_LIBRARIES libs but the Boost_LIBRARIES variable was EMPTY! – Patrik Laszlo Feb 05 '19 at 05:25
  • I provided the complete cmake, i could only make it to work it this way, it works now with Visual Studio ,MingW, cmake.js and CLION (GNU and VS compiler) at once – Patrik Laszlo Feb 05 '19 at 05:28

1 Answers1

0

Ok, many guys help me to fix this. And it is true, but for someone that trying to compile for Visual Studio at once with CLion and cmake-js and Electron, the solution was that, because Visual Studio find out by itself, for MinGW you have to set the linked libraries (besides if you are in Windows or Linux):

#set(BOOST_ARCHITECTURE "-x64")
set(Boost_DEBUG ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
if (MSVC)
    set(BOOST_NO_SYSTEM_PATHS ON)
    set(BOOST_USE_MULTITHREADED  ON)
    set(BOOST_USE_STATIC_LIBS ON)
    set(BOOST_USE_STATIC_RUNTIME OFF)
    set(BOOST_ALL_DYN_LINK OFF)

    set(BOOST_ROOT "C:/boost_1_69_0")
    set(BOOST_INCLUDE_DIRS ${BOOST_ROOT})
    set(BOOST_LIBRARY_DIRS ${BOOST_ROOT}/stage/lib/)
else()
    #set(BOOST_ROOT "C:/boost_1_69_0")
    #set(BOOST_INCLUDE_DIRS ${BOOST_ROOT})
    #set(BOOST_LIBRARY_DIRS ${BOOST_ROOT}/stage/lib/)

    if (WIN32)
        set(BOOST_ROOT "C:/MinGW")
        set(BOOST_INCLUDE_DIRS ${BOOST_ROOT}/include)
        set(BOOST_LIBRARY_DIRS ${BOOST_ROOT}/lib/)
    endif (WIN32)
    find_package(Boost COMPONENTS timer filesystem system REQUIRED )
endif (MSVC)

include_directories(${BOOST_INCLUDE_DIRS})
LINK_DIRECTORIES(${BOOST_LIBRARY_DIRS})
if (CMAKE_JS_VERSION)
else()
    add_executable (test1 src/native/test/test1.cpp src/native/component/Index.cpp src/native/component/Index.h)
    if (NOT MSVC)
        target_link_libraries(test1 boost_filesystem boost_timer boost_chrono boost_system)
    endif (NOT MSVC)
endif()
Srivishnu
  • 759
  • 1
  • 6
  • 15
Patrik Laszlo
  • 4,906
  • 8
  • 24
  • 36