linking GLEW with MinGW64 - undefined reference to `__imp_glewExperimental' and `__imp___glewGenVertexArrays' - c++

undefined reference to '[various things from GLEW library]'
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(newerOpenGLTest)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(newerOpenGLTest ${SOURCE_FILES})
find_package(OpenGL)
# tell it where to look for glew
set(CMAKE_PREFIX_PATH "F:/glew-2.0.0")
set(CMAKE_LIBRARY_PATH "F:/glew-2.0.0/lib/Release/x64")
find_package(GLEW REQUIRED)
if (GLEW_FOUND)
message(${GLEW_INCLUDE_DIRS})
message(${GLEW_LIBRARIES})
# Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
#Find any version 2.X of SFML
#See the FindSFML.cmake file for additional details and instructions
find_package(SFML 2 REQUIRED graphics window system)
if(SFML_FOUND)
include_directories(
${GLEW_INCLUDE_DIRS}
${SFML_INCLUDE_DIR}
)
target_link_libraries(
newerOpenGLTest
${GLEW_LIBRARIES}
${SFML_LIBRARIES}
${SFML_DEPENDENCIES}
${OPENGL_gl_LIBRARY}
)
endif()
endif()
This is the output from Cmake:
F:/glew-2.0.0/include
F:/glew-2.0.0/lib/Release/x64/glew32.lib
-- Found SFML 2.4.2 in F:/SFML-2.4.2 for GCC 6.1.0 MinGW (SEH) - 64-bit/include
-- Configuring done
-- Generating done
-- Build files have been written to: F:/Users/Doug/CLionProjects/newerOpenGLTest/cmake-build-debug
Everything looks fine to me there. It finds GLEW and finds locations for the include files and libraries.
Here is my main.cpp:
#include <GL/glew.h>
#include <SFML/Window.hpp>
int main() {
sf::Window window(sf::VideoMode(800, 600), "openGL");
window.setVerticalSyncEnabled(true);
window.setActive(true);
// Initialize GLEW
glewExperimental = true;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
bool running = true;
while (running) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
running = false;
}
}
}
return 0;
}
Here is the output from linking:
Linking CXX executable newerOpenGLTest.exe
CMakeFiles\newerOpenGLTest.dir\build.make:100: recipe for target 'newerOpenGLTest.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/newerOpenGLTest.dir/all' failed
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/newerOpenGLTest.dir/rule' failed
Makefile:117: recipe for target 'newerOpenGLTest' failed
CMakeFiles\newerOpenGLTest.dir/objects.a(main.cpp.obj): In function `main':
main.cpp:xx: undefined reference to `__imp_glewExperimental'
main.cpp:xx: undefined reference to `__imp___glewGenVertexArrays'
main.cpp:xx: undefined reference to `__imp___glewBindVertexArray'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [newerOpenGLTest.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/newerOpenGLTest.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/newerOpenGLTest.dir/rule] Error 2
mingw32-make.exe: *** [newerOpenGLTest] Error 2
Undefined reference to 3 GLEW elements.
Notice that it does not say undefined reference to '__imp_glewInit'
So it is linking some of GLEW, but not everything.
I run glewinfo.exe and the output has glGenVertexArrays: OK
I think that means my driver supports that function.

