LLD undefined symbol when attempting to link glfw - c++

I've been trying to get an LLVM toolchain setup on my Windows 10 machine. I gave up on building from source and have the MSYS2 mingw-w64-clang-x86_64-toolchain package installed (clang version 13.0.0).
I can compile simple code that uses the C++ standard library. I'm using clang to compile, lld to link, and I should be using libc++.
To test linking an additional library, I'm using glfw:
#include <iostream>
#include <vector>
#include "glfw3.h"
int main(int argc, char **argv) {
glfwInit();
std::vector<int> testVector = {4, 5, 6, 7, 2};
testVector.push_back(23);
std::cout << testVector[1] << std::endl;
return 0;
}
This compiles and runs fine if I comment out the glfwInit(); line and use this command :
clang++ -Iinclude\ -Llib\ -lglfw3 -v .\main.cpp
So it seems lld is finding the libglfw3.a library file I placed in the lib\ directory.
But if glfwInit(); is uncommented, with the same command I get a lot of unresolved symbol errors:
ld.lld: error: undefined symbol: __declspec(dllimport) CreateDIBSection
>>> referenced by libglfw3.a(win32_window.c.obj):(createIcon)
ld.lld: error: undefined symbol: __declspec(dllimport) CreateBitmap
>>> referenced by libglfw3.a(win32_window.c.obj):(createIcon)
ld.lld: error: undefined symbol: __declspec(dllimport) DeleteObject
>>> referenced by libglfw3.a(win32_window.c.obj):(createIcon)
>>> referenced by libglfw3.a(win32_window.c.obj):(createIcon)
>>> referenced by libglfw3.a(win32_window.c.obj):(updateFramebufferTransparency)
..and so on.
I built the glfw library from the glfw source code using CMake, Ninja, and Clang.
The win32_window.c.obj file and all others referenced by these errors are a couple directories deeper in the lib\ directory, but I can't seem to get clang/lld to find them.
What argument am I missing here?
Edit: I ran this
clang++ -### -Iinclude\ -Llib\ -lglfw3 -v .\main.cpp
And got these two lines:
"C:/msys64/clang64/bin/clang++.exe" "-cc1" "-triple" "x86_64-w64-windows-gnu" "-emit-obj" "-mrelax-all" "--mrelax-relocations" "-disable-free"
"-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "main.cpp" "-mrelocation-model" "pic" "-pic-level" "2" "-mframe-pointer=none"
"-fmath-errno" "-fno-rounding-math" "-mconstructor-aliases" "-mms-bitfields" "-munwind-tables" "-target-cpu" "x86-64" "-tune-cpu" "generic"
"-debugger-tuning=gdb" "-v" "-fcoverage-compilation-dir=C:\\Users\\gcvan\\testProgram" "-resource-dir" "C:/msys64/clang64/lib/clang/13.0.0"
"-I" "include\\" "-internal-isystem" "C:/msys64/clang64/x86_64-w64-mingw32/include/c++/v1" "-internal-isystem" "C:/msys64/clang64/include/c++/v1"
"-internal-isystem" "C:/msys64/clang64/lib/clang/13.0.0/include" "-internal-isystem" "C:/msys64/clang64/x86_64-w64-mingw32/include"
"-internal-isystem" "C:/msys64/clang64/include" "-fdeprecated-macro" "-fdebug-compilation-dir=C:\\Users\\gcvan\\testProgram" "-ferror-limit"
"19" "-fmessage-length=120" "-fno-use-cxa-atexit" "-fgnuc-version=4.2.1" "-fcxx-exceptions" "-fexceptions" "-exception-model=seh"
"-fcolor-diagnostics" "-faddrsig" "-o" "C:/Users/gcvan/AppData/Local/Temp/main-c1d43f.o" "-x" "c++" ".\\main.cpp"
"C:/msys64/clang64/bin/ld.lld" "-m" "i386pep" "-Bdynamic" "-o" "a.exe" "C:/msys64/clang64/x86_64-w64-mingw32/lib/crt2.o"
"C:/msys64/clang64/x86_64-w64-mingw32/lib/crtbegin.o" "-Llib\\" "-LC:/msys64/clang64/x86_64-w64-mingw32/lib" "-LC:/msys64/clang64/lib"
"-LC:/msys64/clang64/x86_64-w64-mingw32/sys-root/mingw/lib" "-LC:/msys64/clang64/lib/clang/13.0.0/lib/windows" "-LC:\\cppLibraries" "-lglfw3"
"C:/Users/gcvan/AppData/Local/Temp/main-c1d43f.o" "-lc++" "-lmingw32" "C:/msys64/clang64/lib/clang/13.0.0/lib/windows/libclang_rt.builtins-x86_64.a"
"-lunwind" "-lmoldname" "-lmingwex" "-lmsvcrt" "-ladvapi32" "-lshell32" "-luser32" "-lkernel32" "-lmingw32"
"C:/msys64/clang64/lib/clang/13.0.0/lib/windows/libclang_rt.builtins-x86_64.a" "-lunwind" "-lmoldname" "-lmingwex" "-lmsvcrt" "-lkernel32"
"C:/msys64/clang64/x86_64-w64-mingw32/lib/crtend.o"

