I'm working on a program that will monitor the usage of chosen programs and will log it into a .csv file. That way, I can determine what programs use up the most of a certain resource while I run a game in full-screen. I have included the psapi header like so:
...
#include <psapi.h>
...
And I compile with MinGW's G++ with the following options and necessary libraries for the function I'm using (libraries were from the documentation of the function): g++ -lkernel32 -lpsapi test.cpp -o test.exe
Yet it still throws the error:
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\james\AppData\Local\Temp\cclpYDm2.o:test.cpp:(.text+0x3e7): undefined reference to `GetProcessMemoryInfo@12'
collect2.exe: error: ld returned 1 exit status
I feel that either something is wrong with my library or there's something I'm doing wrong. I've tried surrounding the header with "extern "C"" and I still get the same exact message. I have also verified that the library exists; if it did not, the compiler would have thrown a different error. #pragma comment does not work either, and using the -static flag has no effect. I have also tried defining the PSAPI_VERSION macro and setting it to 1, placing it before the include statement of psapi.
TL;DR: Compiler is throwing an undefined reference error despite having correct libraries. I suspect it's either:
- Library was installed incorrectly
- I'm doing something wrong on linking
Please try this instead. The sequence of arguments you provided to g++ actually matters. Always put the library at the end of your arguments.
The g++ tool chain will first go through
test.cppand compile it to a binary object file, which is a temporary file having a funny name, but let us call ittest.ofor now. At this time, there are still some function references intest.owhich cannot be resolved.Then, the g++ tool chain sees
-lkernel32and then-lpsapi. It goes in these two libraries in sequence and find those missing functions intest.ofor you.If you are linking statically, it will copy the compiled binary code of the functions in need from the library and splice it to
test.o. If you are linking dynamically, it will set up some "entry" to the dynamic library.This is what makes the sequence to be important. The compiler tool chain will only copy (set up entry) those function in need, since a library is typically very large and contains many other functions you don't really need. When currently nothing is needed from the libraries, like the command you originally wrote, g++ needs nothing from
-lkernel32 -lpsapibefore running intotest.cpp, it will simply skip those libraries.In short, if
lib_adepends onlib_b, you should putlib_abeforelib_bin the arguments. In rare cases wherelib_xdepends onlib_ywhich in turn depends onlib_x, you must write something likeg++ file.cpp lib_x lib_y lib_x.Note that this rule only applies to libraries. All functions in the source file will be kept in the binary object file. Thus, even if
file_xdepends onfile_y, writingg++ file_y.cpp file_x.cppis okay, since all functions are kept infile_y.oandfile_x.o, when linking them together, the linker can find them.Related question: GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'