Is possible to pass C++11 param to Buildroot config? - c++

I want to build boost and other packages in buildroot with -std=c++11?
Is it possible to pass it globally, instead by patching program .mk files ?

There is no easy way to pass it globally, and for a good reason: some packages may not build with C++11, e.g. because they use new reserved words.
If you really want to risk it, however, you have three options:
Add -std=c++11 to BR2_TARGET_OPTIMIZATION (in the Toolchain menu). This will be included in the toolchain wrapper and therefore be used for each compile. Note that for C programs, this will give you "command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C" warnings. So packages that to -Werror will break.
Modify package/Makefile.in and add -std=c++11 to TARGET_CXXFLAGS. In this case, it's only passed to C++ compiles. However, TARGET_CXXFLAGS is just passed to the package build system and not all build systems honor it.
Modify toolchain/toolchain-wrapper.c to add this option when g++ is called. This doesn't have the disadvantages of the other two, but is more work to implement.

Related

Add option to CLI based on CMake configuration

I have written a program prg which can be run using bash with some subcommands like so
$ prg subcommand1
Output of subcomman1
$ prg subcommand2
Output of subcomman2
The program is written in C++11 and compiled with CMake (3.10+).
Now, I'd like to add another optional command, say optional_subcommand.
Optional - in a sense that a user can decide whether to compile program with it when configuring Cake.
To clarify, when the code is not compiled withoptional_subcommand support, the output should be something along this lines
$ prg optional_subcommand
Option not supported...
The optional_subcommand requires external library to be installed. Hence find_package(SomeLib REQUIRED) must be invoked at some stage by CMake. The code for optional_subcommand requires this library to compile.
All I can think of is writing some dummy code for optional_subcommand which is then replaced on request by CMake. I think this can be achieved be asking CMake to overwrite, say optional_subcommand.cpp with either dummy or not.
Is proposed solution sensible or perhaps there is a better way to achieve this?
CMake can define a preprocessor symbol and add extra files to your target (below, prg) if needed:
if(SomeLib_FOUND)
target_compile_definitions(prg PUBLIC HAVE_SOMELIB)
target_sources(prg PRIVATE src/optional_subcommand.cpp)
endif()
You can then wrap the command dispatching code for optional_subcommand with #ifdef HAVE_SOMELIB.

Force g++/clang++ to use local `libstdc++.so`

I am trying to compile a library using a specific version of libstdc++.so, not the system one.
The compilation script uses waf.
I tried to export LD_LIBRARY_PATH=<path/to/directory/of/my/libstdc++.so>.
Since I use fish, I have also tried with set --export LD_LIBRARY_PATH <path/to/directory/of/my/libstdc++.so> and LD_LIBRARY_PATH=<path/to/directory/of/my/libstdc++.so> waf
However, until now it still links against the system libstdc++.so
Anyone knows how to force the usage of my libstdc++.so?
You can set the standard library in clang using the -stdlib=<yours> flag. See here for more info: https://clang.llvm.org/docs/ClangCommandLineReference.html
EDIT: Leaving my past answer up there just so that it's a known edit, but you should be able to just use -nostdlib and optionally, -nostdinc, to compile your program. Then to supply your own standard library, just add it as a compiler argument. For example:
clang -nostdinc -nostdlib -I/custom/include/path foo.c /path/to/your/cstdlib.so
For more help configuring the linker, see this post.

Handling Meson build options with multiple buildtypes

Having read the Meson site pages (which are generally high quality), I'm still unsure about the intended best practice to handle different options for different buildtypes.
So to specify a debug build:
meson [srcdir] --buildtype=debug
Or to specify a release build:
meson [srcdir] --buildtype=release
However, if I want to add b_sanitize=address (or other arbitrary complex set of arguments) only for debug builds and b_ndebug=true only for release builds, I would do:
meson [srcdir] --buildtype=debug -Db_sanitize=address ...
meson [srcdir] --buildtype=release -Db_ndebug=true ...
However, it's more of a pain to add a bunch of custom arguments on the command line, and to me it seems neater to put that in the meson.build file.
So I know I can set some built in options thusly:
project('myproject', ['cpp'],
default_options : ['cpp_std=c++14',
'b_ndebug=true'])
But they are unconditionally set.
So a condition would look something like this:
if get_option('buildtype').startswith('release')
add_project_arguments('-DNDEBUG', language : ['cpp'])
endif
Which is one way to do it, however, it would seem the b_ndebug=true way would be preferred to add_project_arguments('-DNDEBUG'), because it is portable.
How would the portable-style build options be conditionally set within the Meson script?
Additionally, b_sanitize=address is set without any test whether the compiler supports it. I would prefer for it to check first if it is supported (because the library might be missing, for example):
if meson.get_compiler('cpp').has_link_argument('-fsanitize=address')
add_project_arguments('-fsanitize=address', language : ['cpp'])
add_project_link_arguments('-fsanitize=address', language : ['cpp'])
endif
Is it possible to have the built-in portable-style build options (such as b_sanitize) have a check if they are supported?
I'm still unsure about the intended best practice to handle different options for different buildtypes
The intended best practice is to use meson configure to set/change the "buildtype" options as you need it. You don't have to do it "all at once and forever". But, of course, you can still have several distinct build trees (say, "debug" and "release") to speed up the process.
How would the portable-style build options be conditionally set within the Meson script?
Talking of b_ndebug, you can use the special value: ['b_ndebug=if-release'], which does exactly what you want. Also, you should take into account, that several GNU-style command-line arguments in meson are always portable, due to the internal compiler-specific substitutions. If I remember correctly, these include: -D, -I, -L and -l.
However, in general, changing "buildtype" options inside a script (except default_options, which are meant to be overwritten by meson setup/configure), is discouraged, and meson intentionally lacks set_option() function.
Is it possible to have the built-in portable-style build options (such as b_sanitize) have a check if they are supported?
AFAIK, no, except has_argument() you've used above. However, if some build option, like b_sanitize, is not supported by the underlying compiler, then it will be automatically set to void, so using it shouldn't break anything.

How to set C++ standard version when build with Bazel?

I'm kinda new to C++. I know how to set C++ version with CMake, but don't know how to set C++ version in Bazel.
Maybe set with the copts parameter in cc_libary but I have to set this in every cc_libary?
To set the standard using the default C++ toolchain in Bazel you can set environment variable BAZEL_CXXOPTS, e.g. BAZEL_CXXOPTS="-std=c++14". You can also set it from the command line or from .bazelrc using --repo_env=BAZEL_CXXOPTS. : is the flag separator.
Alternatively you can pass --cxxopt to Bazel, or put it into .bazelrc, e.g. --cxxopt='-std=c++11'.
The robust solution to specifying C++ toolchain in Bazel is to use the CcToolchainConfigInfo. See the documentation at https://docs.bazel.build/versions/master/tutorial/cc-toolchain-config.html and https://docs.bazel.build/versions/master/cc-toolchain-config-reference.html.
bazel build --cxxopt='-std=c++11' main:hello-world This would work, but I wonder if there's way to set this cxxopt globally, like CMAKE_CXX_FLAGS.
Add this to your .bazelrc next to your WORKSPACE:
build --action_env=BAZEL_CXXOPTS="-std=c++20"
If you want to set multiple options, separate them with a colon:
build --action_env=BAZEL_CXXOPTS="-std=c++20:-Werror"
It is kind of a workaround as bazel sets an environment variable which bazel then uses. But it works.
BTW: build --cxxopt=-std=c++20 in the .bazelrc did not work form me.

How to determine which compiler was requested

My project uses SCons to manage the build process. I want to support multiple compilers, so I decided to use AddOption so the user can specify which compiler to use on the command line (with the default being whatever their current compiler is).
AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', default = DefaultEnvironment()['CXX'], help = 'Name of the compiler to use.')
I want to be able to have built-in compiler settings for various compilers (including things such as maximum warning levels for that particular compiler). This is what my first attempt at a solution currently looks like:
if is_compiler('g++'):
from build_scripts.gcc.std import cxx_std
from build_scripts.gcc.warnings import warnings, warnings_debug, warnings_optimized
from build_scripts.gcc.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
elif is_compiler('clang++'):
from build_scripts.clang.std import cxx_std
from build_scripts.clang.warnings import warnings, warnings_debug, warnings_optimized
from build_scripts.clang.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
However, I'm not sure what to make the is_compiler() function look like. My first thought was to directly compare the compiler name (such as 'clang++') against what the user passes in. However, this immediately failed when I tried to use scons --compiler=~/data/llvm-3.1-obj/Release+Asserts/bin/clang++.
So I thought I'd get a little smarter and use this function
cxx = GetOption('compiler')
def is_compiler (compiler):
return cxx[-len(compiler):] == compiler
This only looks at the end of the compiler string, so that it ignores directories. Unfortunately, 'clang++' ends in 'g++', so my compiler was seen to be g++ instead of clang++.
My next thought was to do a backward search and look for the first occurrence of a path separator ('\' or '/'), but then I realized that this won't work for people who have multiple compiler versions. Someone compiling with 'g++-4.7' will not register as being g++.
So, is there some simple way to determine which compiler was requested?
Currently, only g++ and clang++ are supported (and only their most recently released versions) due to their c++11 support, so a solution that only works for those two would be good enough for now. However, my ultimate goal is to support at least g++, clang++, icc, and msvc++ (once they support the required c++11 features), so more general solutions are preferred.
Compiler just are part of build process. Also you need linker tool and may be other additional programs. In Scons it's named - Tool. List of tools supported from box you can see in man page, search by statement: SCons supports the following tool specifications out of the box: ...
Tool set necessary scons environment variables, it's documented here.
Scons automatically detects compiler in OS and have some priority to choose one of them, of course autodetect will work properly if PATH variable set to necessary dirs. For example of you have msvc and mingw on windows, scons choose msvc tool. For force using tool use Tool('name')(env). For example:
env = Environment()
Tool('mingw')(env)
Now env force using mingw.
So, clang is one of tool which currently not supported from box by scons. You need to implement it, or set env vars such CC, CXX which using scons for generate build commands.
You could just simply use the Python os.path.basename() or os.path.split() functions, as specified here.
You could do what people suggested in the comments by splitting this question into 2 different issues, but I think it could be a good idea to be able to specify the path with the compiler, since you could have 2 versions of g++ installed, and if the user only specifies g++, they may not get the expected version.
There seems to be some confusion about what question is asked here.
For what I can see, this asks how to determine which compiler was chosen by default, so I'll answer that one.
From what I found out, the official way to check the compiler is to look at the construction variable TOOLS, which contains a list of all tools / programs that SCons decided / was told to use in the given construction environment.
env = Environment()
is_gcc = 'g++' in env['TOOLS']
is_clang = 'clangxx' in env['TOOLS']
TOOLS lists only the currently used tools even if SCons can find more of them.
E.g. if you have both GCC and Clang installed and SCons is able to find both, default TOOLS will still contain only GCC.
You can find the full list of predefined tools here.