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:
Please try this instead. The sequence of arguments you provided to g++ actually matters. Always put the library at the end of your arguments.
g++ -o test.exe test.cpp -lkernel32 -lpsapi
The g++ tool chain will first go through test.cpp
and compile it to a binary object file, which is a temporary file having a funny name, but let us call it test.o
for now. At this time, there are still some function references in test.o
which cannot be resolved.
Then, the g++ tool chain sees -lkernel32
and then -lpsapi
. It goes in these two libraries in sequence and find those missing functions in test.o
for 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 -lpsapi
before running into test.cpp
, it will simply skip those libraries.
In short, if lib_a
depends on lib_b
, you should put lib_a
before lib_b
in the arguments. In rare cases where lib_x
depends on lib_y
which in turn depends on lib_x
, you must write something like g++ 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_x
depends on file_y
, writing g++ file_y.cpp file_x.cpp
is okay, since all functions are kept in file_y.o
and file_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()'