G++ linker exiting with code 1 with an undefined reference to 'vkCreateInstance' - c++

I've been having some trouble setting up a custom Vulkan build and development environment with G++ and VSCode. G++ doesn't seem to be linking to the proper library files, and is not recognizing only one of the Vulkan functions I've defined in main.cpp. That, or it's not properly finding the header files. I followed a video tutorial and did my own tweaking to make it work. (You can find it here https://www.youtube.com/watch?v=tRQ3zqCiKdQ). He creates a .bat file to run the compiler command and sets up some boilerplate tasks.json and launch.json files. The .bat file runs fine and makes it so that I don't have to type out file paths each time. Those work fine. And then I've copied his code as well just to get the build environment working, which I'm stuck on.
I'll admit, I'm not a wizard with command line compilers, but I just can't seem to find any information online that can help me. It's either outdated or the answer doesn't fix my issue. So I thought I'd try here. (first question btw).
I've got a basic, very recent and up-to-date Vulkan installation, a main.cpp file, a build.bat file, and g++ version 11.2.0 (according to MSys2, the latest version). I'm on Windows 64 bit running VSCode. I've included some in order, ending with a capture of my working directory. Afterwards, I'll list what I've tried.
Main.cpp
#include <iostream>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_core.h>
using namespace std;
int main(){
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Pong";
appInfo.pEngineName = "PongEngine";
VkInstanceCreateInfo instanceInfo = {};
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceInfo.pApplicationInfo = &appInfo;
VkInstance instance;
VkResult result = vkCreateInstance(&instanceInfo, NULL, &instance);
if(result == VK_SUCCESS){
cout << "Successful!" << endl;
}
}
Build.bat
#echo off
SET include=-I ./src -I C:/VulkanSDK/1.2.198.1/Include/
SET links= -L /C:/VulkanSDK/1.2.198.1/Lib/vulkan-1.lib
#echo "Building main..."
g++ -Wall %include% %links% -o main src/main.cpp
Directory
Root
|-----src
|-main.cpp
|-build.bat
I have tried almost everything. This is always the output:
"Building main..."
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\brado\AppData\Local\Temp\ccj9NixH.o:main.cpp:(.text+0xabe): undefined reference to `vkCreateInstance'
collect2.exe: error: ld returned 1 exit status
The terminal process "E:\coding\vulkan\personal_vulkan_expirimenting\build.bat" terminated with exit code: 1.
Despite -L supposedly specifying directories to search in, anytime I don't include vulkan-1.lib on the -L tag, it breaks.
I've tried using -l to specify the specific library and that doesn't seem to work
I feel like I've tried every flag under the sun. Someone somewhere said it might have to do with -m64 flag but that wasn't it.
I've added in two seemingly redundant header files that I've manually searched for vkCreateInstance in and included them in the hopes that that would trigger it but in vain
I've edited the file paths every which way to see if the formatting was the issue
I have read and checked the g++ and Vulkan documentation to see if anything could help and I could find seemingly nothing that would have helped. Perhaps I'm looking in the wrong place. But I've been googling for hours.
Before this whole fiasco started, I was also trying to use GLFW and GLM as per the basic Vulkan tutorial that's provided, and that was also having linking problems, which to me, narrows it down to how I'm using the compiler.
What's so confusing is that the intellisense on VS Code recognizes the function, and the linker has no issue with the other functions. It may be a limitation in my understanding of compilers, or I've tunnel-visioned and am not seeing outside the problem, I don't know. I'll admit I'm not insanely familiar with g++, but as I tried to get more familiar with it over the course of this problem (that I've been on for the last couple hours) I couldn't find any documentation Let me know what other information I can provide, maybe there's something I'm leaving out. Thanks so much!

Related

MinGW: Internal error when building a C++ program

I had been running C++ programs with G++17 quite comfortably, when one day for no apparent reason, this error shows up:
internal error in mingw32_gt_pch_use_address, at
config/i386/host-mingw32.c:190: MapViewOfFileEx: Attempt to access
invalid address.
Below is the complete error output:
[Finished in 4.5s with exit code 1]
[cmd: ['g++.exe', '-std=c++17', '-D DIV_DEBUG', 'D:\\Codes\\code.cpp', '-o', 'code.exe', '&&', 'code.exe<inputf.in>outputf.in']]
[dir: D:\Codes]
[path: C:\Python38\Scripts\;C:\Python38\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\MinGW\bin;C:\ProgramData\pbox;C:\Program Files\nodejs\;C:\ProgramData\chocolatey\bin;C:\Program Files\Git\cmd;C:\Users\asus\AppData\Local\Microsoft\WindowsApps;C:\Users\asus\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;C:\tools;C:\Users\asus\AppData\Roaming\npm;C:\Users\asus\AppData\Local\atom\bin]
I've been searching for a solution for three days now and haven't found it yet. It looks like a bug in MinGW but I do not know how to fix this. My last option is to delete everything related to MinGW and reinstall it. Any better ideas are appreciated.
The code which I'm trying to compile.
#include <bits/stdc++.h>
int main() {
std::cout << "Hello, World!\n";
return 0;
}
It appears that removing the "bits/stdc++.h" header file removes this error. I would still like to know how I can fix this as I use this library on a daily basis for all my programs.
Edit: I tried building on Windows Powershell but the same error comes up.
PS D:\Codes> g++.exe -std=c++17 -D DIV_DEBUG code.cpp -o code.exe
internal error in mingw32_gt_pch_use_address, at config/i386/host-mingw32.c:190: MapViewOfFileEx: Attempt to access invalid address.
Update: Tried reinstalling MinGW. It didn't work.
Okay, so the issue went as miraculously as it had appeared. I precompiled the header files after reinstalling MinGW and for some reason, it fixed the issue. I'm not sure if this action triggered the fix.
If someone can throw some light on this strange behaviour, I would mark that answer as accepted.

Mingw64 Linker error when trying to include -lhid [duplicate]

Context: I'm using Qt 5.9.3 on Windows, building for MinGW 32-bit. The Qt part is a side issue though - the problem seems to be with MinGW. The version of MinGW is 4.3.0, supplied prebuilt as part of the Qt installation.
I'm building a library which talks to a USB device over HID. Everything compiles fine, but it fails at the link stage with
./..\..\object\debug\usb_hid_device.o: In function `ZN8MyApp3USB5Win3213getDevicePathB5cxx11Ell':
<MYPATH>/../../source/win32/usb_hid_device.cpp:99: undefined reference to `HidD_GetAttributes(void*, _HIDD_ATTRIBUTES*)#8'
./..\..\object\debug\usb_hid_device.o: In function `ZN8MyApp3USB5Win3214CHIDDeviceImplC2EllRNS_15LogPerComponentE':
<MYPATH>/../../source/win32/usb_hid_device.cpp:200: undefined reference to `HidD_FlushQueue(void*)#4'
The linker command is
g++ -shared -mthreads -Wl,-subsystem,windows -Wl,--out-implib,<MYPATH>\bin\debug\libusb_hid_comms.a -o <MYPATH>\bin\debug\usb_hid_comms.dll object_script.usb_hid_comms.Debug -lhid -lsetupapi -LC:\Qt\Qt5.9.3\5.9.3\mingw53_32\lib C:\Qt\Qt5.9.3\5.9.3\mingw53_32\lib\libQt5Guid.a C:\Qt\Qt5.9.3\5.9.3\mingw53_32\lib\libQt5Cored.a
If I omit -lhid I get the same errors. I also get the same errors if I remove -lhid and explicitly set the path and filename to libhid.a. If I deliberately mistype the path and filename, it comes up with an error, so I know the command-line is getting parsed correctly. But for whatever reason, MinGW appears to not be linking with one of its own library files.
I've also tried removing -lsetupapi and I get the linker errors I'd expect for the functions defined in there. Likewise the Qt library files. But it seems that specifically for libhid.a, MinGW can see the library file but just isn't going to link with it.
Has anyone else seen this? Or can anyone else with the same (or similar) version of MinGW confirm or deny that they can link with libhid.a? Or is there something obviously wrong with what I'm doing?
I've just found the answer. I'm posting an answer myself so that other people know in future, because I think this is still a valid question which people might want to know about.
The problem is the include file hidsdi.h. The majority of other header files which pull in Win32 API calls have extern "C" around the function declarations. However this one doesn't! The result is that we end up with C++ name mangling for linker symbols, instead of the C-style "_" in front of the linker symbols.
The solution is to use
extern "C"
{
#include <hidsdi.h>
}
and then everything works fine.
The version of hidsdi.h with the older version of MinGW (which I'm porting from) did have that protection around the function declarations. However it looks like it's gone in the newer version.

Linker errors with codelite, unittest++ and g++ on linux

I'm new to unit testing in c++, and writing c++ on Linux (Mint). I'm using CodeLite as my IDE. I have found several answers on stackoverflow about linker errors, but after hours of trying various solutions I have not succeeded in implementing a solution correctly.
I installed unittest++ through apt-get. The unittest++ header files were installed in /usr/include, so I added this to the Compiler linker options in Codelite (Right click project name->Settings, Compiler):
Codelite screenshot
I then have a very simple program, which consists entirely of one main.cpp file:
#include <unittest++/UnitTest++.h>
//See if unit tests are working
TEST(MyMath) {
CHECK(false);
}
int main()
{
UnitTest::RunAllTests();
return 0;
}
Running the project at this point generates a stream of linker errors other users have experienced, for example:
main.cpp:4: undefined reference to UnitTest::CurrentTest::Details()
At this point, my understanding is that I now need to tell the g++ compiler about the object files and link them to the unittest++ files. And this is where I'm stuck. The only .o file I see is in Debug/main.cpp.o and running the command
g++ main.cpp -o main.cpp.o -Lunittest++
as well as variations with the I and o flags, but all of them return the same linker errors I get when I try to compile. I've also tried to copy every g++ line in the forums and only get various errors.
I've tried to find a solution in the g++ man pages, read about the flags I've been using and did not infer a solution. I then quickly got buried in quantity of pages in the man entry. The documentation for CodeLite and unittest++ seems woefully out of date, so I posted here on stackoverflow as a last resort.
I'm fairly certain I'm just making a rookie mistake. If someone has feedback, I'd be grateful.
In your explanation, you try to link manually with g++ -c main.cpp -o main.cpp.o -Lunittest++ , but the -L option gives the path to additional directories to search for libraries. You probably want -lunittest++ to link with the unittest++ library. That library should provide the symbols you see in the "undefined reference" errors.
As a side note, "/usr/include" should be in the default search path and there's no need to add it explicitly.

gcc and clang under msys2 cannot resolve includes with absolute paths

I try to get tests generated by the cxxtest framework working under a MinGW environment managed by mysys2. The tool generates C++ files with absolute paths. However, gcc seems to be unable to resolve this absolute paths.
Here is a minimal example to demonstrate the problem:
// file1.h
#include <iostream>
inline void hallo() { std::cout << "Hallo\n"; }
// main.cpp
#include "/home/phil/example/file1.h"
int main()
{
hallo();
return 0;
}
The file exists (at least the msys2 shell resolves the path):
$ ls /home/phil/example/file1.h
/home/phil/example/file1.h
... but calling g++ results in this error:
$ g++ main.cpp
main.cpp:1:38: fatal error: /home/phil/example/file1.h: No such file or directory
#include "/home/phil/example/file1.h"
^
compilation terminated.
Same error with clang.
Under a full Linux environment, the example works. It also works if I replace the absolute path by a relative one (#include "file1.h").
So, I assume the problem lies in the layer over Windows that is responsible to resolve paths. Not sure whether I should report it as a bug to the msys2 project, or whether it is a known problem. If it is a known problem, are there any workarounds (like setting -I options)?
(If possible, I would like to avoid replace the absolute paths, as they are in generated code by the cxxtest framework. Technically, running a postprocessing step on the generated files would be possible but seems like a hack in the long run.)
Since you are running compilers that use MinGW-w64 as their runtime environment, they don't recognize POSIX-style paths like that. I think they actually interpret the root directory "/" to be "C:\". Other than that, they would only recognize native Windows-style paths.
I recommend that you pass the argument -I/home/phil/example to your compiler from some program running in the msys-2.0.dll POSIX emulation runtime environment (e.g. /usr/bin/bash or /usr/bin/make). The msys-2.0.dll runtime will then convert that argument to use a native Windows path so the compiler can understand it, and statements like #include <file1.h> will work. Alternatively, you might try putting a Windows-style path in your source code, e.g. the path should start with C:\.
Note however that having absolute paths in source code or build scripts is a bad idea since it makes it harder to build the code on a different computer. You could consider using environment variables or relative paths.
Try using the MinGW compiler that Cygwin provides as a package. (In other words, forget the MSYS environment; work under Cygwin, but build the code as before, in the MinGW style.)
Then you should be able to have include references /home/phil; it will just resolve to C:\Cygwin\home\phil or wherever your Cygwin root is.
Actually, it might be possible under MSYS also (which, after all, is just the descendant of an old for of Cygwin). You just have to figure out what /home/phil is referring to, create that tree and work under there.

error: ‘fileno’ was not declared in this scope

I am running Cygwin on windows 8, attempting to compile the source code for a game I would like to mod. Unfortunately I am running into some errors while building involving the fileno function. After doing some googling It seems like the problem might have to do with c++11 support (I'm not really sure what this means). Most of the solutions people have found involve adding some option like -std=c++0x or -std=c++11 when compiling, but my attempts to add the options into the makefile have been unsuccessful, and I don't know if that's whats causing the problem anyways. I'll include the code snippet that's throwing the error and a link to the makefile as it is quite large. Any advice you could give me would be great.
code that throws error:
time_t file_modtime(FILE *f)
{
struct stat filestat;
if (fstat(fileno(f), &filestat))
return 0;
return filestat.st_mtime;
}
Link to Makefile
it is being hosted on github
EDIT: After getting some advice I poked around the makefile and found five instances where the -std option was used, playing around with them hasn't changed anything. Is the problem with my Cygwin configuration? I installed the packages I was told I would need in the installation guide for the game I am building.
Changing the -std=c*** in your makefile to -std=gnu++0x should fix your problem.
If you don't know what c++11 is you're most likely not using it anyway.
Also if you need c++11 support you can also do: -std=gnu++11 instead of -std=gnu++0x
For windows...
fileno() is deprecated: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-fileno?view=vs-2017
use _fileno() instead: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fileno?view=vs-2017