The g++'s -g option equivalent to VS2010 cl compiler? - visual-studio

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).

Related

How can I add command-line options file to CMake compiler flags?

GCC allows for having command-line options passed by a file by #file syntax. Using this the file should be added as prerequisite (aka dependency) to the target.
I'm not finding any reference in CMake docs about argument files, suggesting it's not supported. Or perhaps just takes a little bit more plumbing, e.g. cat file|xargs? Or some way telling CMake explicitly that the file is a prerequisite? I mean "Prerequisite" according to GNU Make terminology. If file contents change I have to rebuild. AKA dependency.
Which is it? And how does it work?
You should just be able to use target_compile_options() or CXX_<LANG>_FLAGS like you normally would.
Since the flags available for different compilers are usually different, you probably will have one for each compiler you support, in which case you can wrap your target_compile_options() calls with if() blocks based on CMAKE_CXX_COMPILER_ID or the MSVC variable, or use the CXX_COMPILER_ID or X_COMPILER_ID generator expressions to use the right file (if you have multiple files for multiple compilers) for the right compiler.
However, I've also noticed before when trying this that using file flags like this doesn't automatically add the file as a dependency to the target (the CMake won't add a rule for the target to rebuild if that file changes), so you might need to do that manually like this:
# wrap this in a function taking `target` as an argument.
get_target_property(sources ${target} SOURCES)
set_property(SOURCE ${sources}
# DIRECTORY "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
TARGET_DIRECTORY ${target}
APPEND PROPERTY OBJECT_DEPENDS "${PROJECT_SOURCE_DIR}/path/to/flags/file.txt"
)
The above snippet courtesy of a user in this GitHub issue. It uses the OBJECT_DEPENDS source file property to make every source file of a target depend on the compiler options file. I (and the author of that code snippet) would classify it as a workaround, since it only works for Generators that support OBJECT_DEPENDS. From the CMake docs:
Specifies a semicolon-separated list of full-paths to files on which any object files compiled from this source file depend. On Makefile Generators and the Ninja generator an object file will be recompiled if any of the named files is newer than it. Visual Studio Generators and the Xcode generator cannot implement such compilation dependencies.
I'm not sure at what level of the toolchain it would be best to request that such automatic dependency-tracking functionality be added. According some of the Ninja buildsystem maintainers in the above linked GitHub issue, (if my noob brain is understanding the words they're saying correctly :P), it's something that could be handled by compilers when they generate depfiles given a compile comand for a source file. I'm currently too scared to ask compiler maintainers if that's the case. If you're interested in digging onto the part that CMake plays in orchestrating other tools to get dependency tracking for things like header files and the creation of dependency-tracking files ("depfiles"), you can go to your CMake installation's Modules folder and grep for CMAKE_DEPFILE_FLAGS_. Then use "find in files" at https://github.dev/Kitware/CMake.
Notes: Visual Studio / MSVC's compiler calls these "command files", gcc doesn't seem to have a particular name for them, and clang calls these "configuration files". They all support similar #file syntax. I'm not sure what the history is with that, but many compilers aim to have levels of compatibility (similar interface to) with GCC.
That's all. If you're bored and want to read a bit about how CMake does header dependency detection (which is loosely related here on the topic of depfiles), see this other post of mine.

CMake: how to set COMPILE_FLAGS for header files?

