-
Notifications
You must be signed in to change notification settings - Fork 337
Statically allocate string concatenations using FMT formatting #2205
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mini-1235 can you check other parts of code where these kinds of strings are built and can you replace them with fmt ?
Thank you
@saikishor Do I need to do this for the tests as well? |
I don't think it's needed for the tests! |
This pull request is in conflict. Could you fix it @mini-1235? |
e051b0b
to
8332c26
Compare
I can see that the CI is reporting |
For the CI related issues this package may be a good resource to look into: https://github.com/facontidavide/ros2_logging_fmt Probably there are some hints to find here leading to a solution. |
Seems like there is a linking issue. It is missing as a dependency or in the CMakeLists.txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the great work, I have some comments about dependencies.
I never used fmt, so I might be wrong: Which strings should be allocated with fmt? Every string where any variable is included with format specifiers, or +operator of std::string? I made a quick search and still found some occurrences without fmt
controller_manger.cpp: L117, L130, L137, L591, L598, L607, L1357, L1378, L1380, L1424, L1430, L1520, L1574, L1664, L1677, L1690, etc
I suggest searching once again for %s
, %d
, %f,
%lu
, throw
?
@@ -15,10 +15,10 @@ | |||
#ifndef HARDWARE_INTERFACE__COMPONENT_PARSER_HPP_ | |||
#define HARDWARE_INTERFACE__COMPONENT_PARSER_HPP_ | |||
|
|||
#include <fmt/compile.h> | |||
#include <string> | |||
#include <unordered_map> | |||
#include <vector> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please re-add this new-line (google code style)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean two new lines after #define
? Or a new line after `<fmt/compile.h>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reformat the header files in the latest commit, can you please check if that is what you mean @christophfroehlich ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I don't think we need to add target_link_libraries of fmt::fmt every where, in most cases adding to THIS_PACKAGE_INCLUDE_DEPENDS
alone should do, as it is being used in the ament_target_dependencies
I also observed the missing include of fmt in the controller_interface
and controller_manager
along with the dependency in package.xml
and changes in CMakeLists.txt
-> We need this as we want to be with "include-what-you-use" principle
hardware_interface/CMakeLists.txt
Outdated
target_link_libraries(test_joint_handle hardware_interface fmt::fmt) | ||
ament_target_dependencies(test_joint_handle rcpputils fmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
target_link_libraries(test_joint_handle hardware_interface fmt::fmt) | |
ament_target_dependencies(test_joint_handle rcpputils fmt) | |
target_link_libraries(test_joint_handle hardware_interface) | |
ament_target_dependencies(test_joint_handle rcpputils) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -73,13 +74,14 @@ if(BUILD_TESTING) | |||
find_package(rclcpp REQUIRED) | |||
|
|||
ament_add_gmock(joint_limits_rosparam_test test/joint_limits_rosparam_test.cpp) | |||
target_link_libraries(joint_limits_rosparam_test joint_limits) | |||
target_link_libraries(joint_limits_rosparam_test joint_limits fmt::fmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
target_link_libraries(joint_limits_rosparam_test joint_limits fmt::fmt) | |
target_link_libraries(joint_limits_rosparam_test joint_limits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed, but looks like it needs a link in joint_limits
, so I have addedtarget_link_libraries(joint_limits INTERFACE fmt::fmt)
, otherwise it will report
--- stderr: joint_limits
/usr/bin/ld: CMakeFiles/joint_limits_rosparam_test.dir/test/joint_limits_rosparam_test.cpp.o: undefined reference to symbol '_ZN3fmt2v96detail11assert_failEPKciS3_'
/usr/bin/ld: /lib/x86_64-linux-gnu/libfmt.so.9: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/joint_limits_rosparam_test.dir/build.make:222: joint_limits_rosparam_test] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:270: CMakeFiles/joint_limits_rosparam_test.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
joint_limits/CMakeLists.txt
Outdated
|
||
ament_add_gmock(joint_limits_urdf_test test/joint_limits_urdf_test.cpp) | ||
target_link_libraries(joint_limits_urdf_test joint_limits) | ||
target_link_libraries(joint_limits_urdf_test joint_limits fmt::fmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
target_link_libraries(joint_limits_urdf_test joint_limits fmt::fmt) | |
target_link_libraries(joint_limits_urdf_test joint_limits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
I think allocating strings are only required when concatenating? Those only with format specifiers like RCLCPP_DEBUG(
rclcpp::get_logger("ControllerManager::utils"),
"Required interface '%s' with prefix '%s' is not a chain interface.", interface_name.c_str(),
interface_prefix.c_str()); are not required, right? @saikishor |
Yes, it is not required for such cases |
This pull request is in conflict. Could you fix it @mini-1235? |
Sorry for the delayed reply here, I was building a new image on my local machine so that I can reproduce the errors reported by the CI :)
My searching pattern was + " / " +, I think that is enough to find all concatenation cases(?)
Added. |
@mini-1235 can you rebase your changes on top of current master? |
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
b131097
to
2f7cb00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mini-1235 most of the files that have the fmt changes are missing the include of the header. Remember the "include_what_you_use" principle.
Also please fix the pre-commit
joint_limits/CMakeLists.txt
Outdated
@@ -27,6 +28,7 @@ target_include_directories(joint_limits INTERFACE | |||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> | |||
$<INSTALL_INTERFACE:include/joint_limits> | |||
) | |||
target_link_libraries(joint_limits INTERFACE fmt::fmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
target_link_libraries(joint_limits INTERFACE fmt::fmt) |
Isn't the ament_target_dependencies doing the same thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I commented out this line, I can see that the compiler reports a linking error:
--- stderr: joint_limits
/usr/bin/ld: CMakeFiles/joint_limits_rosparam_test.dir/test/joint_limits_rosparam_test.cpp.o: undefined reference to symbol '_ZN3fmt2v96detail11assert_failEPKciS3_'
/usr/bin/ld: /lib/x86_64-linux-gnu/libfmt.so.9: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/joint_limits_rosparam_test.dir/build.make:222: joint_limits_rosparam_test] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:270: CMakeFiles/joint_limits_rosparam_test.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
I will discover why
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just rechecked it locally. you are right. I think your initial approach makes sense here. Just add it to the rosparam test directly :). Sorry for the confusion
target_link_libraries(joint_limits_rosparam_test joint_limits fmt::fmt)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surprisingly, if I remove the line
target_link_libraries(joint_limits INTERFACE fmt::fmt)
I can see more tests report the linking problem:
gmake[2]: *** [CMakeFiles/test_joint_handle.dir/build.make:271: test_joint_handle] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:305: CMakeFiles/test_joint_handle.dir/all] Error 2
gmake[1]: *** Waiting for unfinished jobs....
/usr/bin/ld: CMakeFiles/test_component_interfaces_custom_export.dir/test/test_component_interfaces_custom_export.cpp.o: undefined reference to symbol '_ZN3fmt2v96detail11assert_failEPKciS3_'
/usr/bin/ld: /lib/x86_64-linux-gnu/libfmt.so.9: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/test_component_interfaces_custom_export.dir/build.make:271: test_component_interfaces_custom_export] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:389: CMakeFiles/test_component_interfaces_custom_export.dir/all] Error 2
/usr/bin/ld: CMakeFiles/test_component_interfaces.dir/test/test_component_interfaces.cpp.o: undefined reference to symbol '_ZN3fmt2v96detail11assert_failEPKciS3_'
/usr/bin/ld: /lib/x86_64-linux-gnu/libfmt.so.9: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/test_component_interfaces.dir/build.make:271: test_component_interfaces] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:361: CMakeFiles/test_component_interfaces.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
I believe this happened when they are trying to link to joint_limit
.
It seems that for INTERFACE
libraries, I would need to link it like
target_link_libraries(joint_limits INTERFACE fmt::fmt)
otherwise I would need to link fmt::fmt
in each test, am I correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the joint_limit itself is not using any fmt right?
Co-authored-by: Sai Kishor Kothakota <saisastra3@gmail.com>
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just few minor things, rest looks good
@@ -15,6 +15,8 @@ | |||
#ifndef CONTROLLER_INTERFACE__CHAINABLE_CONTROLLER_INTERFACE_HPP_ | |||
#define CONTROLLER_INTERFACE__CHAINABLE_CONTROLLER_INTERFACE_HPP_ | |||
|
|||
#include <fmt/compile.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mini-1235 As we have included fmt as a build depend only, we will have to place this include in the .cpp, if not we will have to add the dependency to build_export_depend
.
For this reason, if there is no changes in the .hpp, please avoid adding the header include there and move it to .cpp
joint_limits/CMakeLists.txt
Outdated
@@ -27,6 +28,7 @@ target_include_directories(joint_limits INTERFACE | |||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> | |||
$<INSTALL_INTERFACE:include/joint_limits> | |||
) | |||
target_link_libraries(joint_limits INTERFACE fmt::fmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just rechecked it locally. you are right. I think your initial approach makes sense here. Just add it to the rosparam test directly :). Sorry for the confusion
target_link_libraries(joint_limits_rosparam_test joint_limits fmt::fmt)
throw std::runtime_error( | ||
"Invalid data type : '" + interface_description.interface_info.data_type + | ||
"' for interface : " + interface_description.get_name()); | ||
fmt::format( | ||
FMT_COMPILE("Invalid data type : '{}' for interface : {}"), | ||
interface_description.interface_info.data_type, interface_description.get_name())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bmagyar I would like to know your opinion here. fmt is cool when we use it for the string creation etc. I'm just not sure for the exceptions. Do you have a strong opinion here?
@mini-1235 not for this PR but I was wondering if FMT_COMPILE supported specifying the length of the placeholders in the string? it'd gain us fixed length strings |
closes #1906