Monthly Archives: April 2012

MingW: UNIX incompatible & compile verbose

Building Mingw executables using Cygwin

One particular vexing source of error is when you include a file that
exists for Cygwin, but not for Mingw32; the compilation goes ok, but
the compiler is really using the *WRONG* include file and you get link
time errors.

Let’s say you have some code that uses the POSIX/BSD “times” function
which is not part of the ANSI standard and does not exist under Mingw32
runtime.

  #include
  #include
  int main () {
      struct tms time_info;
      times (&time_info);
      printf ("user_time = %d, system_time = %d\n",
              time_info.tms_utime, time_info.tms_stime);
      return 0;
  }

Now build the “times” program:

  $ gcc -c -mno-cygwin times.c
  $ gcc -o times -mno-cygwin times.o
  times.o(.text+0x34):times.c: undefined reference to `times'
  collect2: ld returned 1 exit status

Notice that the compilation goes just fine, but you get an undefined
reference to the “times” function.

What happens is that Cygwin first looks in the mingw32 include directory
the <sys/times.h> file and it can’t find it; it then looks at the default
directory and does find it and uses it and everything is fine at this
point. However, at link time, the Mingw32 runtime library lacks this
function and you get an undefined error. Sometimes these are so confusing
that you may get sidetracked and not look at the real source of the
problem — your own code!

So, how do you diagnose these errors? Whenever you get such errors, use
the -v (verbose) and -H (show include files) options when compiling
to see where include files are coming from. Then use -v option when
linking to see what libraries are being linked in.

Another source of error is creating Mingw DLLs using dllwrap. The current
version of dllwrap does not know the -mno-cygwin option and will
incorrectly add Cygwin libraries when creating DLLs. The workaround is
quite simple: add the --target=i386-mingw32 option instead. In the future,
dllwrap will simply translate the -mno-cygwin option to the --target
option and it will just work.