NO

Author Topic: Trouble linking C runtime  (Read 13595 times)

WRP

  • Guest
Trouble linking C runtime
« on: June 12, 2014, 11:00:10 PM »
I have a small program that links to a library statically (.lib) or dynamically (.dll). It compiles with the Tiny C compiler, but fails with PellesC. With static linking, the error is "can't find LIBC.lib", and with dynamic linking it is "can't find MSVCRT.lib".

I tried renaming crt.lib to msvcrt.lib. I also tried using POLIB to make a msvcrt.lib from my system's msvcrt.dll. In both cases, I got the error:

POLINK: error: Unresolved external symbol '__imp____p___argv'.
POLINK: error: Unresolved external symbol '__imp____p___argc'.

What is the problem and what can I do to compile the program?
« Last Edit: June 13, 2014, 02:18:23 AM by WRP »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #1 on: June 13, 2014, 10:14:35 AM »
Try using the switch '-Gn' undecorate imported stdcall.
the '__imp__' prefix means that the function is declared as imported from DLL (in the .h file there is something like '__declspec(dllimport) _p__argv).
To solve the problem you need to know what is the calling convention, and what is the real name in the DLL (decorated or not).
The request for MSVCRT.lib means that the library you want to use has been linked against the Microsoft runtime. Renaming the PellesC runtime could be the real cause of your problem if the missing symbols come from MSVCRT.lib (and not available in pocrt.lib).
The best solution is to get a copy of MSVCRT.lib (which is widly available and come also with free compilers and SDK from MS), select the switch '-Zl' in the compiler tab to omit default libraries, and add MSVCRT.lib in the linker tab.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

WRP

  • Guest
Re: Trouble linking C runtime
« Reply #2 on: June 14, 2014, 08:56:33 PM »
Try using the switch '-Gn' undecorate imported stdcall.

OK, tried that but it had no effect.

I tried -Zl "Omit default library name in object files" but then got error:
POLINK: error: Unresolved external symbol '__WinMainCRTStartup'.

Quote
The best solution is to get a copy of MSVCRT.lib..., select the switch '-Zl' in the compiler tab to omit default libraries, and add MSVCRT.lib in the linker tab.

I added a msvcrt.lib to \Lib and then got errors:
POLINK: error: Symbol '___argv' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.
POLINK: error: Symbol '___argc' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.

Then I removed crt.lib and got error:
POLINK: fatal error: File not found: 'crt.lib'.

It seems that Pelles C links to its own version of the C lib and can't use DLLs that are linked to msvc.lib because they conflict. Is it then impossible to use DLLs from other compilers?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #3 on: June 14, 2014, 10:22:20 PM »
I added a msvcrt.lib to \Lib and then got errors:
POLINK: error: Symbol '___argv' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.
POLINK: error: Symbol '___argc' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.
That's OK
Then I removed crt.lib and got error:
POLINK: fatal error: File not found: 'crt.lib'.

It seems that Pelles C links to its own version of the C lib and can't use DLLs that are linked to msvc.lib because they conflict. Is it then impossible to use DLLs from other compilers?
Have you compiled your sources with the switch '-Zl' in the compiler tab to omit default libraries before linking?

Could you post a simple project, with possibly a small library from TinyC to check?
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

WRP

  • Guest
Re: Trouble linking C runtime
« Reply #4 on: June 15, 2014, 03:07:19 AM »
Have you compiled your sources with the switch '-Zl' in the compiler tab to omit default libraries before linking?
Yes, I always get:
POLINK: error: Unresolved external symbol '__WinMainCRTStartup'.

Here is a small project and the binary compiled with TCC.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #5 on: June 15, 2014, 06:19:49 PM »
The library is a GUI library, so you have to setup a windows subsystem project.
The uipstub library provides for the missing entry point WinMan.
The library use __cdecl convention (see the use of the new pragma default_convention of PellesC V8 before inclusion of 'iup.h').
I created the project using standard PellesC runtime (not msvcrt).

Anyway, unless you are interested to linking with TinyC prebuild libraries, I suggest you to download the iup sources and natively compile them in PellesC.  ;)
« Last Edit: June 15, 2014, 06:35:05 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

