Linking in C with MinGW

tatteredpotato

Diamond Member
Jul 23, 2006
3,934
0
76
I've been working on a Modbus library for an embedded system, however I've been doing most of the design and testing just using Netbeans (on Windows) and some simulation programs to ease development. I'm to the point that I want to start checking performance with some timers and from I've read, on Windows my main options are:

timeGetTime() ~ 1ms resolution
QueryPerformanceCounter() ~ microsecond resolution

Now when I try to use timeGetTime I get the following error:

C:/..../modbus/main.c:56: undefined reference to `timeGetTime@0'

I gather this is some error with the compiler not knowing where to find the library? For the record I have included windows.h (which should include the requisite mmsystem.h). I'm a little confused on how exactly I go about determining how to fix this. I've tried adding a -lwinmm to both the compiler and the linker but it still can't find timeGetTime.

It's not a problem with all windows libraries either, I have the serial communications working just fine and Query PerformanceCounter works as well.
 

tatteredpotato

Diamond Member
Jul 23, 2006
3,934
0
76
Gah, figures I work on this for hours and figure out the solution 10 minutes after posting.

I was specifying -lwinmm in the "Additional Options" portion of the preferences dialog for the linker which apparently doesn't behave the same from adding the library in the "Libraries" section. I'd still be interested in any insight into the differences.

For the record here's the command that ended up with the reference to the winmm library:

gcc.exe -o dist/Debug/MinGW_1-Windows/modbus build/Debug/MinGW_1-Windows/modbus.o build/Debug/MinGW_1-Windows/ring_buffer.o build/Debug/MinGW_1-Windows/main.o build/Debug/MinGW_1-Windows/checksum.o -lwinmm

EDIT: Hmm so I also managed to read the documentation backwards... I thought it said libraries must come first whereas it said the exact opposite. My guess is that the library flag was concatenated into the command in the wrong place which was my issue.

http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use
 
Last edited:

Cogman

Lifer
Sep 19, 2000
10,284
138
106
:) glad you figured it out. Linking errors can be a pain to track down.

One suggestion, IIRC, timeGetTime has the same resolution as the very common function GetTickCount(); (I want to say that it uses it, but I can't). I would recommend using GetTickCount over timeGetTime. No messy linker problems with roughly the same resolution.

[edit]Well I looked it up, and I'm definitally wrong on this one. timeGetTime uses different methods then GetTickCount and often has a higher resolution.

However, newer windows implementations have higher resolutions of GetTickCount. When I've used it, its been something like 15ms resolution in xp and less in Vista/7. People elsewhere are saying 50ms.
 
Last edited:

tatteredpotato

Diamond Member
Jul 23, 2006
3,934
0
76
:) glad you figured it out. Linking errors can be a pain to track down.

One suggestion, IIRC, timeGetTime has the same resolution as the very common function GetTickCount(); (I want to say that it uses it, but I can't). I would recommend using GetTickCount over timeGetTime. No messy linker problems with roughly the same resolution.

[edit]Well I looked it up, and I'm definitally wrong on this one. timeGetTime uses different methods then GetTickCount and often has a higher resolution.

However, newer windows implementations have higher resolutions of GetTickCount. When I've used it, its been something like 15ms resolution in xp and less in Vista/7. People elsewhere are saying 50ms.

Yea the 1ms resolution provided by timeGetTime() was good enough for my application, especially that the end product was going to be running on a completely different architecture and clock speed, I was just ensuring that I didn't have any big performance issues right off the bat. The QueryPerformanceCounter() is supposed to have really good resolution, however the API wasn't quite as simple as timeGetTime() (which I felt more natural with coming from java's System.currentTimeMillis).
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
Yea the 1ms resolution provided by timeGetTime() was good enough for my application, especially that the end product was going to be running on a completely different architecture and clock speed, I was just ensuring that I didn't have any big performance issues right off the bat. The QueryPerformanceCounter() is supposed to have really good resolution, however the API wasn't quite as simple as timeGetTime() (which I felt more natural with coming from java's System.currentTimeMillis).
QueryPerformanceCounter is implemented different ways in different systems, which is why it is somewhat non-intuitive. For example, on P4s (and I believe most systems) it measure the number of clocks the processor had completed using a specific CPU instruction, RDTSC. Either way. The reason you have to do the performance counter then the frequency is because its resolution is dependent on many factors.
 
Last edited:

patterman

Junior Member
Jun 9, 2015
1
0
0
A big thanks to all involved in this thread, It saved me a great deal of time.

I was getting Linker notification "linker error [Linker error] undefined reference to `timeGetTime@0' "

No matter what I tried it just would not go away.

As it turns out it is significant which order the linker declaration ( "-lwinmm" ) is added into the GUI Dev-Cpp under TAB Tools > Compiler options > Compiler > "Add these commands to the linker command line"

Like this it it kept giving me the above notification:
g++.exe txtncurl.o -o "txtncurlpost.exe" -L "D:/Dev-Cpp/lib" -lwinmm -lcurl -lws2_32

The issue go's away when reordered as:
g++.exe txtncurl.o -o "txtncurlpost.exe" -L "D:/Dev-Cpp/lib" -lcurl -lws2_32 -lwinmm

:hmm: Best wishes.
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
At this point, I would strongly suggest not using dev-cpp. It was outdated and unmaintained in 2010, now it is practically dilapidated. Visual studios, CLion, QT creator, Code Blocks, Netbeans, eclipse. Any of these would be a better choice than Dev cpp. I mean, for pete sake they are on gcc 3x. 3.4.2 was released in 2004, that is over 10 years old!
 
Last edited:

Merad

Platinum Member
May 31, 2010
2,586
19
81
timeGetTime() can actually have a resolution of > 5 ms depending on the system. You should basically always use QueryPerformanceCounter() for any kind of timing info that needs to be remotely accurate. It's very trivial to wrap it in a class or a few C functions.

Edit: Holy thread necro, batman.