I was under the impression that ament build chose to compile things for Release by default.
Is that a correct assumption?
The default is the same as for CMake, which is CMAKE_BUILD_TYPE=None
. Build type of None is neither release nor debug. It does not use the -g
flag, but also does not define the NDEBUG
definition and does not use any -O
flags if I remember correctly. You need to explicitly set a build type if you want Release or Debug or RelWithDebInfo or something else. For example: ament.py build --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo --
It might make sense to do release builds by default for ament. The default configuration does not have much utility, since it is not optimized or has debug information.
My general CMake development process is to use either release or debug mode. Then, if there is a build that only has errors in release mode, I use release with debug information mode.
I did a (very unscientific) test to see how much slower a Release build is than a regular build. Using cmake to build ros_comm on kinetic, I timed just the “make” portion. It took 3 minutes when I did not set the build type, and 4 minutes when I set the build type to “Release”. That’s fairly significant.
The build type can make a huge difference though, particularly for planner code. Some planners I’ve written run 5 to 10 times faster when compiled with Release mode.
Personally, I always use RelWithDebInfo
, but I do so with an alias, something like:
% alias ab
ab='src/ament/ament_tools/scripts/ament.py build \
--build-tests \
--symlink-install \
--isolated \
--cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo --'
As for changing the default, I suppose we could change it in the tool, but I’m hesitant to do so because it only makes sense for CMake building C/C++ code (whereas the tool also builds other things like Python packages, i.e. the cmake build type cannot be generalized to all build system types), and it is a departure from typical CMake development (where the default is None) and catkin development (also where the default is None).
Just to put one more variable in the discussion, building with Release or RelWithDebInfo mode disables the asserts in most code (due to the -DNDEBUG flag), so I am a bit against making either of those the default.
I agree that uninformed people just compile using catkin_make/ament and find that the code runs slower than expected so maybe better documentation about that would be good, maybe even show a warning at the start of build that no optimizations are enabled by default.
I think the confusion was created because Windows build default to Release using ament.
Or, at least, the executables show up in the Release folder. Whether or not all the right flags were set, I haven’t verified.
But because of that, we thought it was the same across the board.
I think helping people be informed is probably the right choice, and leaving it as None is appropriate.
Visual Studio
behaves very different compared to make
when it comes to the CMAKE_BUILD_TYPE
.
When using the Makefile
generator of CMake you select a specific build type by passing -DCMAKE_BUILD_TYPE=...
. The subsequent make invocation builds all the code with that build type. If you don’t specify any it is neither a Debug
nor a Release
build but something else (called None
).
When using the Visual Studio
generator of CMake the generated visual studio project will have configuration for all possible build types. The build type is not selected at CMake configure time. When you then build the Visual Studio project you must select a valid build type (None
is not an option here). When ament_tools
invokes VS it considers the build type you have passed via the command line. If none was passed it has to make a decision and chooses Release
(see https://github.com/ament/ament_tools/blob/5811a5002233fb32da5faab891e6b646430005e4/ament_tools/build_types/cmake.py#L275).