WRP

  • Guest
Re: Trouble linking C runtime
« Reply #6 on: June 15, 2014, 11:37:58 PM »
As far as I can tell, I did the same thing as you. I created a Windows EXE project in the IDE. Here is my project file.

Code: [Select]
#
# PROJECT FILE generated by "Pelles C for Windows, version 8.00".
# WARNING! DO NOT EDIT THIS FILE.
#

POC_PROJECT_VERSION = 7.00#
POC_PROJECT_TYPE = 0#
POC_PROJECT_OUTPUTDIR = output#
POC_PROJECT_RESULTDIR = .#
POC_PROJECT_ARGUMENTS = #
POC_PROJECT_WORKPATH = #
POC_PROJECT_EXECUTOR = #
POC_PROJECT_ZIPEXTRA = #
CC = pocc.exe#
AS = poasm.exe#
RC = porc.exe#
LINK = polink.exe#
SIGN = posign.exe#
CCFLAGS = -std:C99 -Tx86-coff -Ot -Ob1 -fp:precise -W1 -Gd#
ASFLAGS = -AIA32 -Gz#
RCFLAGS = #
LINKFLAGS = -subsystem:windows -machine:x86 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib delayimp.lib iup.lib iupstub.lib -delayload:iup.dll#
SIGNFLAGS = -location:CU -store:MY -timeurl:http://timestamp.verisign.com/scripts/timstamp.dll -errkill#
INCLUDE = $(PellesCDir)\Include\Win;$(PellesCDir)\Include;..\..\iup-3.10.1_Win32_dll10_lib\include#
LIB = $(PellesCDir)\Lib\Win;$(PellesCDir)\Lib;..\..\iup-3.10.1_Win32_dll10_lib#

#
# Build alarm.exe.
#
alarm.exe: \
output\alarm.obj \
output\iup.res
$(LINK) $(LINKFLAGS) -out:"$@" $**

#
# Build alarm.obj.
#
output\alarm.obj: \
..\..\iup-3.10.1_Examples\C\alarm.c \
..\..\iup-3.10.1_Win32_dll10_lib\include\iup.h \
..\..\iup-3.10.1_Win32_dll10_lib\include\iupdef.h \
..\..\iup-3.10.1_Win32_dll10_lib\include\iupkey.h
$(CC) $(CCFLAGS) "$!" -Fo"$@"

#
# Build iup.res.
#
output\iup.res: \
..\..\iup-3.10.1_Win32_vc12_lib\etc\iup.rc \
..\..\iup-3.10.1_Win32_vc12_lib\etc\iup.manifest \
..\..\iup-3.10.1_Win32_vc12_lib\etc\pen.cur \
..\..\iup-3.10.1_Win32_vc12_lib\etc\tecgraf.ico
$(RC) $(RCFLAGS) "$!" -Fo"$@"

.EXCLUDEDFILES:

.SILENT:

I also tried using just the files you returned to compile the project.

With just the files that come with Pelles C, I got the error:
POLINK: fatal error: File not found: 'MSVCRT.lib'.

When I added msvcrt.lib to PellesC\Lib, I got:
POLINK: error: Symbol '___argv' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.
POLINK: error: Symbol '___argc' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.

What did you do to make it compile?
« Last Edit: June 16, 2014, 06:04:57 AM by WRP »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #7 on: June 16, 2014, 09:16:54 AM »
Probably you doesn't move to -subsystem:windows? (see below)
Anyway you can look the project options to check compiler and linker switches used.

No. It's not black magic ...  ;)
« Last Edit: June 17, 2014, 09:09:32 AM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

WRP

  • Guest
Re: Trouble linking C runtime
« Reply #8 on: June 17, 2014, 01:45:22 AM »
I discovered the linker option -force:multiple. It is not displayed in the IDE controls. This causes the linker to ignore when symbols are multiply defined. Now it will build and I get a working executable.

I don't know how safe this strategy is, though.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #9 on: June 17, 2014, 08:53:46 AM »
WRP, sorry, but I have not understood if my project worked for you.
My project, with msvcrt.lib in libraries folder, compiles or not? And if not which errors you still have? The same as before?

