I can set the variable CMAKE_CXX_STANDARD like this
set(CMAKE_CXX_STANDARD 17)
but I can't print it like this
message("This is the C++ Standard we are using: ${CMAKE_CXX_STANDARD}")
I guess the variable CMAKE_CXX_STANDARD doesn't exist by default unless explicitly specified.
In such case, how is the default C++ Standard determined?
I guess the variable CMAKE_CXX_STANDARD doesn't exist by default unless explicitly specified.
Correct. If you need a specific C++ version you should specify.
In such case, how is the default C++ Standard determined?
If you don't specify it depends on the compiler. As an example new versions of MSVC for example default to C++14. As they don't want to maintain C++11 / C++98.
Not specifying the C++ standard is equivalent to not specifying other compiler flags. IE you are fine with the compiler provided defaults. Similar to how if you don't specify RTTI most C++ compilers will assume you want it enabled.
There are some projects that strive to work with whatever the compiler will give them, and a result won't specify the standard. This depends on what you want to support as a developer.
In most cases though it's a good idea to specify the C++ standard for your project.
Related
Are there any compiler independent flags that can be set? I'd like to be able to set single variable to e.g. OPTIMIZE_MOST and get -O3 on gcc and /O2 in MS C++ compiler. Is there something I can use or should flags be set for each compiler separately?
Simply spoken: No, there is no flag to directly set the optimization level independently for every compiler.
However, CMake provides so called build types. Those are independent of the compiler in use and each comes with a predefined selection of flags, one of which is the optimization flag.
Available build types are
Debug
Release
RelWithDebInfo
MinSizeRel
For a comprehensive explanation, I refer to this answer. It also provides some code that helps to identify the flags in question when included into the CMakeLists.txt file:
message("CMAKE_C_FLAGS_DEBUG is ${CMAKE_C_FLAGS_DEBUG}")
message("CMAKE_C_FLAGS_RELEASE is ${CMAKE_C_FLAGS_RELEASE}")
message("CMAKE_C_FLAGS_RELWITHDEBINFO is ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message("CMAKE_C_FLAGS_MINSIZEREL is ${CMAKE_C_FLAGS_MINSIZEREL}")
message("CMAKE_CXX_FLAGS_DEBUG is ${CMAKE_CXX_FLAGS_DEBUG}")
message("CMAKE_CXX_FLAGS_RELEASE is ${CMAKE_CXX_FLAGS_RELEASE}")
message("CMAKE_CXX_FLAGS_RELWITHDEBINFO is ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message("CMAKE_CXX_FLAGS_MINSIZEREL is ${CMAKE_CXX_FLAGS_MINSIZEREL}")
To a degree. For some concepts, CMake has support for specifying them in a compiler-agnostic manner, usually by setting properties on the target in question. Unfortunately, there is no one location where all such possibilities would be listed. I went through the current list of target properties and identified the following properties as "absrtacting away build-tool option syntax":
COMPILE_PDB_NAME
INCLUDE_DIRECTORIES
INSTALL_RPATH
INTERPROCEDURAL_OPTIMIZATION
LINK_DIRECTORIES
LINK_LIBRARIES
PDB_NAME
PDB_OUTPUT_DIRECTORY
(plus the properties for setting output name, path, etc.)
There is apparently nothing for handling optimisation flags other than IPO.
To the best of my knowledge, there is also no generic process for adding these — they are added to CMake as someone finds the need for them (and the time to implement them).
I had an interview recently and was asked this question:
How are cobol programs are called when no compiler option specified?
Static or dynamic?
I answered dynamic, but I am not sure what the correct answer is.
How are cobol programs are called when no compiler option specified? Static or dynamic?
That appears to be a trick question since the default is: CALL literal is static and CALL identifier is dynamic.
See http://publibfp.boulder.ibm.com/epubs/pdf/igy6pg20.pdf,
Enterprise COBOL for z/OS, Programming Guide, Version 6.2,
SC27-8714-01.
Page 338, DLL
Default is: NODLL
Pge 340, DYNAM
Default is: NODYNAM
Page 498, Making static calls
When you use the CALL literal statement in a
program that is compiled using the NODYNAM and NODLL compiler options,
a static call occurs. With these options, all CALL literal calls are
handled as static calls.
Page 499, Making dynamic calls
When you use a CALL literal statement in a program that is compiled
using the DYNAM and the NODLL compiler options, or when you use the
CALL identifier statement in a program that is compiled using the
NODLL compiler option, a dynamic call occurs.
[Emphasis added]
The other answers on DYNAM are correct for how the compiler ships from IBM; making the assumption this is an IBM COBOL compiler.
Default: NODYNAM
That said, every installation sets their own installation defaults for the compiler that in most instances establishes the preferred minimum or default options which are different than the compiler defaults. In general, these are very different than the compiler defaults. Those defaults will tend not to change over time in order to maintain product consistency. They do not represent industry norms or preferences.
The compiler options are documented here for Enterprise COBOL for z/OS 6.2.0.
Note the comment about Installation Defaults:
Installation defaults: The default compiler options that were set up
when your compiler was installed are in effect for your program unless
you override those options. (In some installations, certain compiler
options are fixed so that you cannot override them. If you have
problems with the default options, contact your system administrator.)
To determine which are the default options, run a test compilation
without specifying any compiler options. The output listing lists the
default options in effect at your site.
It's not exactly clear what compiler you are using, but I found some documentation for IBM Enterprise COBOL for z/OS 6.1.0 :
Use DYNAM to cause nonnested, separately compiled programs invoked through the CALL literal statement to be loaded for CALL, and deleted for CANCEL, dynamically at run time.
Here's the sample syntax provided:
DYNAM option syntax
.-NODYNAM-.
>>-+-DYNAM---+-------------------------------------------------><
It further observes that
Default is: NODYNAM
Abbreviations are: DYN|NODYN
So, it looks like the default is static (non-dynamic), with dynamic being a compiler option.
If this is not the compiler you are using, please update your question so we can locate the correct version.
When the variable CMAKE_BUILD_TYPE is empty which compiler flags are used? Does the compiler then simply use CMAKE_CXX_FLAGS and CMAKE_C_FLAGS for C++ and C?
The default will be "empty" or "Debug" depending on the compiler. The value of the variable will be only of interest in places where SOME_VAR_${CONFIG} is used. So to answer your question. From my understanding the debug flags could be added. The documentation (http://www.cmake.org/cmake/help/v3.3/variable/CMAKE_BUILD_TYPE.html) is unfortunately not so clear.
As a comment on https://blog.kitware.com/cmake-and-the-default-build-type/ says, the default (empty) build type is targeted at Linux distributions which want to use the same compiler flags for multiple packages.
There are multiple mechanisms offered by CMake for getting flags to the compiler:
CMAKE_<LANG>_FLAGS_<CONFIG> variables
add_compile_options command
set_target_properties command
Is there one method that is preferred over the other in modern use? If so why? Also, how can this method be used with multiple configuration systems such as MSVC?
For modern CMake (versions 2.8.12 and up) you should use target_compile_options, which uses target properties internally.
CMAKE_<LANG>_FLAGS is a global variable and the most error-prone to use. It also does not support generator expressions, which can come in very handy.
add_compile_options is based on directory properties, which is fine in some situations, but usually not the most natural way to specify options.
target_compile_options works on a per-target basis (through setting the COMPILE_OPTIONS and INTERFACE_COMPILE_OPTIONS target properties), which usually results in the cleanest CMake code, as the compile options for a source file are determined by which project the file belongs to (rather than which directory it is placed in on the hard disk). This has the additional advantage that it automatically takes care of passing options on to dependent targets if requested.
Even though they are little bit more verbose, the per-target commands allow a reasonably fine-grained control over the different build options and (in my personal experience) are the least likely to cause headaches in the long run.
In theory, you could also set the respective properties directly using set_target_properties, but target_compile_options is usually more readable.
For example, to set the compile options of a target foo based on the configuration using generator expressions you could write:
target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
The PUBLIC, PRIVATE, and INTERFACE keywords define the scope of the options. E.g., if we link foo into bar with target_link_libraries(bar foo):
PRIVATE options will only be applied to the target itself (foo) and not to other libraries (consumers) linking against it.
INTERFACE options will only be applied to the consuming target bar
PUBLIC options will be applied to both, the original target foo and the consuming target bar
I am splitting off some of the code in my project into a separate library to be reused in another application. This new library has various functions defined but not implemented, and both my current project and the other application will implement their own versions of these functions.
I implemented these functions in my original project, but they are not called anywhere inside it. They are only called by this new library. As a result, the compiler optimizes them away, and I get linking failures. When I add a dummy call to these functions, the linking failures disappear.
Is there any way to tell GCC to compile these functions even if they're not being called?
I am compiling with gcc 4.2.2 using -O2 on SuSE linux (x86-64_linux_2.6.5_ImageSLES9SP3-3).
You could try __attribute__ ((used)) - see Declaring Attributes of Functions in the gcc manual.
Being a pragmatist, I would just put:
// Hopefully not a name collision :-)
void *xyzzy_plugh_zorkmid_3141592653589_2718281828459[] = {
&functionToForceIn,
&anotherFunction
};
at the file level of one of your source files (or even a brand new source file, something along the lines of forcedCompiledFunctions.c, so that it's obvious what it's for).
Because this is non-static, the compiler won't be able to take a chance that you won't need it elsewhere, so should compile it in.
Your question lacks a few details but I'll give it a shot...
GCC generally removes functions in very few cases:
If they are declared static
In some cases (like when using -fno-implement-inlines) if they are declared inline
Any others I missed
I suggest using 'nm' to see what symbols are actually exported in the resulting .o files to verify this is actually the issue, and then see about any stray 'static' keywords. Not necessarily in this order...
EDIT:
BTW, with the -Wall or -Wunused-function options GCC will warn about unused functions, which will then be prime targets for removal when optimising. Watch out for
warning: ‘xxx’ defined but not used
in your compile logs.
Be careful as the -Wunused-functions doesn't warn of unused functions as stated above. It warns of ununsed STATIC functions.
Here's what the man page for gcc says:
-Wunused-function
Warn whenever a static function is declared but not defined or a non-inline static function is unused. This warning is
enabled by -Wall.
This would have been more appropriate as a comment but I can't comment on answers yet.