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

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

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.

Build library archive with undefined references

A colleague of mine told me yesterday that building libfoo.a doesn't require all it's functions to be defined, as long as they will be if you are building an executable that links to it AND that defines that missing reference..
He said that archives are only a collection of object files with indexing, and since object files can be build with undefined references, so can archives..
Is this true ? If so, does this imply that reference resolving is ONLY performed during the linking stage (ie never at compilation or archiving) ?
Thanks a lot.. compiler is gcc by the way, language is c/c++
Yes, all that is perfectly true. You seem to know that libfoo.a
is an ar archive. ar is the GNU
general purpose archiver. It is quite as happy to archive the contents
of your Documents, Pictures and/or Music folders as a collection of object
files.
External symbol resolution is linkage: it is the core business of linkage, and linkage
is done only by the linker. If ar were to supposed to resolve the external symbol references of object files in an archive, then ar,
like the linker, would require command options to specify the external libraries in
which symbol definitions are to be searched for, and the directories in which
those libraries are to be searched for. It hasn't any.
An ar archive may be used as a linker input file. In this case the linker will
search in the archive for any object files that provide definitions for unresolved
symbol references that have accrued from object files already consumed. It will
not care at all what other kinds of files are in the archive, with or
without object files. If it finds any object files that define unresolved references, it extracts
them from the archive and adds them to linkage, exactly as if they had been individually
specified in the commandline and the archive not mentioned at all. So the only role of
an archive in linkage is as a bag of object files from which the linker can pick ones
it needs to carry on.
If we know the right bag to offer the linker, we're spared the difficulty of knowing
exactly which object files within in it the linkage will need. That's the usefulness
of static libraries. In principle, any archive format might have been adopted (.tar, .gz...) But ar was first in
the field, is not burdened with unwanted functionality (directory serialization, compression ...), and was history's choice.
Microsoft LIB format, incidentally, is the same as ar format.
For this role in the service of the linker, GNU ar has specialized a little
for the presence of object files. The s option - which is a default, overrideable by
S - adds a fake "file" to the archive with an empty filename and data that the
linker is able to read as a lookup table from the global symbols defined by any object files in the archive to
the names and positions of those object files. Formerly
(and in non-GNU variants of ar) this kludge was applied by running a separate
program, ranlib on an archive to make it accessible to the linker.
The injection of a ranlib table is what enables the linker to pick the object files it needs out of the archive.
Any undefined references that are brought in with these object files are for the linker to
resolve as usual, from object files or libraries subsequently consumed.
The wording of your question suggests you may be under the impression that "archiving" -
e.g. creating libfoo.a - is one of processes that can be invoked, like compilation
and linkage, through the GCC frontends (gcc, g++, gfortran, etc.) This isn't
so. Those frontends invoke only (one or more of) a preprocessor, a compiler, an assembler
and the linker. Archives are an auxiliary convenience for delivering object files
to the linker and are created straightforwardly with ar:
ar cr libfoo.a file.o...
When this is done, the undefined references within libfoo.a are exactly the
undefined references within file.o ....

Source files missing from ELF symbol table - how to include them?

I am working with a project that was handed off to me and some of the building and linking concepts are new to me. I have a makefile, several assembly and C source files, an ELF file and binary file. When I load the ELF file onto my target, I am only able to step-through the C files, not the assembly files.
When I do a readelf on the ELF file, I see that the assembly (.S) files are missing from the symbol table. Likewise, my debugger (RealView Debugger 4.1) doesn't list those .S files in the "sources from image" tree. I can see that some of the symbols from those files are included (i.e. label names) in my readelf output, but not the file type symbols themselves. I've been going over the makefile to try to spot what may be failing to include them, but I'm not sure what I'm looking for. Can anyone please point me in the right direction? Thanks!
You mentioned using the RealView debugger so I'm making an educated guess that you have RVDS. If so, have you tried using the readelf equivalent that ships with RVDS, fromelf. I have no way to confirm this now but I recall there were subtle differences between assembly code generated by the ARM compiler and gcc.

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

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

Resources