1

Im trying to build a project which uses the Myo SDK and the LeapMotion SDK on Windows 7 with CMake, Qt Creator and MinGW 4.9.2 32bit as compiler.

The MyoSDK ist working fine but I have some problems with linking the LeapMotion SDK in CMake. I found an existing sample CMake file which says that the Windows part is not finished.

Here is my CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)

project (MyoLeapController)

#set(THALMICLABSMYO_ROOT_DIR "C:/myo-sdk-win-0.9.0")

################## MYO

if(WIN32)
    set(THALMICLABSMYO_ROOT_DIR
            "${THALMICLABSMYO_ROOT_DIR}"
            CACHE
            PATH
            "Directory to search for the Thalmic Labs Myo SDK")

    if(CMAKE_SIZEOF_VOID_P MATCHES "8")
        set(_ARCH x86_64)
    else()
        set(_ARCH x86_32)
    endif()

    set(_SDKDIR Windows)

    find_path(THALMICLABSMYO_INCLUDE_DIR
            NAMES myo/libmyo.h
            PATHS "${THALMICLABSMYO_ROOT_DIR}/include")

    include(FindPackageHandleStandardArgs)

    if(CMAKE_SIZEOF_VOID_P MATCHES "8")
        find_library(THALMICLABSMYO_LIBRARY
            NAMES myo64
            PATHS "${THALMICLABSMYO_ROOT_DIR}/lib"
            PATH_SUFFIXES "${_SDKDIR}/${_ARCH}")
    else()
        find_library(THALMICLABSMYO_LIBRARY
            NAMES myo32
            PATHS "${THALMICLABSMYO_ROOT_DIR}/lib"
            PATH_SUFFIXES "${_SDKDIR}/${_ARCH}")
    endif()

    find_package_handle_standard_args(ThalmicLabsMyo
            DEFAULT_MSG
            THALMICLABSMYO_LIBRARY
            THALMICLABSMYO_INCLUDE_DIR
            ${_deps_check})

    if(THALMICLABSMYO_FOUND)
        set(THALMICLABSMYO_LIBRARIES "${THALMICLABSMYO_LIBRARY}")
        set(THALMICLABSMYO_INCLUDE_DIRS "${THALMICLABSMYO_INCLUDE_DIR}")
        mark_as_advanced(THALMICLABSMYO_ROOT_DIR)
    endif()

    mark_as_advanced(THALMICLABSMYO_INCLUDE_DIR THALMICLABSMYO_LIBRARY)
endif()

################## LEAP

IF(LEAP_INCLUDE_DIR AND LEAP_LIBRARY)
    SET(LEAP_FIND_QUIETLY TRUE)
ENDIF(LEAP_INCLUDE_DIR AND LEAP_LIBRARY)

# Set locations to search
IF(UNIX)
    SET(LEAP_INCLUDE_SEARCH_DIRS
        /usr/include
        /usr/local/include
        /opt/leap/include
        /opt/leap_sdk/include
        /opt/include INTERNAL)
    SET(LEAP_LIBRARY_SEARCH_DIRS
        /usr/lib
        /usr/lib64
        /usr/local/lib
        /usr/local/lib64
        /opt/leap/lib
        /opt/leap/lib64
        /opt/leap_sdk/lib
        /opt/leap_sdk/lib64 INTERNAL)
    SET(LEAP_INC_DIR_SUFFIXES PATH_SUFFIXES leap)
ELSE(UNIX)
    #WIN32
    SET(LEAP_INC_DIR_SUFFIXES PATH_SUFFIXES inc)
    SET(LEAP_LIB_DIR_SUFFIXES PATH_SUFFIXES lib)
ENDIF(UNIX)

# Set name of the Leap library to use
IF(APPLE)
    SET(LEAP_LIBRARY_NAME libLeap.dylib)
ELSE(APPLE)
    IF(UNIX)
        SET(LEAP_LIBRARY_NAME libLeap.so)
    ELSE(UNIX)
        # TODO Different libraries are provided for compile and runtime
        SET(LEAP_LIBRARY_NAME libLeap.lib)
    ENDIF(UNIX)
ENDIF(APPLE)

IF(NOT LEAP_FIND_QUIETLY)
    MESSAGE(STATUS "Checking for Leap")
ENDIF(NOT LEAP_FIND_QUIETLY)

# Search for header files
FIND_PATH(LEAP_INCLUDE_DIR Leap.h
    PATHS ${LEAP_INCLUDE_SEARCH_PATHS}
    PATH_SUFFIXES ${LEAP_INC_DIR_SUFFIXES})

# Search for library
FIND_LIBRARY(LEAP_LIBRARY ${LEAP_LIBRARY_NAME}
    PATHS ${LEAP_LIBRARY_SEARCH_DIRS}
    PATH_SUFFIXES ${LEAP_LIB_DIR_SUFFIXES})

SET(LEAP_INCLUDE_DIR ${LEAP_INCLUDE_DIR} CACHE STRING
    "Directory containing LEAP header files")
SET(LEAP_LIBRARY ${LEAP_LIBRARY} CACHE STRING "Library name of Leap library")

SET(LEAP_INCLUDE_DIRS ${LEAP_INCLUDE_DIR} )
SET(LEAP_LIBRARIES ${LEAP_LIBRARY} )

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Leap DEFAULT_MSG LEAP_LIBRARY LEAP_INCLUDE_DIR)

MARK_AS_ADVANCED(LEAP_INCLUDE_DIR LEAP_LIBRARY)

##################

message(${LEAP_LIBRARY})
INCLUDE_DIRECTORIES(${THALMICLABSMYO_INCLUDE_DIR} ${LEAP_INCLUDE_DIRS})
add_executable(MyoLeapController main.cpp)
target_link_libraries(MyoLeapController ${THALMICLABSMYO_LIBRARY} ${LEAP_LIBRARY})

My CMake output is:

C:/LeapSDK/lib/x86/Leap.dll
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/riecker/Documents/Masterthesis/MyoLeapController-bin

I link the found Leap library exactly the same like the Myo but I get some Linker errors.

My C++ program for testing:

#include <iostream>
#include <myo/myo.hpp>
#include <Leap.h>

int main (int argc, char *argv[])
{
    //myo::Hub hub("MyoLeapController");
    Leap::Controller controller;

    std::cout << "hi" << std::endl;
    return 0;
}

The Error Message:

[ 50%] Linking CXX executable MyoLeapController.exe
CMakeFiles\MyoLeapController.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x1d): undefined reference to `Leap::Controller::Controller()'
CMakeFiles\MyoLeapController.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x51): undefined reference to `Leap::Controller::~Controller()'
CMakeFiles\MyoLeapController.dir\build.make:98: recipe for target 'MyoLeapController.exe' failed
CMakeFiles\MyoLeapController.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x61): undefined reference to `Leap::Controller::~Controller()'
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/MyoLeapController.dir/all' failed
makefile:82: recipe for target 'all' failed
C:/Qt/Tools/mingw492_32/bin/../lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w64-mingw32/bin/ld.exe: CMakeFiles\MyoLeapController.dir/objects.a(main.cpp.obj): bad reloc address 0x0 in section `.ctors'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [MyoLeapController.exe] Error 1
mingw32-make[1]: *** [CMakeFiles/MyoLeapController.dir/all] Error 2
mingw32-make: *** [all] Error 2
10:56:32: Der Prozess "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" wurde mit dem Rückgabewert 2 beendet.
Fehler beim Erstellen/Deployment des Projekts MyoLeapController (Kit: Desktop Qt 5.6.0 MinGW 32bit)
Bei der Ausführung von Schritt "Make"

The include of the Leap SDK is working because it can find the header files only during linking I get the problem. For including and linking I am doing the same like with the Myo SDK which is working.

Can anybody help me or have an idea about this? Thank you

Antonio
  • 19,451
  • 13
  • 99
  • 197
