Author Topic: Unresolved externals with NODEFAULTLIB flag  (Read 10660 times)

0 Members and 1 Guest are viewing this topic.

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Hi guys,

As you're probably aware, I use IQ's 64k C++ framework as a base. This uses the NODEFAULTLIB linker flag to keep the size down.

There are ASM replacements for a lot of standard functions, all prefixed with "msys_" i.e. msys_memset etc.  My issue is that VC is being smart and identifying certain blocks of code as doing something specific (like memset) and replacing the code block with a call to memset during compilation.

This results in things such as:

Error   3   error LNK2019: unresolved external symbol _memset referenced in function "int __fastcall build_huffman(struct huffman *,int *)" (?build_huffman@@YIHPAUhuffman@@PAH@Z)   stb_image.obj   phenomenaEclipse

Is there an easy way to avoid this happening without mashing up the code so the compiler cannot recognise it that will not impact badly on overall performance?

I'm adding some image handling stuff using stbi (stb Image), which is the source of these headaches.

Any advice gratefully appreciated :)

EDIT: I found a similar post where Hellfire suggest adding the /QIfist compiler flag. This flag is already present and doesn't resolve the issue.
« Last Edit: November 22, 2011 by Raizor »
raizor

Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #1 on: November 22, 2011 »
I've found some info that helped: http://stackoverflow.com/questions/2938966/how-to-use-vc-intrinsic-functions-w-o-run-time-library.

Adding this:

#pragma function(memset)
void * __cdecl memset(void *pTarget, int value, size_t cbTarget) {
    char *p = reinterpret_cast<char *>(pTarget);
    while (cbTarget-- > 0) {
        *p++ = static_cast<char>(value);
    }
    return pTarget;
}


has got round the problem. Not an ideal solution, but it will do for now :)
raizor

Challenge Trophies Won:

Offline LittleWhite

  • Senior Member
  • Amiga 1200
  • ********
  • Posts: 418
  • Karma: 31
  • It's me!
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #2 on: November 22, 2011 »
The demoscene will never die, never!

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #3 on: November 22, 2011 »
There's no point getting rid of the C runtime (CRT) libraries and then using another big binary library like stb image if the aim is to achieve small exes.  Nearly all these external libs will also have a dependency on CRT.

Windows can load bmp files with a few lines of code (LoadImage), or with a bit more ingenuity you can use Direct3DX or GDI+ to do the loading for other formats.

<edit>
FYI, the compiler will generate memset for things like this
Code: [Select]
void apple(void)
{
   int banana[200]={0};
}
and many other scenarios where a stack-based variable must be cleared to 0.

If you want to avoid that, make banana a global.
Code: [Select]
int banana[200];
But watch if you're not using CRT, as it is that guy that guarantees that the BSS segment - uninitialised global variables - is cleared to 0 at exe startup.  Not initialising CRT e.g. by bypassing WinMain and using WinMainCRTStartup will also break any lib that depends on that behaviour.

Jim
« Last Edit: November 22, 2011 by Jim »
Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #4 on: November 22, 2011 »
Thanks LittleWhite and Jim.

Jim, I'm not overly worried about size at the moment, just wanted to keep things as lean as possible for a 64k intro. Some useful information you provided there, thanks.
raizor

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1292
  • Karma: 466
    • View Profile
    • my stuff
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #5 on: November 23, 2011 »
Adding this:

#pragma function(memset)
void * __cdecl memset(void *pTarget, int value, size_t cbTarget) {
    char *p = reinterpret_cast<char *>(pTarget);
    while (cbTarget-- > 0) {
        *p++ = static_cast<char>(value);
    }
    return pTarget;
}


has got round the problem. Not an ideal solution, but it will do for now :)
I guess this is about size, so you can link against the runtime dlls - all functions are already in there. Just add msvcrt.lib to your libs.
This requires that the vcredist-package is installed, though - which one exactly depends on your vs version (2005, 2008, 2010).
Or you link the msvcrt.lib which comes with vs6 (from 1998), its' runtime dlls are already shipped with windows since 2000.
Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #6 on: November 23, 2011 »
Or you link the msvcrt.lib which comes with vs6 (from 1998), its' runtime dlls are already shipped with windows since 2000.

That sounds like a good plan Hellfire, thanks.
raizor

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2750
  • Karma: 493
    • View Profile
    • http://www.rbraz.com/
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #7 on: November 27, 2011 »
Or you link the msvcrt.lib which comes with vs6 (from 1998), its' runtime dlls are already shipped with windows since 2000.

@Raizor: This is how I do it all the time :), and if I remember correctly this lib version is included with "tinyptc_ext" on this forum.
Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #8 on: November 27, 2011 »
Cool rbz! Does it bump the exe size much?
raizor

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2750
  • Karma: 493
    • View Profile
    • http://www.rbraz.com/
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #9 on: November 29, 2011 »
It's small as coding it in asm :)
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #10 on: November 29, 2011 »
It only links in the functions you use (and any internal ones it needs) and the code is pretty optimal - the source code for the CRT is included with visual studio so you can check it out and see.
e.g.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src

Jim
Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #11 on: November 29, 2011 »
Thanks Jim and Rbz, useful info :)
raizor

Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #12 on: January 01, 2012 »
Does anyone have a copy of msvcrt.lib from VC6 handy? I checked the Tiny_PTC archive RBZ, but it doesn't seem to be included.

Thanks
raizor

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2750
  • Karma: 493
    • View Profile
    • http://www.rbraz.com/
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #13 on: January 01, 2012 »
Sorry, I thought it was there.

I've attached it here for you  8)


Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Unresolved externals with NODEFAULTLIB flag
« Reply #14 on: January 01, 2012 »
Many thanks Rbz :)
raizor

Challenge Trophies Won: