Compiling a simple Win32 program

Hi!

I’ve tried to compile this simple program:

#include <windows.h>

int main()
{
::MessageBoxW(NULL, L"Test!", L"Test!", MB_OK);
return 0;
}

It compiles nicely, but fails to link. Please can you tell me how to specify user32 and gdi32 libraries for the linker? Sorry if I’m being too newbie. :slight_smile:

Thank you a lot!

Best regards
Mello

For example like this
link test.obj user32.lib msvcrt.lib msvcprt.lib

  - Dmitry Sokolov.

Hi Cesar,

Hi!

I've tried to compile this simple program:

#include <windows.h>

int main()
{
::MessageBoxW(NULL, L"Test!", L"Test!", MB_OK);
return 0;
}

It compiles nicely, but fails to link. Please can you tell me how to specify
user32 and gdi32 libraries for the linker? Sorry if I'm being too newbie.

Unfortunately, you did not supply enough information to allow
diagnosing your problem.

* Which clang is it? What is the output of "clang -v"? Where did you
get it? Was it built with MS VC or MinGW?
* What was the compilation command?
* What was the error message?

Csaba

Oh thank you so much Dmitry! It worked perfectly!

clang -c test.cpp
link test.o user32.lib msvcrt.lib msvcprt.lib

clang and llvm are awesome! Congratulations to all for the great work!!!

Best regards
Mello

This could be made to work without a separate link invocation, but
someone would have to teach clang how to properly forward -l arguments
to link.exe. It should actually be pretty simple.

- Michael Spencer

Does clang have a chance to know where to look for LINK.EXE, or does
it just have to assume it's in the path?

I've run into some problems when I had gnuwin32's link.exe (which
creates filesystem links) in the path -- I eventually had to rename it
to glink.exe.

Just a heads-up if someone does work on this.

- Kim

Now that you mention this, I think I had the same problem. It’s interesting since there is a function getVisualStudioDir in the WindowsToolChain.cpp. I’m just not sure how link.exe is invoked, I might look into it.

I think this should do the trick. I’m only unsure about the declaration for getVisualStudioDir that I had to add. Could somebody please review and commit this?

linker-path.txt (686 Bytes)

I forgot to handle the 64bit tool chain, hope this is the right approach.

I’m also not sure what to do with the cross tools? Maybe a check if we’re on a 32bit platform but targeting a 64bit one?

linker-path.txt (770 Bytes)

(+list)

Hi Nikola,

I forgot to handle the 64bit tool chain, hope this is the right approach.

I'm also not sure what to do with the cross tools? Maybe a check if we're on
a 32bit platform but targeting a 64bit one?

Thanks for the effort!

Maybe that's part of why it was cleaner to fall back on the
environment having the "right" linker in the path?

I have three versions of Visual Studio installed side-by-side, and
usually run their respective environment setup script (vsvars32.bat)
to wire up a shell with the right toolchain. That could be considered
a feature of the current approach...

- Kim

I think that Clang records the exact version of Visual Studio it was compiled with, so there should be only one “right” linker?

Hello

I forgot to handle the 64bit tool chain, hope this is the right approach.

1. Please follow LLVM style guidelines (no tabs, etc.)
2. Please use Support/Path library

I'm also not sure what to do with the cross tools? Maybe a check if we're on
a 32bit platform but targeting a 64bit one?

You should check & use target arch.

  1. Please follow LLVM style guidelines (no tabs, etc.)

Sorry about that

  1. Please use Support/Path library

Fixed, but there’s some code in ToolChains.cpp that handles paths the way I did.

You should check & use target arch.

What I have now kinda works. But the problem is that I’m not interested in Clang’s default triple, I’m interested if the OS is 32bit or 64bit. So if I have a 32bit Clang running on my Windows x64 and I’m targeting x64, it will use a cross tools which is wrong! How can I detect this?

linker-path.txt (1.28 KB)

Hi Nikola,

You should check & use target arch.

What I have now kinda works. But the problem is that I'm not interested in
Clang's default triple, I'm interested if the OS is 32bit or 64bit.

I'm not sure what the default triple represents, but there seems to be
four cases;

1) OS architecture is 32-bit, target is 32-bit -- use VC\bin
2) OS architecture is 64-bit, target is 32-bit -- use VC\bin
(Virtualization should allow the 32-bit linker to run and generate
32-bit code)
3) OS architecture is 32-bit, target is 64-bit -- use VC\bin\x86_amd64
4) OS architecture is 64-bit, target is 64-bit -- use VC\bin\amd64

Your if-chain looks right to me, if getDefaultTargetTriple() returns
architecture information that matches the OS.

So if I
have a 32bit Clang running on my Windows x64 and I'm targeting x64, it will
use a cross tools which is wrong! How can I detect this?

It should work, though, thanks to 32-bit virtualization, right?

- Kim

I'm not sure what the default triple represents, but there seems to be
four cases;

Default target triple represents the target triple specified during
build time (can be auto-detected at configure time)

Not really, default triple represents Clang’s default target. I’m using 32-bit Clang on 64-bit Windows and this will work as long as I target x86. But if I target x64 the code that I have right now will select the cross tools. The check should be the same, but this information should be about the OS, not the default target.

Any ideas Anton?

I don't see the immediate problem with it using the cross tools. You
ran a 32-bit compiler, why not run a 32-bit linker as long as it
produces correct x64 code?

- Kim

That’s true, but it just doesn’t seem right :). Let’s see what others have to say.

At the time I did that test, I was so excited that I didn’t realize I was using the MS linker. That does not impact my excitment, but I’m curious if linkers are in the scope of LLVM, and if a Windows linker is planned.

Thanks!

Best regards
Mello

Hi,

Take a look at http://lld.llvm.org. It is the documentation for a planned new linker which will eventually support PE-COFF as well as ELF and so on. I know that somebody is working on this, but it is my impression that help is very much needed.

From what I know, the Microsoft C++ ABI is not supported so you’ll only get away with linking trivial applications using the Microsoft linker. If you want to do advanced C++, you need to use the Mingw32 header files, libraries, and linker. I have tried all the major combinations and the only one that works well at this time is Mingw32 and a 32-bit version of Clang.

Cheers,
Mikael

2012/6/12 Cesar Mello <cmello@gmail.com>