Qt6 and CMake - Unable to Link Library (R3DSDK)

Hello All,

New to CMkae and been struggling with try to build a simple CMake project to link to a library using Qt6 and CMake. Below is my CMakeList.txt and below that is the Compiler output. There seems to be many ways to define a path to both the header and library files but I was unable to get any of them to work. I resorted to the using absolute path since that seems to the least problematic. If someone could take a look at it and let me know my mistake, I would appreciate it.

Thanks,
Ben


cmake_minimum_required(VERSION 3.19)
project(Hello LANGUAGES CXX)

find_package(Qt6 6.5 REQUIRED COMPONENTS Core)

qt_standard_project_setup()

add_library(MyExternalLib STATIC IMPORTED) # For a static library
set_property(TARGET MyExternalLib PROPERTY IMPORTED_LOCATION “C:/Users/Dell-9710/Documents/Qt/R3D/Qt_R3DLib/Hello/R3DSDK-2017MD.lib”) # For static

qt_add_executable(Hello
main.cpp
R3DSDK.h
R3DSDKMetadata.h
)

target_link_libraries(Hello
PRIVATE
Qt::Core
MyExternalLib
)

include(GNUInstallDirs)

install(TARGETS Hello
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)


13:57:08: Running steps for project Hello…
13:57:08: Starting: “C:\Qt\Tools\CMake_64\bin\cmake.exe” --build C:/Users/Dell-9710/Documents/Qt/R3D/Qt_R3DLib/Hello/build/Desktop_Qt_6_9_1_MinGW_64_bit-Debug --target all
[1/4 5.6/sec] Automatic MOC and UIC for target Hello
[2/3 1.2/sec] Building CXX object CMakeFiles/Hello.dir/main.cpp.obj
[3/3 1.6/sec] Linking CXX executable Hello.exe
FAILED: Hello.exe
C:\WINDOWS\system32\cmd.exe /C “cd . && C:\Qt\Tools\mingw1310_64\bin\g++.exe -DQT_QML_DEBUG -g CMakeFiles/Hello.dir/Hello_autogen/mocs_compilation.cpp.obj CMakeFiles/Hello.dir/main.cpp.obj -o Hello.exe -Wl,–out-implib,libHello.dll.a -Wl,–major-image-version,0,–minor-image-version,0 C:/Qt/6.9.1/mingw_64/lib/libQt6Core.a C:/Users/Dell-9710/Documents/Qt/R3D/Qt_R3DLib/Hello/R3DSDK-2017MD.lib -lmpr -luserenv -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd .”
C:/Qt/Tools/mingw1310_64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/Hello.dir/main.cpp.obj: in function main': C:/Users/Dell-9710/Documents/Qt/R3D/Qt_R3DLib/Hello/main.cpp:27: undefined reference to R3DSDK::InitializeSdk(char const*, unsigned int)’
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
13:57:10: The command “C:\Qt\Tools\CMake_64\bin\cmake.exe --build C:/Users/Dell-9710/Documents/Qt/R3D/Qt_R3DLib/Hello/build/Desktop_Qt_6_9_1_MinGW_64_bit-Debug --target all” terminated with exit code 1.
13:57:10: Error while building/deploying project Hello (kit: Desktop Qt 6.9.1 MinGW 64-bit)
13:57:10: When executing step “Build”
13:57:10: Elapsed time: 00:02.

These likely need to be added with target_include_directories() (or in HEADER_SETS?), so not as a part of qt_add_executable(). And of course main.cpp should #include them too, since it seems to be using those functions.

I am able to compile and link the same source/header/library files using the following VSCode CLI command but not able to replicate it using Qt and CMake.

cl “C:\Users\Dell-9710\Documents\Qt\R3D\R3D_LL\Hello\GetSdkVersionSample.cpp” /nologo /W3 /O2 /D NDEBUG /EHsc /MD /I"C:\Users\Dell-9710\Documents\Qt\R3D\R3D_LL\Hello" /link “C:\Users\Dell-9710\Documents\Qt\R3D\R3D_LL\Hello\R3DSDK-2017MD.lib” /out:MainCheckSdkVersion.exe

Likely because with this one you do have the headers path:

/I"C:\Users\Dell-9710\Documents\Qt\R3D\R3D_LL\Hello"

So as I said, you need to add that path to headers in your CMake project.

This is using the cl compiler (MSVC). In your CMake example you are using g++. That is likely the reason it can’t find symbols from your R3DSDK-2017MD.lib library to link. You need to use cl and not g++. To do that with CMake make sure you run CMake from a command prompt where the compiler is initialized correctly by running vcvars.bat.

Hello retif, Thanks for the information. CMake just completely boggles my mind. Honestly, I’ve struggles with it for several days and none of it makes sense to me. Let me see how I can implement what you wrote on my CMakeList file. Thanks!

Yes, I was just using the cl compiler/linker to confirm that what I was doing with Qt (using gcc) was correct. But my goal is to use the Qt IDE so I would like to make it work with the standard Qt setup and minimize issues down the road.

I added the Include directory using target_include_directories() and I’m still getting the “undefined reference to” from the linker. Pleaes let me know if there is something else I can try, Also, is there a complete/working project, not just code snipets, that links to an external librayr that I can look at. For some reason, all my search results are AI snipets. Thanks!


cmake_minimum_required(VERSION 3.16)

project(helloworld VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Core)
message(STATUS “Qt6_FOUND: ${Qt6_FOUND}”)

message(STATUS “CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}”)
set(CMAKE_INCLUDE_PATH “C:/Users/Dell-9710/Documents/Qt/R3D/R3DSDKv9_0_1/Include”)
set(CMAKE_LIBRARY_PATH “C:/Users/Dell-9710/Documents/Qt/R3D/R3DSDKv9_0_1/Lib/win64”)

message(STATUS “The CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}”)
message(STATUS “CMAKE_INCLUDE_PATH: ${CMAKE_INCLUDE_PATH}”)
message(STATUS “CMAKE_LIBRARY_PATH: ${CMAKE_LIBRARY_PATH}”)

#qt_standard_project_setup()

add_executable(helloworld
main.cpp

R3DSDK.h

R3DSDKDefinitions.h

)

target_include_directories(helloworld PUBLIC “C:/Users/Dell-9710/Documents/Qt/R3D/R3DSDKv9_0_1/Include”)
target_link_libraries(helloworld PUBLIC Qt6::Core “C:/Users/Dell-9710/Documents/Qt/R3D/R3DSDKv9_0_1/Lib/win64/R3DSDK-2017MD.lib”)

message(STATUS “End of CMAKELIST.TXT!”)

added the Include directory using target_include_directories() and I’m still getting the “undefined reference to” from the linker

Then it could be because if what Bill said about the compilers mix.

I could try to reproduce your problem if you shared your (simplified) project somewhere together with that pre-built R3DSDK library, ideally as a Git repository (that will make it easier to suggest patches).

I really appreciate that! Let me put my project into a single simplified pacakge. Is it best to just Zip the files?

By Git I was implying hosting it on GitHub or elsewhere, but a ZIP archive would be fine too.

I’m really unfamiliar with Git but here is the Zip file. Everything is included and I changed all reference from absolute to reltative. Thanks again!

R3D_LL.zip (2.4 MB)

Yes, I could reproduce your initial problem with MSYS environment using MinGW/GCC:

undefined reference to `R3DSDK::InitializeSdk(char const*, unsigned int)'

I would assume this is because the library was build with MSVC, so it will only work if your project is also built with MSVC and not MinGW/GCC, which I guess is what Bill meant.

Confirming that, I could successfully build it from MSVC PowerShell prompt (which Bill has already mentioned too):

> cd /path/to/Hello
> mkdir build
> cd build
> cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="d:/path/to/my/qt/6.8.1-static" ..
> cmake --build .
> .\helloworld.exe
Failed to initialize SDK: 2

As you can see, the project compiles and links successfully. The resulting application fails to initialize SDK, but that’s another problem.

I have also tried building your project not from bare CLI but from Qt Creator, which is apparently what you are after, and that worked as well, but of course I had MSVC there too, while you are likely trying to use MinGW. So what you need to do is change the C/C++ compiler for your Qt kit from MinGW/GCC to MSVC.

If anything, there are some other (not exactly related?) issues in your project, which I’ve fixed here. In short:

  • it is redundant to have duplicates of R3DSDK headers both in the Include folder and in the project root folder
    • same applies to the R3DSDK-2017MD.lib binary
  • using CMAKE_INCLUDE_PATH to add paths to headers isn’t exactly a common way
    • same applies to CMAKE_LIBRARY_PATH

Thanks for taking the time to fix my issue. I didn’t understand what Bill was trying to tell me before about MSVC. I didn’t even realize that LIB had to use the same compiler. So let me make those changes. Thanks again!

That part I am not entirely sure about myself, but evidently it does matter, and actually it does seem to make sense too, as in the particular case of MSVC and MinGW/GCC it is different(?) C++ runtimes.