Well, it seems I have a lot to learn about command line compiling/linking.
I fixed it by adding -lgdi32 to the compile tags:
clang++ -Iinclude\ -Llib\ -lglfw3 -lgdi32 -v .\main.cpp
Got the idea from this thread: https://github.com/ziglang/zig/issues/3319
From the thread, near the bottom, there is some good advice:
When you see undefined symbol: __imp_CreateDCW the trick is to look up what DLL that is in. A duck duck go search lands us at https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createdcw which says at the bottom it is in Gdi32.dll. So you need addSystemLibrary("Gdi32").
For some reason I assumed all the undefined function calls were from glfw, but they aren't, they are from the GDI32 Win32 library.
Just goes to show, for anyone at my experience level, you should probably make sure to google ALL relevant text from your errors and don't make assumptions about the provenance of things..

Related

Freeglut 64 bit program linking errors

I'm trying to compile a 64 bit version of an OpenGL C++ program using freeglut. I followed the exact instructions on this website to set up freeglut with MinGW. I have the header files in C:\MinGW\include\GL, I have the 32 bit libraries in C:\MinGW\lib and 64 bit libraries in C:\MinGW\lib\x64, and I have the 64 bit freeglut.dll in my project directory. However, even the simplest of OpenGL programs don't link successfully...
My code is minimal:
// test.cpp
#include <GL/glut.h>
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
}
And I compile it with the exact commands given on the readme/on the website:
g++ -c -o test.o test.cpp -I"C:\MinGW\include"
g++ -o test.exe test.o -L"C:\MinGW\lib\x64" -lfreeglut -lopengl32 -Wl,--subsystem,windows
(except of course I changed the directories and changed gcc to g++)
The compile runs fine, but linking throws these error messages:
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: test.o:test.cpp:(.text+0x1c): undefined reference to `_imp____glutInitWithExit#12'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: test.o:test.cpp:(.text+0x3f): undefined reference to `_imp____glutCreateWindowWithExit#8'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: test.o:test.cpp:(.text+0x61): undefined reference to `_imp____glutCreateMenuWithExit#8'
collect2.exe: error: ld returned 1 exit status
I've tried to change -lopengl32 in the command to -lopengl64 and -lopengl, but the linker couldn't find those libraries.
I can't answer your specific case, but another approach would be to use mingw-w64, with MSYS2 as a package manager. The old mingw.org project is not well maintained, unlike mingw-w64 and the MSYS2 package database. There is probably some mismatch between how your precompiled binaries were built and the compiler you are currently using.
On my system I compiled your code with g++ -o gl gl.cpp -lfreeglut and it worked first time .
How to install MinGW-w64 and MSYS2?
Then use pacman -Ss glut to find the freeglut package.

How to use the fmt library without getting "Undefined symbols for architecture x86_64"