I've successfully used CMake to built a shared library, but the size is not so good.
I've already tried several compile flags to cut size, etc.
set_source_files_properties(${TARGET_SOURCE_FILES} PROPERTIES COMPILE_FLAGS "-fexceptions")
Code above is used to open exception handling for single file while -fno-exceptions is added to CMAKE_CXX_FLAG. It works fine.
However, I used the same code to an *.hpp to open rtti for it while -fno-rtti is added to CMAKE_CXX_FLAGS. Unfortunately, it didn't work.
So, is there a way to add COMPILE_FLAGS to header files in CMAKE? I've viewd documentary on offical site, but still no clues.
This is not possible and probably a questionable thing to do in the first place.
Mixing different compile flags within the same binary is a dangerous game. Usually you would want all compilation units in a target to share the same compile flags, as it is very easy to mess things up subtly but terribly otherwise. However, CMake still allows you to use source file properties the way you did to do this if you are really sure what you are doing.
With header files though, things are worse. Headers do not get compiled on their own, so what you are asking for is that all source files that pull in that header will inherit the special compilation options associated with that header. But since all calls to the compiler happen based on source files, this would require to re-run CMake on every source change, check all the includes in all the source files, and adapt the compiler options accordingly. Hopefully you can now see why CMake doesn't want to do this.
What you can do though is specify those options on a per-target basis. Move your headers to an interface target and add a corresponding interface property there. Then, all targets that want to use the header will have to pull in that target as a dependency. As a consequence, all depending source files will get the special compile flags, regardless of whether they actually do include the header or not, but that's just how build systems work:
add_library(my_headers INTERFACE)
target_include_directories(my_headers INTERFACE ${PATH_TO_HEADERS})
target_compile_options(my_headers INTERFACE $<$<CXX_COMPILER_ID:GNU>:-fexceptions>)
add_executable(client a.cpp)
target_link_libraries(client PUBLIC my_headers)
In this example, a.cpp (as well as all other sources of client) will now get compiled with the -fexceptions flag.

Even with /Zf, not all names are in MAP file

I'm building a project for Wintel-32 with Visual Studio's MASM (it's called ML). I request map file generation in linker options. I'm specifying the /Zf option for the assembler (make all symbols global). Yet not all functions appear in the generated map file. Looks like only ones that are imported by other modules appear.
EDIT: there's a bunch of functions that are used only statically (i. e. within the same source file). They are not eliminated from the executable and they shouldn't be. But they don't appear in the MAP file. I want them there.
Those names can be seen if I call dumpbin /symbols on the object file (but only with the /Zf). Yet linker strips it from the final executable's map for some reason. The linker options /MAP and /MAPINFO:EXPORTS are there. What am I missing?
EDIT: and /OPT:NOREF too.
Probably the following options are enabled in your project.
- COMDAT generation i.e. Function-Level Linking during compilation.
- /OPT=NOREF linker optimization during linking.
Both the above options tell the compiler/linker to discard unused functions.
For example, update the command invoking the MASM linker ML, with the /OPT linker option as follows to retain even unused functions in the final executable:
ML [you-options] <your-file-name>/link /OPT:REF

What is happening when you set a compilation path?

I understand it is somehow making a connection so that a compiler when envokes connects a source code to whatever libraries that it needs to.
But what is going on a more technical level, or better put what do I need to know in order to confidentally compile code.
I'm working with C++ and MinGW, and have started to look into build files and stuff for Sublime Text 2 (Have learned mostly under unix, or Java + eclipse so far). But what I don't understand what is adding a compiler to your path do for you?
Do I need to add it for every folder I want to compile from? Or is it system wide? I'm really learning this stuff for the first time, we we're never showed how to set up development environments or even deploy code on other systems.
You probably mean include paths and library paths in the compiler:
include paths: where the compiler will look for headers; and
library paths: where the linker, invoked by the compiler, will look for binary libraries to finish building your project.
If that is the case, look here for a gentle explanation.
Basically, what is happening is that the compiler looks in certain places for symbols defined by the operating system and other libraries installed system-wide.
In addition to those paths, you need to tell the compiler where to find the symbols defined in your own project.
You may also mean something related to installing the compiler itself or configuring the editor to use it.
In that case, what is happening is that you need to tell the build system where to find the executable for the compiler.
Basically, what is probably happening is that your editor wants to know where the compiler is so that it can provide real time feedback on your code. Adding the compiler to the system path will usually, but not always, solve your problem.
In more detail:
A C++ build is a rather complex tool chain, involving determining dependencies, preprocessing, compiling, and linking. There are tools that automate that tool chain, and those tools are in turn wrapped into the functionality of modern IDEs like Eclipse, Visual C++, or Sublime Text 2. You many need to tell your editor where to find the tools it uses to provide you with those services.

Which headers should I not use if I don't want my program to be linked with any of msvc*.dll's?

Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.

Resources