Apparently, the binaries from the GLEW website only work for Visual C++.
If you want to use it with MinGW, you have to compile your own.
Instructions copied from here:
https://www.opengl.org/discussion_boards/showthread.php/198730-How-do-I-build-GLEW-for-mingw-w64-using-cmake-on-Windows
1) Download the GLEW Source files. DO NOT download the 32/64bit Window Binaries unless you're using Visual Studio, and if you are, you wouldn't be reading this.
2) Download, install, and update msys2. Unfortunately, I was unable to find a way to compile GLEW (for mingw-w64) without it, but trust me, it's painless, and once you're done, you don't need msys2, we're only using it to compile the GLEW lib files. Follow the update instructions at the official msys2 site before you do anything else. It's only 3 steps long.
Warning: For some strange reason, once you pass the second update step, the msys2 command prompt shortcut stops working on my computer. Just navigate to the c:/msys2 folder and run msys2_shell.cmd if it does.
3) You'll need mingw-w64 for msys2. Some Stack Overflow answers suggest downloading both 64bit and 32bit versions of mingw, but since I'm no expert on the matter, it turned into a pain, so I was better off just downloading the 64bit version which is what I'm using and targeting. Run the following cmd in the msys2 cmd prompt: $ pacman -S gcc make mingw-w64-x86_64-gcc
3-a) You'll need make and gcc for msys2. Run this in the msys2 cmd line: $ pacman -S gcc make
4) Once you're done downloading mingw-w64, gcc, and make. You're ready to compile GLEW. Unzip the source files you downloaded earlier, and put it into you're C:\msys64\home\yourusername folder.
5) Open the msys2 cmd prompt, navigate to the glew2.x.x folder and run the following CMDs in the following order (as soon as each one is done):
5-a) make
5-b) make install
5-c) make install.all
6) You might get some errors and warnings, don't worry. Look in the lib folder within the glew2.x.x folder, and you'll see the lib files you'll need.
7) Copy glew32.dll into the same folder where your programs executable is, and libglew32.a into your program's lib folder.

Related

Linker error with Libtorch, Cmake and CLion

I am just starting out with libtorch and seem to have run into a rather serious linker issue. Previously, I was able to at least build other projects with torch (that others had created), but now that I've tried to create my own simple file, nothing seems to be building anymore.
I have manually installed the latest MacOS build in my root directory:
/Users/jlenz/libtorch/share/cmake/Torch
I am using CLion and have the following CmakeLists.txt:
cmake_minimum_required(VERSION 3.23)
project(midi_plugin)
set(CMAKE_CXX_STANDARD 17)
add_executable(midi_plugin main.cpp)
set(CMAKE_PREFIX_PATH "~/libtorch/share/cmake")
find_package(Torch REQUIRED)
target_link_libraries(midi_plugin "${TORCH_LIBRARIES}")
One thing that is noticeable, although the cmake 'succesfully' builds, it displays this in the process:
-- MKL_ARCH: intel64
-- MKL_ROOT /Users/jlenz/opt/miniconda3
-- MKL_LINK: dynamic
-- MKL_INTERFACE_FULL: intel_ilp64
-- MKL_THREADING: intel_thread
-- MKL_MPI: mpich
Once I try to build the project (which is just 'hello world' with torch included) I get the following error:
FAILED: midi_plugin
: && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk -mmacosx-version-min=12.5 -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/midi_plugin.dir/main.cpp.o -o midi_plugin -Wl,-rpath,/Users/jlenz/libtorch/lib /Users/jlenz/libtorch/lib/libc10.dylib /Users/jlenz/libtorch/lib/libkineto.a /Users/jlenz/libtorch/lib/libtorch.dylib /Users/jlenz/libtorch/lib/libtorch_cpu.dylib /Users/jlenz/libtorch/lib/libc10.dylib -lmkl_intel_ilp64 -lmkl_core -lmkl_intel_thread && :
ld: library not found for -lmkl_intel_ilp64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Would anyone know how to solve this? I have tried addressing it with a colleague who has used libtorch quite a bit and he can't identify the issue either. Many thanks in advance.
Posting my solution here in case someone else runs into a similar issue.
It turns out the issue was with my brew installation of torch, which was being referenced implicitly. To fix it, all I had to do was:
Brew install pytorch
It asked permission to overwrite some files that had issues, which I granted. Afterwards, all of my Torch projects are working perfectly.

CMake does not link Boost correctly, but compiling from a terminal does

