Compilation options for different versions of Clang, GCC, MSVC, Emscripten, ICC and ICX. Provided a generator and different file formats (build system and compiler).
The output
directory contains files for cmake
, xmake
, premake5
, meson
, bjam
/b2
, scons
and command-line options for gcc
/g++
, clang
/clang++
and msvc
. If a version of the compiler is not present, then there is no difference compared to an older version.
Each build system also has a branch with only the files it needs.
Here is an example with gcc:
int main()
{
int x;
return x; // used but uninitialized
}
$ g++ main.cpp
No output
$ g++ main.cpp @cpp-compiler-options/output/cpp/gcc/gcc-6.1-warnings
main.cpp: In function ‘int main()’:
main.cpp:4:10: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
4 | return x; // used but not initialized
| ^
(@file
is a special option of gcc and clang for read command-line options from file.)
Supported options are listed below by category. The same option can be found in several categories.
The first value corresponds to the one used by default,
and the value default
has no associated behavior.
Options with a default value other than default
are listed below.
# Warning:
warnings = on default off essential extensive
warnings_as_error = default off on basic
conversion_warnings = on default off sign float conversion all
covered_switch_default_warnings = on default off
fix_compiler_error = on default off
msvc_crt_secure_no_warnings = on default off
noexcept_warnings = default off on
reproducible_build_warnings = default off on
shadow_warnings = off default on local compatible_local all
suggestions = default off on
switch_warnings = on default off exhaustive_enum mandatory_default exhaustive_enum_and_mandatory_default
unsafe_buffer_usage_warnings = default on off
windows_abi_compatibility_warnings = off default on
# Pedantic:
msvc_conformance = all default all_without_throwing_new
pedantic = on default off as_error
stl_fix = on default off
# Debug:
debug = default off on gdb lldb vms codeview dbx sce
debug_level = default 0 1 2 3 line_tables_only line_directives_only
stl_hardening = default off fast extensive debug debug_with_broken_abi
control_flow = default off on branch return allow_bugs
sanitizers = default off on
float_sanitizers = default off on
integer_sanitizers = default off on
other_sanitizers = default off thread pointer memory
var_init = default uninitialized pattern zero
ndebug = with_optimization_1_or_above default off on
optimization = default 0 g 1 2 3 fast size z
# Optimization:
cpu = default generic native
linker = default bfd gold lld mold native
lto = default off on normal fat thin
optimization = default 0 g 1 2 3 fast size z
whole_program = default off on strip_all
# C++:
exceptions = default off on
rtti = default off on
# Hardening:
control_flow = default off on branch return allow_bugs
relro = default off on full
stack_protector = default off on strong all
stl_hardening = default off fast extensive debug debug_with_broken_abi
# Analyzer:
analyzer = default off on
analyzer_too_complex_warning = default off on
analyzer_verbosity = default 0 1 2 3
# Other:
color = default auto never always
coverage = default off on
diagnostics_format = default fixits patch print_source_range_info
diagnostics_show_template_tree = default off on
elide_type = default off on
msvc_diagnostics_format = caret default classic column
msvc_isystem = default anglebrackets include_and_caexcludepath external_as_include_system_flag assumed
msvc_isystem_with_template_from_non_external = default off on
pie = default off on static fpic fPIC fpie fPIE
windows_bigobj = on default
If not specified:
msvc_conformance
isall
msvc_diagnostics_format
iscaret
ndebug
iswith_optimization_1_or_above
- The following values are
off
:shadow_warnings
windows_abi_compatibility_warnings
- The following values are
on
:conversion_warnings
covered_switch_default_warnings
fix_compiler_error
msvc_crt_secure_no_warnings
pedantic
stl_fix
switch_warnings
warnings
windows_bigobj
control_flow=allow_bugs
- clang: Can crash programs with "illegal hardware instruction" on totally unlikely lines. It can also cause link errors and force
-fvisibility=hidden
and-flto
.
- clang: Can crash programs with "illegal hardware instruction" on totally unlikely lines. It can also cause link errors and force
msvc_isystem=external_as_include_system_flag
is only available withcmake
.stl_hardening=debug
- msvc: unlike
stl_hardening=debug_with_broken_abi
, STL debugging is not enabled by this option, as it breaks the ABI (only hardening mode is enabled on recent versions). However, as the_DEBUG
macro can be defined in many different ways, STL debugging can be activated and the ABI broken.
- msvc: unlike
category | options |
---|---|
debug | control_flow=on debug=on sanitizers=on stl_hardening=debug_with_broken_abi or debug optimization=g or optimization=0 + debug_level=3 |
release | cpu=native lto=on or thin optimization=3 rtti=off whole_program=strip_all |
security | control_flow=on relro=full stack_protector=strong pie=fPIE stl_hardening=fast or extensive |
really strict warnings | pedantic=as_error shadow_warnings=local suggestions=on warnings=extensive |
This is what enabled of sanitizers looks like with the different build systems available:
$ cmake -DJLN_SANITIZERS=on
$ xmake f --jln-sanitizers=on
$ premake5 --jln-sanitizers=on
$ meson -Djln_sanitizers=on
$ bjam -s jln_sanitizers=on
$ scons jln_sanitizers=on
(jln
is a parameterizable prefix: ./compiler-options.lua generators/cmake.lua [prefix]
)
# launch example: cmake -DJLN_SANITIZERS=on
include(output/cpp/cmake)
# init default values
# jln_init_flags(
# [<jln-option> <default_value>]...
# [AUTO_PROFILE on]
# [VERBOSE on]
# [BUILD_TYPE type [<jln-option> <default_value>]...]...
# )
# AUTO_PROFILE: enables options based on CMAKE_BUILD_TYPE
# (assumes "Debug" if CMAKE_BUILD_TYPE is empty)
# BUILD_TYPE: enables following options only if ${CMAKE_BUILD_TYPE}
# has the same value (CMAKE_BUILD_TYPE assumed to Debug if empty)
jln_init_flags(
SUGGESTIONS on # set SUGGESTIONS default value to "on"
BUILD_TYPE debug
SANITIZERS on # set SANITIZERS default value to "on" only in Debug build
BUILD_TYPE release
LTO on # set LTO default value to "on" only in Release build
)
# jln_target_interface(
# <libname> {INTERFACE|PUBLIC|PRIVATE}
# [<jln-option> <value>]...
# [DISABLE_OTHERS {on|off}]
# [BUILD_TYPE type [<jln-option> <value>]...]...
# )
jln_target_interface(mytarget1 INTERFACE WARNINGS very_strict) # set WARNINGS to "very_strict"
# jln_flags(
# CXX_VAR <out-variable>
# LINK_VAR <out-variable>
# [<jln-option> <value>]...
# [DISABLE_OTHERS {on|off}]
# [BUILD_TYPE type [<jln-option> <value>]...]...
# )
jln_flags(CXX_VAR CXX_FLAGS LINK_VAR LINK_FLAGS WARNINGS very_strict)
target_link_libraries(mytarget2 INTERFACE ${LINK_FLAGS})
target_compile_options(mytarget2 INTERFACE ${CXX_FLAGS})
# NOTE: for C, jln_ prefix function becomes jln_c_ and CXX_VAR becomes C_VAR
Copy output/cpp/xmake_options.lua
to myproj/cpp/xmake.lua
and output/cpp/xmake
to myproj/cpp/flags.lua
. cpp
is an arbitrary directory name, this can be changed.
-- launch example: xmake f --jln-sanitizers=on
includes'cpp'
-- Registers new command-line options and set default values
jln_cxx_init_options({warnings='very_strict', warnings_as_error='basic'})
-- Set options for a specific mode (see also jln_cxx_rule())
-- When the first parameter is nil or unspecified, a default configuration is used.
jln_cxx_init_modes({
debug={
stl_hardening='debug_with_broken_abi',
},
release={
function() ... end, -- callback for release mode
lto='on',
},
-- ...
})
target('hello1')
set_kind('binary')
add_files('src/hello.cpp')
-- Create a new rule. Options are added to the current configuration
jln_cxx_rule('custom_rule', {warnings_as_error='on'})
target('hello2')
set_kind('binary')
add_rules('custom_rule')
add_files('src/hello.cpp')
target('hello3')
set_kind('binary')
-- Custom configuration when jln_cxx_rule() or jln_cxx_modes() are not enough
on_load(function(target)
import'cpp.flags'
-- see also get_flags() and create_options()
local flags = flags.set_flags(target, {elide_type='on'})
print(flags)
end)
add_files('src/hello.cpp')
-- NOTE: for C, jln_cxx_ prefix become jln_c_
Copy output/cpp/meson_options.txt
and rename output/cpp/meson
to meson_jln_flags/meson.build
.
# launch example: meson -Djln_sanitizers=on
# note: `meson --warnlevel=0` implies `--Djln_warnings=off`
project('test', 'cpp')
# default options (without prefix)
# optional
jln_default_flags = {'rtti': 'off'}
# options for specific buildtype (added to default options)
# optional.
jln_buildtype_flags = {
'debug': {'rtti': 'on'},
}
# Use a default configuration when jln_buildtype_flags is unspecified.
# optional.
jln_use_profile_buildtype = true
# optional
jln_custom_flags = [
{'rtti': 'off', 'optimization': '3'}, # (0) opti flags
{'debug': 'on'}, # (1) debug flags
# { ... } # (2)
# etc
]
# declare jln_link_flags, jln_cpp_flags, jln_custom_cpp_flags and jln_custom_link_flags
subdir('meson_jln_flags')
my_opti_cpp_flags = jln_custom_cpp_flags[0] # (0) opti flags (see above)
my_opti_link_flags = jln_custom_link_flags[0]
my_debug_cpp_flags = jln_custom_cpp_flags[1] # (1) debug flags (see above)
my_debug_link_flags = jln_custom_link_flags[1]
# my_... = jln_custom_cpp_flags[2] # (2)
# my_... = jln_custom_link_flags[2]
# etc
executable('demo', 'main.cpp', link_args: jln_link_flags, cpp_args: jln_cpp_flags)
# NOTE: for C, jln_ prefix becomes jln_c_
-- launch example: premake5 --jln-sanitizers=on
include "output/cpp/premake5"
-- Registers new command-line options and set default values
jln_newoptions({warnings='very_strict'})
-- getoptions(values = {}, disable_others = false, print_compiler = false)
-- `values`: table. ex: {warnings='on'}
-- `values` can have 3 additional fields:
-- - `cxx`: compiler name (otherwise deducted from --cxx and --toolchain)
-- - `cxx_version` (otherwise deducted from cxx)
-- - `ld`: linker name
-- `disable_others`: boolean
-- `print_compiler`: boolean
-- return {cxxflags=table, ldflags=table}
-- Note: with C language, cxxflags, cxx and cxx_version become cflags, cc and cc_version
local options = flags.getoptions({elide_type='on'})
for _,opt in ipairs(options.cxxflags) do target:add('cxxflags', opt, {force=true}) end
for _,opt in ipairs(options.ldflags) do target:add('ldflags', opt, {force=true}) end
-- or equivalent (return also options)
flags.setoptions(target, {elide_type='on'})
-- return the merge of the default values and new value table
local values = flags.tovalues({elide_type='on'}, --[[disable_others:bool]])
print(values)
-- jln_getoptions(values = {}, disable_others = false, print_compiler = false)
-- `values`: table. ex: {warnings='on'}
-- `values` can have 3 additional fields:
-- - `cxx`: compiler name
-- - `cxx_version` (otherwise deducted from cxx)
-- - `ld`: linker name
-- `disable_others`: boolean
-- `print_compiler`: boolean
-- return {buildoptions=table, linkoptions=table}
-- Note: with C language, cxx and cxx_version become cc and cc_version
local mylib_options = jln_getoptions({elide_type='on'})
buildoptions(mylib_options.buildoptions)
linkoptions(mylib_options.linkoptions)
-- or equivalent
jln_setoptions({elide_type='on'})
-- returns the merge of the default values and new value table
local values = jln_tovalues({elide_type='on'}, --[[disable_others:bool]])
print(values)
-- NOTE: for C, jln_ prefix function becomes jln_c_
# launch example: bjam -s jln_sanitizers=on
include output/cpp/bjam ;
# rule jln_flags ( properties * )
project name : requirements
<jln-lto-default>on # enable jln-lto
<jln-relro-default>on
<conditional>@jln_flags
: default-build release ;
exe test : test.cpp : <jln-relro-incidental>off # incidental version of <jln-relro>off
# NOTE: for C, jln_flags becomes jln_c_flags
# launch example: scons jln_sanitizers=on
import jln_options as jln
jln.set_global_flags({'rtti': 'off'})
vars = Variables(None, ARGUMENTS)
jln.add_variables(vars, {'debug':'on'}) # default value of debug to on
# get_flags(variables[, env]) -> {flags=[...], linkflags=[...]}
flags1 = jln.get_flags(vars)
flags2 = jln.get_flags({'debug':'on'})
The scripts below add 4 aliases with warnings=on
, pedantic=on
and color=always
.
gw++
for g++cw++
for clang++
for comp in g++ clang++ ; do
version=$($comp --version | sed -E '1!d;s/.*([0-9]\.[0-9]\.[0-9]).*/\1/g')
echo "alias ${comp:0:1}w++='$comp "$(./compiler-options.lua generators/compiler.lua "$comp-$version" warnings pedantic color=always)\'
done >> ~/.bashrc
gwcc
for gcccwcc
for clang
for comp in gcc clang ; do
version=$($comp --version | sed -E '1!d;s/.*([0-9]\.[0-9]\.[0-9]).*/\1/g')
echo "alias ${comp:0:1}wcc='$comp "$(./compiler-options.lua -c generators/compiler.lua "$comp-$version" warnings pedantic color=always)\'
done >> ~/.bashrc
Usage:
./compiler-options.lua [-h] [-p] [-c] [-o outfilebase]
[-t [-]{platform|compiler|linker}=name[,...]]
[-f [-]{option_name[=value_name][,...]}]
[-d option_name=value_name[,...]]
{generator} [options...]
./compiler-options.lua -f debug,warning generators/cmake.lua # only with debug and warning
./compiler-options.lua -f -debug,warning generators/cmake.lua # without debug nor warning
-p
Print an AST.-c
for C, default is C++.-t
Restrict to a list of platform, compiler or linker. When the list is prefixed with '-', values are removed from current AST.-f
Restrict to a list of option/value. When the list is prefixed with-
, options/values are removed.-d
Set new default value. An empty string forvalue_name
is equivalent todefault
.
See ./compiler-options.lua generators/compiler.lua -h
for detailed usage information.
$ ./compiler-options.lua generators/list_options.lua [--profile] [--color]
Checks and displays options and their values.
Generators for different build system.
$ ./compiler-options.lua [-o filebase] {generator} [option-prefix]
Edit compiler-options.lua
file.
The MakeAST
function contains the options tree.
_koptions
of Vbase
contains the list of available options.
_opts_by_category
a categorization of these options.
c
,cxx
,flag
,link
,fl
c'-Wall' -- C only
cxx'-Wall' -- C++ only
flag'-Wall' -- C and C++
link'-flto' -- Link option
fl'xxx' -- is a alias of {flag'xxx',link'xxx'}
gcc
for gcc or g++clang
for clang or clang++clang_cl
for clang-clclang_emcc
refers to the version of clang used by emccclang_like
refers toclang
,clang_cl
andclang_emcc
msvc
for clicc
icl
lld_link
for lld-linkld64
icx
, icpx
, dpcpp
are equivalent to clang
.
With mingw
, the compiler is gcc
.
version can be specified with vers
or a compiler name and a parameter of the form {operator}{major}.{minor}
.
gcc { ... } -- for gcc only
gcc'>=5' { ... } -- for >= gcc-5
gcc'>=5.3' { ... } -- for >= gcc-5.3
gcc'<5.3' { ... } -- for < gcc-5.3
gcc'>=5.3' { ... } -- equivalent to `gcc { vers'>=5.3' { ... } }`
linux
windows
macos
mingw
withgcc
as compiler
opt'name' { ... }
lvl'name' { ... }
opt'warnings' { -- if warnings is enabled (not `warnings=default`)
lvl'off' { cxx'-w' } -- for `warnings=off`
}
has_opt'name' { ... }
opt'warnings' {
has_opt'debug' { -- if debug is enabled (not `debug=default`)
lvl'off' { cxx'-w' } -- for `warnings=off`, not debug=off
}
}
has_opt'debug':with('gdb', 'on') { -- if debug is 'on' or 'gdb'
...
}
has_opt'debug':without('gdb', 'on') { -- if debug is not 'default', 'on' or 'gdb'
...
}
reset_opt'name'
for disabled an option
vers'<8' {
reset_opt'lto' -- disable lto option when version < 8
}
Or(...)
And(...)
Or(gcc, clang, msvc) { ... }
And(gcc, lvl'off') { ... }
Compilers, linkers, platforms and condition returns a if_mt
.
-xxx {...}
fornot xxx
xxx {...} / yyy {...}
forxxx or else yyy
opt'warnings' { -lvl'on' { ... } } -- neither warnings=on nor warnings=default
lvl'on' { xxx } / { yyy } -- equivalent to `{ lvl'on' { xxx }, -lvl'on' { yyy } }`
Note: -opt'name'
isn't allowed
if_else(cond, f)
=cond { f(true) } / f()
match(a,b,c,...)
=a / b / c / ...
act(data)
for a specific action hardcoded into a generator- cmake:
data
must be a table which can contain the keys:cxx
: add the value inCMAKE_CXX_FLAGS
/CMAKE_C_FLAGS
system_flag
: add the value inCMAKE_INCLUDE_SYSTEM_FLAG_CXX
/CMAKE_INCLUDE_SYSTEM_FLAG_C
.
- cmake: