I don't repeat more than necessary, brief summary:
Following the Adder example from this tutorial on a machine with win7 (64) with VS 2010.
But I don't use C++ but plain C.
When using the cl (MS compiler) with cl /Zi (and no other flag) it works like expected.
If not use /Zi and then try to execute the exe goes into flames.
Why?
(There must be some compiler/link options that make some init in the start of the haskell dll go wrong )
EDIT:
Some investigation:
/Zi does not affect optimizations. However, /Zi does imply /debug; see /DEBUG (Generate Debug Info) for more information.
/DEBUG changes the defaults for the /OPT option from REF to NOREF and from ICF to NOICF (so, you will need to explicitly specify /OPT:REF or /OPT:ICF).]
/OPT:ICF can result in the same address being assigned to different functions or read only data members (const variables compiled with /Gy). So, /OPT:ICF can break a program that depends on the address of functions or read-only data members being different. See /Gy (Enable Function-Level Linking) for more information.
Can someone confirm that /OPT:ICF will affect the loading of a Haskell/GHC compiled shared library(dll) ?
Related
I'm trying to wrap my head around how MT and MD options are used when compiling C/C++ projects. However, without being able to expand these supposed abbreviations to meaningful phrases, I forget which one is which from one paragraph to the next. Strangely enough none of the text I've read starts by defining the M, the T and the D. What do they stand for?
From the compiler options link given by chris above:
https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-alphabetically?view=vs-2019
/MD Creates a multithreaded DLL using MSVCRT.lib.
/MDd Creates a debug multithreaded DLL using MSVCRTD.lib.
/MT Creates a multithreaded executable file using LIBCMT.lib.
/MTd Creates a debug multithreaded executable file using LIBCMTD.lib.
Thus MT stands for Multithreaded and MD stands for Multithreaded DLL.
These switches for cl.exe specify which C runtime library to link against; /MT specifies to link with LIBCMT.LIB; /MD specifies to link with MSVCRT.LIB.
The different CRT libraries are described in greater detail here. The primary difference between LIBCMT and MSVCRT is that the former links the CRT statically into your output file, whereas MSVCRT links to the VC runtime DLL (which, unlike its name suggests, is not MSVCRT.DLL (see here)).
DLL and internal may be used as mnemonic to distinguish /MD from /MT.
I would like to compile the Hello World NASM example on windows.
I've pasted the code above into a main.asm file, and compiled it into an obj file with this command:
nasm -fwin32 .\main.asm -o main.obj
After that I wanted to compile this obj file to an exe, like this:
g++ .\main.obj -o main.exe -m32
But I get this error:
C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x39): undefined reference to `WinMain#16'
What do I miss? How is it possible to fix this error?
That Hello World program is trying to create the PE import table manually. In order for that to work, you need to instruct the linker carefully (the PE sections are not tied to PE directories, idata is just a name).
Further assumptions are made in that source (e.g. the base address of the image and the need for the CRT).
Honestly, it's just nonsense. Use the linker properly, like Jester shown.
Being really honest, that whole Wikipedia section is just informational at best.
Long story short: never use Wikipedia as a programming tutorial.
EDIT: The x86-64 Linux example on the Wikipedia page has been updated by Peter Cordes; the others may still be misleading.
A bit of brief theory
You can create a 32-bit Windows console program mainly in two ways:
Use the C run time (CRT)
This lets you use the common C functions (above all printf).
There are two ways to use the CRT:
Statically
The object files resulting from the compilation of the CRT source code are linked with the object file resulting from the compilation/assembling of your source code.
The CRT code is embedded entirely in your application.
In this scenario your main function (main/WinMain/DllMain and unicode variants) is being called by the CRT that runs first by a properly set PE entry-point).
In order to use this method you need the CRT object files, these can be found with Visual Studio or MinGW (to name twos).
The order of execution is: The Windows loader calls your PE entry-point, this is set to something like _mainCRTStartup that initialize the CRT and the CRT calls your main function.
Dynamically
The CRT main dll is msvcrt.dll for the version shipped with Windows installation or msvcrtXX0.dll for the version shipped with Visual Studio installation (where XX depends on the VS version).
The CRT dll has the initialization and tear down code in the DLL entry point so by just putting it in the PE import table the CRT is automagically managed.
The order of execution is: The Windows loader loads your PE dependencies, including the CRT DLL (that got initialised as per above) and then call your PE entry-point.
Use only the Windows API
The Windows API are the OS exposed functions, these are what the CRT implementation ends up calling.
You can use the Windows API and the CRT (the common scenario is for a graphical application to have the CRT statically linked and use WinMain as the entry-point - where the Windows APIs are intermixed with C utility functions) or the Windows API alone.
When using them alone you get a smaller, faster and easy to make executable.
To use 1.1 you need the CRT object files and these are usually shipped with a compiler (they once were shipped with the Windows SDK but now that VS is free Microsoft moved them in the VS package - fair but VS is orders of magnitude more heavy than the SDK).
1.2 and 2 don't need these object files.
Note however that compilers/assemblers/linkers compatibility may be a nasty beast, especially the .lib machinery for linking external APIs (basically libs file are a way to make the linker find the functions that will be resolved by the loader at runtime - i.e. those defined in an external DLL).
Hello, world!
Method 2
First, to write Hello, World! using the method 2., see this other answer of mine.
It was written when a linker was available in the Windows SDK, today I use GoLink.
It is a minimalist, very easy to use, linker.
One key point of it is that it doesn't need the .lib files, instead you can pass it the path of the DLLs where the external functions reside.
The NASM command is the same, to link use:
golink /console /entry main c:\windows\system32\kernel32.dll hello.obj -fo hello.exe
Untested - optionally add /largeaddressaware if you code can handle that
That example is for 64-bit programming, it's more involved than a 32-bit one but may be useful anyway.
Method 1.2
This is what the Wikipedia article is trying to use.
Before analyzing that specific code, let me show how I'd write it:
BITS 32
GLOBAL _main
EXTERN printf
EXTERN exit
SECTION .text
_main:
push strHelloWorld
call printf
add esp, 04h
push 0
call exit
SECTION .data
strHelloWorld db "Hello, world!", 13, 10, 0
This is pretty straightforward compared to the Wiki's one.
To make an executable:
nasm -fwin32 helloworld.asm -o helloworld.obj
golink /console /entry _main c:\windows\system32\msvcrt.dll helloworld.obj -fo helloworld.exe
The Wikipedia's code is creating an .idata sections that stores the PE Import Address Table.
This is a silly move, the linker is used to generate that table based on the dynamic dependencies of the object files.
To make that program link we need to:
Tell the linker that the base address is 0x400000. This can be done with any linker (for golink use /base 0x400000).
Tell the linker that the entry-point is where the .text section starts. I don't know if link.exe can take .text as a valid symbol name or if allows to specify an entry-point relative to .text but that seems very unlikely. Golink won't allow for that. In short a label is probably missing.
Tell the linker to make the Import directory points to the .idata section. I'm not aware of any linker that would allow for that (though it may exists).
In short, forget about it.
Method 1.1
This is what the link Jester pointed out is using.
The assembly code is the same as for 1.2 but you use MinGW for linking.
Some projects in my solution produce this linker warning:
MSIL .netmodule or module compiled with /GL found; restarting link with /LTCG; add /LTCG to the link command line to improve linker performance
I'm using Visual Studio 2013 Update 3. I haven't yet been able to identify anything particular to those projects that could cause this.
What is it about those projects that produces this?
I've looked at this: http://msdn.microsoft.com/en-us/library/k669k83h.aspx
but I'm not aware we are using any CLR, managed code, /LN or /NOASSEMBLY.
I had the same problem, so I did some research.
According to https://msdn.microsoft.com/en-us/library/0zza0de8.aspx :
If you compile your program with /GL and /c, you should use the /LTCG
linker option to create the output file.
So the message can be a bit misleading - the problem is not the MSIL .netmodule, but modules compiled with /GL
When using /GL, you tell the compiler to delay the generation of some code namely around function bounderies, in order to optimise them. LTCG instruct the linker to generate (and optimise) the missing code. Otherwise, the program will not run as expected.
Basically, the two switches should be used together (when used). They apply to different parts of the build: one for compilation and the other one for link.
For completeness:
/GLis controlled from Configuration Properties > C/C++ > Optimization > Whole Program Optimization
/LTCG is controlled from Configuration Properties > Linker > Optimization > Whole Program Optimization
On later versions,
/LTCG is controlled from Configuration Properties > Linker > Optimization > Link Time Code Generation / Use Link Time Code Generation (/LTCG)
I have encountered the same error and spent quite a lot of time trying to fix it. Finally, I figured out that it appeared due to the use of "Whole Program Optimization" option in one of my dependency libraries.
By default, this option is set to "Yes" in newly created projects. When I changed it to "No" and recompiled all dependencies, the warning disappeared. I have purely native C++ solution without any managed code.
To fix, open project settings of all dependency projects and check setting:
Configuration Properties > C/C++ > Optimization > Whole Program Optimization
Make sure it is set to "No" everywhere.
I find the same error goes away by telling the linker about /GL setting you have used:
Set ...
Configuration Properties/Linker/Optimization/Link Time Code Generation
To ...
One of the non-Default settings
Maybe https://msdn.microsoft.com/en-us/library/xbf3tbeh.aspx is of some use?
Neil
This message shows a lot, which is really raising suspicion. I use a property sheet which tells both /GL and /LTCG. The project isn't using any external libraries. And I get this message, which doesn't make any sense. It disappears, if I go to the project properties and specify "Use Link Time Code Generation" again from there. It doesn't change the command line or anything, but just makes VC happy...
With g++ with -g option, I can use gdb for debugging purposes.
What's the equivalent to this option with Visual Studio 2010 cl.exe compiler?
This page has different libraries (debug/release) for linking.
If I compile with debugging option with cl.exe, do I have to use the corresponding library linking options (/MD/MT vs /MDd/MTd)?
There are a few separate pieces to this question: how to tell the compiler/linker to generate and preserve "debug information" (mapping between source code and object code), how to tell the compiler to compile the code differently to make debugging easier (think of assert() and #ifdef _DEBUG), and whether the precompiled libraries you link into your project include debugging information.
-Zi (flag to the CL compiler to tell it to generate debug information) is the equivalent of gcc's -g flag.
(There are other forms of the -Z option: -ZI if you want the "edit and continue" support in the Visual Studio IDE, but if you're using the IDE you're probably using its interface to the compiler settings instead of manipulating them directly, and -Z7 if you want the old CodeView-format debug information; whenever I've invoked CL directly it's always been -Zi that I wanted.)
Note that using the -Zi (or -ZI) option will generate a .pdb file per directory, usually, but when you link code together, it may have come from .obj files represented in different .pdb files, and you also want to combine those separate .pdb files into a master one representing the code you linked together -- this is what the -debug switch for the linker is for.
Also note: this may sound counterintuitive, but always use -Zi (for CL) and -debug (for link.exe). Even for code you're going to release. It doesn't increase the size of your executable, or give away secrets to your customers, since the debug information goes in a separate .pdb file (which you won't ship to customers). If there's any chance you're ever going to have to debug it, you're going to want the .pdb. (-Zi isn't even incompatible with optimizations, though -ZI is. So you might want to compile your "debug" builds with -ZI, and your "release" builds with "-Zi -O2".)
As for the libraries: you don't strictly need to match the debug/release property of the C runtime library with whether your code includes debugging information, but it's usually a good idea -- if you're going to debug the project you want to be able to debug all of it, and if you're not going to debug it you don't need the extra weight. Using debug/release versions of a given library won't affect whether it has debug symbols available (hopefully, if whoever compiled the library understood the point I made in the previous paragraph), but it will affect things like assert and extra #ifdef _DEBUG code in that library.
This goes for all libraries you link with, but especially for the C runtime library -- Microsoft added extra error-detection code to malloc() and free(). So if anything in your project is using the debug flavor of the CRT library, all of it should be.
The /M options (/MTd and /MDd) are weird and magic, in my opinion -- they're just aliases for a complicated set of other stuff going on behind the scenes. Take /MDd for example, documented to "Defines _DEBUG, _MT, and _DLL and causes your application to use the debug multithread- and DLL-specific version of the run-time library. It also causes the compiler to place the library name MSVCRTD.lib into the .obj file." Here, it's affecting both the preprocessor (defining _DEBUG and some other preprocessor symbols) and the linker (it actually puts a #pragma comment(linker) in your source code). If you care about what's going on and don't understand it, this can cause real problems -- I've seen a lot of projects that don't use the IDE get bogged down in warnings about both msvcrt.lib and msvcrtd.lib being linked in, etc. By the time you understand how to use these (/M options) safely, you don't really need them any more! I prefer to make things explicit: specify "-D _DEBUG" directly where I need it, specify which libraries to link with explicitly (and use -nodefaultlib), and then the /M options aren't needed.
You're looking for one of the debug information generation options (/Z7, /Zi or /ZI).
If you use one of those, you should also pass the /DEBUG option to the linker.
You will also need to link against the debug version of the runtime libraries (/MDd or /MTd). This is important because these versions are different from their release counterparts (e.g. their memory allocations routines are not compatible).
When developing and deploying native Windows applications, I often need to install a runtime before being able to run my binary, or statically link the library with my binary. For instance, after building a "Win32 Console" project with Visual Studio 2008, attempting to run the program on a fresh Windows 7 image results in:
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Issues like this one have been brought up in other posts on StackOverflow.
How does one develop applications that don't require runtimes that aren't already on the target OS (i.e. don't require installing redistributable packages or private/shared side-by-side assemblies)? How does one avoid using msvc[mpr]90.dll and just use the Windows API in \windows\system32*.{dll,sys}?
I'm thinking along the lines of the code that comes out of the demoscene, but that's frequently not made available.
Others have already responded with respect to linking CRT statically. If you also want a small binary at the same time, then your best bet is forego CRT entirely, and use only Win32 API functions as much as possible. You'll still get some CRT code, most notably related to startup (i.e. that which calls main) and shutdown (atexit handling etc), but otherwise the linker won't link CRT functions that you do not use.
You can avoid linking CRT altogether by using /Zl compiler switch. This means that main will no longer work, however - you'll need to define WinMain (name doesn't matter, but signature must match, and it must be __stdcall), and you will have to specify the name of your WinMain-like function as an entry point via linker /entry: switch. This will save you ~30Kb of CRT code (tested on a .cpp with an empty main).
If you go the latter route, you might also have to deal with issue of compiler intrinsics. There are some functions that are nominally defined by the CRT (and declared in its headers), but which are treated specially by the compiler, so that it inserts optimized assembly instructions at the point of the call where possible - examples are memset, strlen, and a good chunk of functions in <math.h>; a complete list can be found here. Since you don't have CRT, if you need these functions, or could avoid it but prefer the intrinsic because of improved performance (hard to do better than memset, for example), then you have to declare them yourself, and use #pragma intrinsic. E.g.:
// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h>
extern "C"
{
int abs(int);
void* memset(void*, int, size_t);
}
#pragma intrinsic(abs, memset)
int __stdcall main(void*, void*, char*, int)
{
char tmp[10];
memset(tmp, abs(-123), 10);
return 0;
}
The above can be compiled with:
cl /c /Zl foo.cpp
link /entry:main foo.obj
Link the CRT statically via the /MT switch (and likewise MFC, if you're using it).
Static linking limits what you can do with DLLs somewhat, but for simple executables it works like a charm. (And if you're shipping DLLs, you can always ship private assemblies anyway.)
Use the static CRT. This doesn't create a dependency on msvc*.dll. The CRT is linked directly into your program. This doesn't create dependencies, but does increase the size of your executable.
More info on different CRT options here.
Statically link the runtime. MS Visual C++ has option /MT for that (default is /MD)
I think one way to do this is to just not use Visual Studio and instead rely on the command line SDK tools. (You can alternatively figure out how to config VS to do what you want, but that seems harder.) E.g.:
cl /c app.cpp
link app.obj ws2_32.lib