EDIT: Maybe I found the problem. Why you linked with delay load the library iup.lib? It's a nosense. the iup code in iup.lib is the first to execute, and that code calls your main routine. Why you added iup.dll as delay load?

P.S. Using -force:multiple is not a good option. Some symbols maybe dynamically allocated and calling them in the wrong place (the first definition that linker can find) could lead to many many problems...
« Last Edit: June 17, 2014, 10:27:18 AM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

WRP

  • Guest
Re: Trouble linking C runtime
« Reply #10 on: June 17, 2014, 06:41:10 PM »
My project, with msvcrt.lib in libraries folder, compiles or not? And if not which errors you still have? The same as before?
I tried your project. The errors are the same.

Quote
Why you added iup.dll as delay load?
I just tried it to see what would happen. I noticed no difference.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #11 on: June 18, 2014, 09:06:21 AM »
My project, with msvcrt.lib in libraries folder, compiles or not? And if not which errors you still have? The same as before?
I tried your project. The errors are the same.

Strange.   :P
It seems that on your system the linker includes immediatly the pocrt.lib, then when the iup.lib is linked it includes msvcrt.lib and found the duplicate symbols.
What is strange is that using my project and a standard PellesC installation you still get different result. Or you have made modifications, or added other objects or libraries?  :(
The only solution is to force the linker to load the msvcrt.lib before anything else.
This can be done inserting msvcrt.lib as first library on the linker command line or in the IDE's libraries list (in the linker tab, see image).
The sequence of objects and libraries linked is very important.
Eventually use also the switch -Zl to omit the default libraries in object files.
« Last Edit: June 18, 2014, 09:09:47 AM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

WRP

  • Guest
Re: Trouble linking C runtime
« Reply #12 on: June 18, 2014, 10:16:13 PM »
It is a default installation, no changes.

I put msvcrt.lib as first library in the linker list and still get error:
POLINK: error: Symbol '___argv' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.
POLINK: error: Symbol '___argc' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.

Then I added switch -Zl to omit the default libraries in object files and got error:
POLINK: error: Unresolved external symbol '__WinMainCRTStartup'.

Did it actually work on your system?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #13 on: June 19, 2014, 09:18:19 AM »
Did it actually work on your system?
On my system it compiles, links and run like a charm... (see picture)

It is a default installation, no changes. The msvcrt.lib I use is the 100 that loads MSVCR100.dll in runtime.

I put msvcrt.lib as first library in the linker list and still get error:
POLINK: error: Symbol '___argv' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.
POLINK: error: Symbol '___argc' is multiply defined: 'crt.lib(_crt0dat.obj)' and 'msvcrt.lib(msvcrt.dll)'.

Then I added switch -Zl to omit the default libraries in object files and got error:
POLINK: error: Unresolved external symbol '__WinMainCRTStartup'.
Your problem is clearly due to the fact that the linker use both msvcrt and pocrt libraries together in the first case so you get the multiple definition.
In the second case, omitting the default libraries, pocrt is not loaded anymore, but somewhere you reference the symbol '__WinMainCRTStartup' that is in no library.
Really strange, difficult to say what is the problem.
The cause of the problem could be so subtle that is very difficult to identify.
I asked you to use the project that I published, unzip it in a folder, double click the 'Alarm.prj' in that directory then compile and run it as is. I'm not sure that you have done so, if you still just look the configuration of my project and try to adapt yours, maybe we'll never solve the problem. This because if in your project there are other switch set or missing, or it includes other modules or libraries compiled differently I can't test and nor even know.
If you have used *just* my project maybe the msvcrt.lib is not correct. Download a version 100 or newer.
I attach also a simplified version that is just a windows compile and doesn't use iupstub.lib.

If someone eslse want compile the sample is welcome.
« Last Edit: June 19, 2014, 09:55:28 AM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Trouble linking C runtime
« Reply #14 on: June 19, 2014, 10:55:02 AM »
This is the msvcrt.lib created using polib against msvcr100.dll.
« Last Edit: June 19, 2014, 12:34:17 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide