Cmake change stack size - visual-studio

Is there a way to change stack size from the Cmake ?
I only found one forum thread mentioning CMAKE_CXX_STACK_SIZE but I couldn't find the documentation for this command. Ideally the command should work for both Visual Studio C++ and gcc.

I don't have VS at the moment, but the following three CMake commands all work for me on MinGW/GCC (replace <target> with what you entered into add_executable()):
target_link_libraries(<target> PRIVATE "-Wl,--stack,10000000")
OR
set_target_properties(<target> PROPERTIES LINK_FLAGS -Wl,--stack,10000000)
OR
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--stack,10000000")
Note that according to the CMake documentation, each of these should just add linker flags, not replace any that are already set.
In VS, it looks like you should replace -Wl,--stack, with /STACK: (more on this below) and use an if/else to have different commands for each compiler.
Regarding CMAKE_CXX_STACK_SIZE, this thread, which is worth a read, says the command is
in the implementation of the VS generator for historical reasons but is not intended as a first-class way to set the stack size. Instead just pass /STACK:... as a linker flag using target_link_libraries, or the LINK_FLAGS target property, or in CMAKE_EXE_LINKER_FLAGS...
Such a command can actually be seen on the page linked in your post (not sure if you saw it) as well as in this one:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:10000000")

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.

LinkOnceODRLinkage on Windows for global variables

I'm compiling two files with clang 6.0: testA.c and testB.c.
On both files I am running a custom compiler pass that inserts a zero-initialized global variable called globalVarTest. I set the linkage of such global variable to be LinkOnceODRLinkage.
Now, when I link testA.c and testB.c together (that is, the object files obtained by compiling them separately), the linker complains that there are multiple definitions of globalVarTest.
Isn't LinkOnceODRLinkage supposed to tell the linker that if both definitions match, the symbols is the same and it can therefore pick any of the two definitions when building the final executable?
UPDATE:
The same procedure works on Linux. Is this a limitation of the Windows linker? I have been able to achieve the same effect using COMDAT sections but I wonder why LLVM is not using that mechanism automatically without me requiring to explicitly set COMDATS.
I got an answer from the LLVM mailing list. Using LinkOnceODRLinkage does not work on Windows, even though it used to work in the past.
The best way to achieve the same effect is to explicitly use COMDAT sections. Apparently, this is what was happening automatically by setting LinkOnceODRLinkage, until the behavior changed.

Code::Blocks Linking Options

I was setting up SDL in Code::Blocks 17.12, using MinGW on Windows, and I saw a weird set of options for the linker. I'm new to this, so it could be obvious. Load up a project, go into the Project tab at the top, click on Properties, then click on Project's build options. If you click on Linker settings, you'll find two things. One contains a list of libraries to link, while the other contains a list of options given to the linker in the command itself. Here's a screenshot of what the window looks like:
What I found is that removing the link libraries doesn't mess up the build at all, while removing the linker options messes up everything. Is this something that only happens with SDL? What's the difference between these two sections? What do these flags tell the linker to do?
Okay, this was a pretty simple mistake. After doing some research, I found this post on the forums explaining the problem. The libraries have to be loaded in the exact same order! To answer my first question, SDL does have some weirdness, but this problem can happen with any set of library files. Second, these two sections are basically exactly the same when it comes to linking static library files, but the linker options give you more control and let you specify other flags that the linker might use. Finally, these flags tell the linker to look into the directories provided and embed them into your program, allowing you to use the functionality present in the library in your final executable.
Here's an image showing what I did. Using the same specs as previously provided, the build ran perfectly, and I was successfully able to run the final program.

How to specify preference for compilers when using enable_language [cmake]

When using enable_language in cmake, it always search for compilers in a certain default sequence. I wonder how I can change this sequence. For example, if my system has both ifort (icc) and gfortran (g++) installed, and I want to use ifort (icc) instead of the gfortran (g++), how could I set up this?
CLARIFICATION: I know we can switch the compiler explicitly by changing the variable CMAKE_Fortran_Compiler, but what I want to do is rather to modify the default sequence that cmake searches for available compilers if the user does not specify such a preference.
From what I currently found, a work-around is to set CMAKE_Fortran_Compiler before project(xxx), so that this variable can never gets overridden later, but clearly this is not the best way, since I will need gfortran if there turns out to be no ifort available.
By the way, what's the best place to look for this kind of information? The documentation does not seem to be very complete..
Thanks!
The right place to look is the CMake FAQ, which answers your question.
Omegaice's answer will work, as will CC=/path/to/icc cmake ..., see also this discussion thread.
Setting CMAKE_Fortran_Compiler before the project call is strongly discouraged (as the FAQ will tell you).
Note that manually calling enable_language is no different from specifying the languages with the project call (or indeed not specifying them, in which case they default to C and CXX), since that calls enable_language internally.
You can probably specify which compiler to use by doing ccmake .. -DCMAKE_Fortran_Compiler=<executable> (where <executable> is either the name of the compiler or the full path to the compiler) instead of setting it in the CMakeLists.txt.

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