Nico R.
  • 86
  • 11
  • It looks fine to me. Is main.cpp your only source file, or did you also implement a `Leap::Controller` class? (In case, in which file? It should also be listed in your add_executable command) – Antonio May 11 '16 at 11:31
  • no I just have the main.cpp and if I follow the Leap::Controller I get to the Leap.h – Nico R. May 11 '16 at 13:26
  • Can you remove `FIND_PACKAGE_HANDLE_STANDARD_ARGS(Leap DEFAULT_MSG LEAP_LIBRARY LEAP_INCLUDE_DIR)` and can you show the output of building (from clean) with `make VERBOSE=1`? – Antonio May 11 '16 at 13:36
  • I removed the line and the make VERBOSE=1 output is here: http://pastebin.com/tKLEGxUq – Nico R. May 11 '16 at 13:46
  • Can you try with a clean build? It looks like you have a broken object file – Antonio May 11 '16 at 13:56
  • I did - nothing changed. I also tried an older version of the SDK but I got the same error – Nico R. May 11 '16 at 13:58
  • You have more than one sdk version installed? It could be that the library binaries of one gets mixed with the headers of the other – Antonio May 11 '16 at 14:03
  • No you cant install the SDK its just the include directory with the header files and a lib file. The header files are included and working but linking the lib file doesnt work. The Myo SDK was the same type but is working ... – Nico R. May 11 '16 at 14:09
  • Can you show the content of this rsp file `CMakeFiles\MyoLeapController.dir\linklibs.rsp` – Antonio May 11 '16 at 14:19
  • C:/LeapSDK/lib/x86/Leap.lib C:/myo-sdk-win-0.9.0/lib/myo32.lib -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 – Nico R. May 12 '16 at 06:03
  • From the build directory, after a failed build, try `C:\Qt\Tools\mingw492_32\bin\g++.exe -Wl,--whole-archive CMakeFiles\MyoLeapController.dir/objects.a -Wl,--no-whole-archive -o MyoLeapController.exe -Wl,--out-implib,libMyoLeapController.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -lC:/LeapSDK/lib/x86/Leap.lib -lC:/myo-sdk-win-0.9.0/lib/myo32.lib -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32` What's the output? – Antonio May 12 '16 at 07:52
  • C:/Qt/Tools/mingw492_32/bin/../lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w 64-mingw32/bin/ld.exe: cannot find -lC:/LeapSDK/lib/x86/Leap.lib C:/Qt/Tools/mingw492_32/bin/../lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w 64-mingw32/bin/ld.exe: cannot find -lC:/myo-sdk-win-0.9.0/lib/myo32.lib collect2.exe: error: ld returned 1 exit status – Nico R. May 12 '16 at 08:43
  • Are the files there? If yes, then change your line to `C:\Qt\Tools\mingw492_32\bin\g++.exe -Wl,--whole-archive CMakeFiles\MyoLeapController.dir/objects.a -Wl,--no-whole-archive -o MyoLeapController.exe -Wl,--out-implib,libMyoLeapController.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -LC:/myo-sdk-win-0.9.0/lib/ -LC:/LeapSDK/lib/x86/ -lLeap -lmyo32 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32`. Try also the same command swapping `-lLeap` with `-lmyo32`. And: Which CMake version are you using? – Antonio May 12 '16 at 11:09
  • yeah the files are right there on these positions, swapping the parameters doesnt change anything and the output is here (too long as a comment): http://pastebin.com/qJHfe7Nx -> the same errors as in the Qt Creator Output. Im using CMake 3.3.0 – Nico R. May 12 '16 at 11:28
  • At this point I would check if the constructor/destructor of `Leap::Controller` are really defined in Leap.lib http://stackoverflow.com/questions/305287/how-to-see-the-contents-of-windows-library-lib – Antonio May 12 '16 at 13:08
  • thanks for the link :) but the constructor is definied: ??0Controller@Leap@@QAE@XZ (public: __thiscall Leap::Controller::Controller(void)) as well as the destructor: ??1Controller@Leap@@UAE@XZ (public: virtual __thiscall Leap::Controller::~Controller(void)) – Nico R. May 12 '16 at 13:36
  • Could it be that that library as a Visual Studio name mangling, incompatible with gcc? – Antonio May 12 '16 at 14:20
  • Can you try the dll in [this package](https://dl.dropboxusercontent.com/u/14672987/leap/MinGW.zip). It comes from [this thread](https://community.leapmotion.com/t/mingw-support-please/270/32). – Antonio May 12 '16 at 14:24

1 Answers1

2

Leap Motion library does not support MinGW, so the library that you are trying to link is incompatible.

However, you can try the dll in this package. It comes from this thread. It seems to be only for 32-bit, but that's apparently what you are trying to build.

From the build directory where you got the error, first see if this command line works, then you can proceed to make it work within your cmake project:

C:\Qt\Tools\mingw492_32\bin\g++.exe -Wl,--whole-archive CMakeFiles\MyoLeapController.dir/objects.a -Wl,--no-whole-archive -o MyoLeapController.exe -Wl,--out-implib,libMyoLeapController.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -LC:/myo-sdk-win-0.9.0/lib/ -LpathToTheLeapDll -lLeap -lmyo32 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

If it works, when you try the executable make sure the libLeap.dll is available in your path or in your execution directory.

Antonio
  • 19,451
  • 13
  • 99
  • 197
  • building and linking works fine now thank you so much for the solution! the programm is crashing right now but I think its another problem (device registration or something like that ...) – Nico R. May 13 '16 at 09:55
  • @NicoR. Great! This was hard to spot, but now we know what to check first when including a third party library in our projects :) – Antonio May 13 '16 at 12:06