I'm trying to use the fmt (https://github.com/fmtlib/fmt) formatting header library in my c++ project.
I've added the path to the core header file at the top of my main file like so:
#include "../third_party/fmt/core.h"
but when I try to call any function like:
string message = fmt::format("The answer is {}", 42);
I get the following error:
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > fmt::v5::internal::vformat<char>(fmt::v5::basic_string_view<char>, fmt::v5::basic_format_args<fmt::v5::buffer_context<char>::type>)", referenced from:
std::__1::basic_string<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type, std::__1::char_traits<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type>, std::__1::allocator<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type> > fmt::v5::format<char [17], int>(char const (&) [17], int const&) 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[2]: *** [main] Error 1
make[1]: *** [CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2
I'm not sure how to use this as this is how I have used other header libraries in the past such as cxxopts. Any help would be appreciated!
You should link with the fmt library or use the optional header-only mode.
For example, if you have the file test.cc:
#include <fmt/core.h>
int main() {
fmt::print("The answer is {}.", 42);
}
You can compile and link it with gcc:
g++ -std=c++11 test.cc -lfmt
From a comment in #vitaut's answer, if you change your #include line from this:
#include "../third_party/fmt/core.h"
to this:
#include "../third_party/fmt/format.h"
it will cause the code to be compiled in "header-only mode", and you won't need to change your build process to compile and link in the {fmt} library.
I'm working on Mac, and I did not realize that you can install the library using brew. It appears at the end of the page. I have been dealing with symbol errors all evening, and I'm not sure that all my problems were related to the build process. The compiling process was also not working properly.
The paths where the library is installed are: /usr/local/include and /usr/local/lib.
I'm using g++-11 to build my project and this instruction works for me:
g++-11 -std=c++20 -I/usr/local/include -L/usr/local/lib -lfmt main.cpp -o main
The only problem is that it works partially. It works fine with print:
fmt::print("Don't {}!\n", "panic");
But it breaks using format:
fmt::format("Don't {}!\n", "panic");
I'm missing something, but I'm not sure what.
By the way, if you are using VSCode, you can create a c_cpp_properties.json into your .vscode folder and add the include path for the headers.
{
"includePath": [
[...],
"/usr/local/include/"
],
}
Not sure if this is related to your case, but I hope it helps.

libtensorflow_core.a missing symbols (tensorflow::port::InitMain(char const*, int*, char***)

I have compiled the static library libtensorflow_core.a in the tensorflow/contrib/makefiles/gen/lib folder using the
./tensorflow/contrib/makefile/build_all_linux.sh
script
Making some minor adjustments for CentOS 6.10 to include a LD_LIBRARY_PATH for libstdc++ as the gcc that comes with CentOS 6 is gcc 4.4 and gcc 4.8 is needed for C++11
I have tested the compile was successful by testing the benchmark binary with my model
./tensorflow/contrib/makefile/gen/bin/benchmark etc
This all works as expected.
Now I am hosting Tensorflow in my application, which was previously dynamically linked to libtensorflow_cc.so and libtensorflow_framework.so
instead I am linking to libtensorflow_core.a statically
Compiling and linking of my plugin are successful.
At runtime the following error occurs:
/usr/local/Nuke11.3v1/Nuke11.3: symbol lookup error: /usr/OFX/Plugins/rotobot.ofx.bundle/Contents/Linux-x86-64/rotobot.ofx: undefined symbol: _ZN10tensorflow4port8InitMainEPKcPiPPPc
We can see the symbol missing is
tensorflow::port::InitMain(char const*, int*, char***)
my code indeed contains this function
[samh#apollo-centos6 Rotobot-CPU-static]$ grep -rn InitMain rotobot.cpp
130: tensorflow::port::InitMain(&usage[0], &argc, NULL);
What adjustments do I need to make to my the libtensorflow_core.a Makefile to include InitMain?
Sam
I can see that this function is in the benchmark binary which works
and I can also see that the benchmark source are as follows
BENCHMARK_SRCS := \
tensorflow/core/util/reporter.cc \
tensorflow/tools/benchmark/benchmark_model.cc \
tensorflow/tools/benchmark/benchmark_model_main.cc
the LIBS flags for my compile are the libprotobuf.a and libtensorflow_core.a and the other things needed for my application
I think if you had the following
#include <tensorflow/core/platform/init_main.h>
#include <tensorflow/core/public/session.h>
int main(int argc, char* argv[]){
char usage[] = "iLikeTurtles";
tensorflow::port::InitMain(&usage[0], &argc, NULL);
}
it would be enough to trigger the error
I would expect the program to function the same as the code linked against libtensorflow_cc.so and libtensorflow_framework.so
looking into
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/benchmark/BUILD
deps = select({
"//tensorflow:android": [
"//tensorflow/core:android_tensorflow_lib",
"//tensorflow/core:android_tensorflow_test_lib",
],
"//conditions:default": [
"//tensorflow/core:core_cpu",
"//tensorflow/core:lib",
"//tensorflow/core:framework",
"//tensorflow/core:framework_internal",
"//tensorflow/core:framework_lite",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:tensorflow",
"//tensorflow/core:test",
],
}),
Looks like we might need the .o files for framework, framework_internal, and framework_lite.
the devil is in the detail
here are the library args to use the static library
-Wall -L$(TENSORFLOW)/tensorflow/contrib/makefile/gen/protobuf-host/lib -Wl,--allow-multiple-definition -Wl,--whole-archive $(TENSORFLOW)/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a -Wl,--no-whole-archive $(TENSORFLOW)/tensorflow/contrib/makefile/downloads/nsync/builds/default.linux.c++11/nsync.a -lstdc++ -l:libprotobuf.a -lz -lm -ldl -lpthread -lrt
Then everything works great
This was deciphered by looking at make VERBOSE=true when executing the build_all_linux.sh
and looking at the last command for building and linking the benchmark executable
you may not need -lrt but I do on CentOS 6.10
I still need to do the same on OSX
Building on OSX is still using the build_all_linux.sh script as OSX is close enough to Linux
TENSORFLOW_LIBS = -Wl,-force_load,$(TENSORFLOW)/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a -Wl,-force_load,$(TENSORFLOW)/tensorflow/contrib/makefile/downloads/nsync/builds/default.macos.c++11/nsync.a -Wl,-force_load,$(TENSORFLOW)/tensorflow/contrib/makefile/gen/protobuf-host/lib/libprotobuf.a -lstdc++ -lz -lpthread

vscode g++ Link failure : Undefined symbols for architecture x86_64

Basic Info:
system: macOS High Sierra(10.13.6)
editor : vs code(latest version)
Compiler: g++ (Xcode)
Target:deploy GLFW + GLAD
Question Description:
Recently, I'm learning to do some Computer Graphics related work. Everything is going smooth. However, when i create a window to test the env.Link error happened:
Undefined symbols for architecture x86_64:
"_gladLoadGLLoader", referenced from:
_main in main-5c211c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The terminal process terminated with exit code: 1
It seems I have not link some third party file. I
have fixed exactly the same problem by add "-lglfw" args to g++ when using functions in glfw3.h.
But when meeting glad related function : gladLoadGLLoader, I don't know how to do.
Something I have done:
Can find the head file.
#include glad/glad.h
#include GLFW/glfw3.h
Have put the file "glad.c" in workspace.
Try to Add "g++ -framework XXXXX" , But doesn't work.
Try to Add "g++ -lglfw3", But doesn't work.
Add "g++ -L or I /usr/lib or /usr/local/lib or /usr/local/include", But doesn't work.
Just tell the g++ to compile glad.c by adding "glad.c" to args. I thought glad.c will be compiled by default. Although I am not clear what happened, the problem is resolved anyway.
Add glad.c into Build Phases->Compile Sources

undefined reference to glfwSetErrorCallback

I'm trying to use the GLFW library, but am having difficulty with compiling a simple program. I went to the GLFW website and download the latest release, then using "How to build & install GLFW 3 and use it in a Linux project" I built and installed it.
Here's my code:
#include <GLFW/glfw3.h>
#include <iostream>
using std::cout;
using std::endl;
void GLFW_error(int error, const char* description)
{
fputs(description, stderr);
}
void run()
{
cout << "pooch" << endl;
}
int main()
{
glfwSetErrorCallback(GLFW_error);
if (!glfwInit()) exit(EXIT_FAILURE);
run();
glfwTerminate();
return 0;
}
Using the command line:
bulletbill22#ROBOTRON ~/Desktop $ g++ -std=c++11 -lglfw source.cpp
yields
source.cpp:function main: error: undefined reference to 'glfwSetErrorCallback'
glfwSetErrorCallback is taken from their tutorial for "Setting an error callback".
Inclusion of -glfw3 results in /usr/bin/ld: error: cannot find -lglfw3
Even though everything seemed to be installed correctly, I suspect the problem may lie somewhere with the installation of the GLFW library because I'm not used to CMake and don't entirely understand how it works. I'm frustrated because the answer must be simple, but I'm not sure which keywords are really relevant when googling the problem; mostly the results are people who were incorrectly compiling with CMake, which I'm not compiling with in this case.
It seems that the directories for the glfw3.h header and libglfw3.so (and/or libglfw3.a) library are not in the default path.
You can check with by adding the -v option to the g++ options. Locate the directory where the glfw3.h header is found - call this $GLFW_INCDIR - it typically ends with .../GLFW. Locate the directory where the library is found - call this $GLFW_LIBDIR. Try:
g++ -std=c++11 -I$GLFW_INCDIR source.cpp -o pooch -L$GLFW_LIBDIR -lglfw3
If all the library dependencies are satisfied, this hopefully results in a program called pooch.
One other thing: GLFW3 is a C library, and the callback function arguments are expected to be C functions. So your callback should have 'C' linkage, i.e.,
extern "C" void GLFW_error(int error, const char* description) ...
Also, if you're having trouble with cmake, you may have ccmake installed. Try ccmake . in the top-level directory of the GLFW3 package for 'interactive' configuration.