I am running Ubuntu 21.04 on a Raspberry Pi 4b (8gb), and am using QtCreator for an IDE, with default settings, which landed on Clang as a compiler.
Most code (excepting libconfig) ran perfectly fine, but for reasons unknown to me, linking Boost::filesystem and Boost::system is proving impossible. See the minimal code below for the snippet I have been testing with:
#include <boost/filesystem.hpp>
#include <iostream>
int main()
{
boost::filesystem::path full_path(boost::filesystem::current_path());
std::cout << "Current path is : " << full_path << std::endl;
return 0;
}
If I open a terminal on this source file, and run
clang++ main.cpp -lboost_system -lboost_filesystem
I get an output that behaves exactly as one'd expect, reporting '/home/username/repo/boostsandbox/'.
Now, if I attempt to compile with CMake, using the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(boostsandbox LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Compiler Options --------------------
add_compile_options(--verbose)
# Package Management ------------------
find_package( Boost COMPONENTS filesystem system REQUIRED)
include_directories(... ${Boost_INCLUDE_DIRS})
link_directories(... ${Boost_LIBRARY_DIRS})
message("Found Boost, {${Boost_LIBRARIES}}, at ${Boost_INCLUDE_DIR}")
add_executable(boostsandbox main.cpp)
link_libraries(boostsandbox Boost::filesystem Boost::system)
I receive the CMake parsing message 'Found Boost, {Boost::filesystem;Boost::system}, at /usr/include', and building halts at compile time, reporting the following:
/usr/bin/ld: CMakeFiles/boostsandbox.dir/main.cpp.o: in function `boost::filesystem::current_path()':
/usr/include/boost/filesystem/operations.hpp:244: undefined reference to `boost::filesystem::detail::current_path(boost::system::error_code*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[2]: *** [CMakeFiles/boostsandbox.dir/build.make:133: boostsandbox] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/boostsandbox.dir/all] Error 2
gmake: *** [Makefile:103: all] Error 2
10:13:31: The process "/usr/bin/cmake" exited with code 2.
I am starting to feel like I've used every trick possible by now (including the C++11 enum define that gets Boost to work for some people), but I'm completely stumped. Please help!
TLDR:
Compiling with g++ or clang++, linking lboost_filesystem + lboost_system, building and executing functions perfectly. Building via the QtCreator IDE using CMake, compilation halts on a linking error, while Boost is found and linked.

Undefined reference using external library with CMake and Conan

I am trying to develop a program that communicates with a PCSC USB reader using Conan and CMake with the LibLogicalAccess library. I followed the instructions of building and installing the library which seemed to have gone fine. I created a small simple console project with a "main.cpp" file. Following the C++ guide on the wiki of the library I tried to call a function from the library which resulted in a "Undefined reference to function. I know there are a lot of topics covering this but I have read as many as I could but could not seem to find the right solution.
I don't have much experience with Ubuntu/CMake/Conan/C++ so it might as well be a very simple fix.
OS: Kubuntu 18.04
Lang: C++
Related software: LibLogicalAccess
2.2.1,
CMake 3.17.1,
Conan 1.25.0
main.cpp
#include <iostream>
#include <logicalaccess/dynlibrary/librarymanager.hpp>
#include <logicalaccess/readerproviders/readerconfiguration.hpp>
#include <logicalaccess/cards/chip.hpp>
int main()
{
std::cout << "Program started\n";
// Reader configuration object to store reader provider and reader unit selection.
std::shared_ptr<logicalaccess::ReaderConfiguration> readerConfig(new logicalaccess::ReaderConfiguration());
// Set PCSC ReaderProvider by calling the Library Manager which will load the function from the corresponding plug-in
readerConfig->setReaderProvider(logicalaccess::LibraryManager::getInstance()->getReaderProvider("PCSC"));
std::cout << "after..\n";
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(project)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
set(CMAKE_CXX_FLAGS "-I /usr/include/PCSC")
add_executable(project main.cpp)
target_link_libraries(project PUBLIC CONAN_PKG::LogicalAccess)
When I try to build the program using cmake --build . this is the output:
[100%] Linking CXX executable bin/project
CMakeFiles/project.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x140): undefined reference to `logicalaccess::LibraryManager::getReaderProvider(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status
CMakeFiles/project.dir/build.make:191: recipe for target 'bin/project' failed
make[2]: *** [bin/project] Error 1
CMakeFiles/Makefile2:95: recipe for target 'CMakeFiles/project.dir/all' failed
make[1]: *** [CMakeFiles/project.dir/all] Error 2
Makefile:103: recipe for target 'all' failed
make: *** [all] Error 2
The weird part is that the first line of code: std::shared_ptr<logicalaccess::ReaderConfiguration> readerConfig(...) works fine and the second line of code gives an undefined reference.
I have tried other functions in the same file which give the same result. The file compiles and runs fine when I remove the last "setReaderProvider" line of code. Also tried a lot of different little adjustments regarding the conanfile.txt and CMakeLists.txt.
Your error says:
main.cpp:(.text+0x140): undefined reference to `logicalaccess::LibraryManager::getReaderProvider(std::__cxx11::basic_string, std::allocator > const&)'
It occurs because your CMake is using libstdc++11 to link, however, Conan is configured to use libstdc++ due backward compatibility.
You need to update your default libcxx:
conan profile update settings.compiler.libcxx=libstdc++11 default
Please, read this section in Conan docs How to Manage GCC ABI to get more information.
Also, it's explained on step 5 of Getting Started.
Now when building again, you will need that your local packages won't be available, because it's a new package, using different settings, so you will need to install, or build from sources. The link to libstdc++11 is automatically managed by Conan, it passes the definitions to CMake.
Regards!

Minimal example with GLFW fails because of undefined symbols for architecture x86_64

I am trying to compile the following minimal example for GLFW:
#include <GLFW/glfw3.h>
#include <thread>
int main() {
glfwInit();
std::this_thread::sleep_for(std::chrono::seconds(1));
glfwTerminate();
return 0;
}
My CMakeLists.txt file is:
cmake_minimum_required(VERSION 3.9)
project(viewer)
set(CMAKE_CXX_STANDARD 11)
find_package(glfw3 3.2 REQUIRED)
include_directories(${GLFW_INCLUDE_DIRS})
add_executable(viewer main.cpp)
target_link_libraries(viewer ${GLFW_LIBRARIES})
If I try to compile the code, it fails with the following error message:
[ 50%] Linking CXX executable visualiser
Undefined symbols for architecture x86_64:
"_glfwInit", referenced from:
_main in main.cpp.o
"_glfwTerminate", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [visualiser] Error 1
make[2]: *** [CMakeFiles/visualiser.dir/all] Error 2
make[1]: *** [CMakeFiles/visualiser.dir/rule] Error 2
make: *** [visualiser] Error 2
I see the similar questions, e.g.:
Trouble compiling GLFW, undefined symbols
http://dudandan.com/2017/02/15/Setup-glfw-and-glew/
But their solutions did not really help.
UPD: Following the comment of #thomas_f, I modified my CMakeLists.txt file as follows:
cmake_minimum_required(VERSION 3.9)
project(viewer)
set(CMAKE_CXX_STANDARD 11)
find_package(glfw3 3.2 REQUIRED)
include_directories(${GLFW3_INCLUDE_DIR})
add_executable(viewer main.cpp)
target_link_libraries(viewer ${GLFW3_LIBRARY})
message(GLFW LIB: ${GLFW3_LIBRARY})
I also made sure that there is no CMakeCache.txt in my build directory:
$ ls -a
. .. .idea CMakeLists.txt cmake-build-debug main.cpp
However, I still get the same error message. It seems, that
/Applications/CLion.app/Contents/bin/cmake/bin/cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" ........./viewer
GLFWLIB:
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/denis/Documents/projects/theia/code/visualiser/cmake-build-debug
[Finished]
So it seems that ${GLFW3_LIBRARY} is not defined.
From glfw3Config.cmake:
# - Config file for the glfw3 package
# It defines the following variables
# GLFW3_INCLUDE_DIR, the path where GLFW headers are located
# GLFW3_LIBRARY_DIR, folder in which the GLFW library is located
# GLFW3_LIBRARY, library to link against to use GLFW
It seems that you are referencing the wrong variables. Also, there is no need to invoke include_directories() in this case, since GLFW is obviously installed in a standard location, i.e. your compiler already knows where to find it.
Edit: I was able to reproduce the linker error and changing the variable name to GLFW3_LIBRARY fixed it.
Clarification: Change your link command to: target_link_libraries(viewer ${GLFW3_LIBRARY})
Update if you're on Mac OS: If you're experiencing the same issues as OP, it may be because glfw3Config.cmake does not export the variables mentioned in my answer. Instead it creates an imported library, glfw. In this case, the correct way to link to glfw would be to simply do this: target_link_libraries(<target> glfw).
If glfw was installed using brew, you should find the .cmake-files under: /usr/local/Cellar/glfw/<version>/lib/cmake/glfw3.

Compiling Qt5 hello world .cpp file under Windows using MinGW-w64 gives "undefined reference" error

When I run make to compile the Makefile produced by cmake, to compile an hello world example of a Qt5 application, the compilation fails with the following error:
Why is the compilation failing?
(details of what exactly I'm trying to do follow)
I'm under Windows 10, using the Qt5.5 binaries downloaded from Qt official website, mingw-w64 gcc and g++ shipped with WinBuilds, and cmake v3.6 downloaded from the official website and installed with the Windows win64-x64 Installer.
I'm trying to compile the following hello world test file, provided in Qt5's official wiki:
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication app (argc, argv);
return app.exec();
}
The Makefile is built successfully using the command cmake -G "MinGW Makefiles" .. from a folder called build inside the directory containing the .cpp file. The following CMakeLists.txt file (taken from Qt5's cmake wiki page, with the addition of the specification of the CMAKE_PREFIX_PATH variable, which is required as for example discussed in this SO post) was used:
cmake_minimum_required(VERSION 2.8.11)
SET(CMAKE_C_COMPILER C:/WinBuilds/bin/x86_64-w64-mingw32-gcc-4.8.3.exe)
SET(CMAKE_CXX_COMPILER C:/WinBuilds/bin/x86_64-w64-mingw32-g++-4.8.3.exe)
project(testproject)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
#set(CMAKE_PREFIX_PATH "C:/WinBuilds/lib64/cmake")
set(CMAKE_PREFIX_PATH "C:/Qt/5.5/mingw492_32/lib/cmake")
find_package(Qt5Widgets)
add_executable(testfile WIN32 test.cpp)
target_link_libraries(testfile Qt5::Widgets)
(I did not use the cmake shipped with Qt5 as that did not work).
Now, the problem arises when I run make (or more precisely, mingw32-make, again shipped with WinBuilds) on the Makefile produced by cmake.
When I do this, the compilation fails with the following error (same one showed in the screenshot above):
CMakeFiles\testfile.dir/objects.a(test.cpp.obj):test.cpp:(.text+0x35): undefined reference to `__imp__ZN16QCoreApplicationC1ERiPPci'
CMakeFiles\testfile.dir/objects.a(test.cpp.obj):test.cpp:(.text+0x3e): undefined reference to `__imp__ZN16QCoreApplication4execEv'
CMakeFiles\testfile.dir/objects.a(test.cpp.obj):test.cpp:(.text+0x50): undefined reference to `__imp__ZN16QCoreApplicationD1Ev'
CMakeFiles\testfile.dir/objects.a(test.cpp.obj):test.cpp:(.text+0x67): undefined reference to `__imp__ZN16QCoreApplicationD1Ev'
c:/winbuilds/bin/../lib64/gcc/x86_64-w64-mingw32/4.8.3/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\testfile.dir/objects.a(test.cpp.obj): bad reloc address 0xc in section `.xdata'
c:/winbuilds/bin/../lib64/gcc/x86_64-w64-mingw32/4.8.3/../../../../x86_64-w64-mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
CMakeFiles\testfile.dir\build.make:127: recipe for target 'testfile.exe' failed
mingw32-make[2]: *** [testfile.exe] Error 1
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/testfile.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/testfile.dir/all] Error 2
Makefile:82: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
Why is the compilation failing?
A similar undefined reference error was reported in this other SO question, but the reason there seemed to be different than the present case.
The problem is you are using 32 bit mingw compiled Qt binaries when you are trying to build a 64 bit Qt application. You need to use 64 bit Qt binaries compiled with mingw for this to work.