feat: support basic conan build

This commit is contained in:
insleker 2025-05-27 12:29:59 +08:00
parent 7bdfb82e6b
commit 42a8fd2d45
5 changed files with 306 additions and 154 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/
*Presets.json

View File

@ -3,17 +3,9 @@ cmake_minimum_required(VERSION 3.7.2)
project(kdl_parser)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(catkin QUIET
COMPONENTS rosconsole cmake_modules
)
if(NOT catkin_FOUND)
# use local copies of FindTinyXML.cmake and FindTinyXML2.cmake from
# 'cmake_modules' (https://github.com/ros/cmake_modules)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
endif()
find_package(catkin QUIET COMPONENTS rosconsole cmake_modules)
if(catkin_FOUND)
find_package(urdfdom REQUIRED)
include_directories(${urdfdom_INCLUDE_DIRS})
@ -22,11 +14,12 @@ find_package(orocos_kdl REQUIRED)
find_package(TinyXML REQUIRED)
find_package(TinyXML2 REQUIRED)
# check for rosconsole
# We check additionally for catkin to distinguish between an "official" ROS distribution
# and the one provided in the distribution's repository.
# check for rosconsole We check additionally for catkin to distinguish between
# an "official" ROS distribution and the one provided in the distribution's
# repository.
find_package(rosconsole QUIET)
if(rosconsole_FOUND AND catkin_FOUND)
if(rosconsole_FOUND)
add_definitions(-DHAS_ROS)
endif()
@ -36,57 +29,63 @@ if(urdf_FOUND)
include_directories(${urdf_INCLUDE_DIRS})
endif()
include_directories(include ${orocos_kdl_INCLUDE_DIRS} ${TinyXML_INCLUDE_DIRS} ${TinyXML2_INCLUDE_DIRS})
include_directories(include ${orocos_kdl_INCLUDE_DIRS}
${TinyXML_INCLUDE_DIRS} ${TinyXML2_INCLUDE_DIRS})
if(catkin_FOUND)
link_directories(${catkin_LIBRARY_DIRS})
include_directories(${catkin_INCLUDE_DIRS})
catkin_package(
LIBRARIES ${PROJECT_NAME} ${orocos_kdl_LIBRARIES}
INCLUDE_DIRS include
CATKIN_DEPENDS rosconsole urdf
DEPENDS orocos_kdl TinyXML TinyXML2
)
endif()
LIBRARIES
${PROJECT_NAME}
${orocos_kdl_LIBRARIES}
INCLUDE_DIRS
include
CATKIN_DEPENDS
rosconsole
urdf
DEPENDS
orocos_kdl
TinyXML
TinyXML2)
add_library(${PROJECT_NAME} SHARED src/kdl_parser.cpp)
target_link_libraries(${PROJECT_NAME}
${TinyXML_LIBRARIES} ${TinyXML2_LIBRARIES} ${orocos_kdl_LIBRARIES}
)
target_link_libraries(${PROJECT_NAME} ${TinyXML_LIBRARIES}
${TinyXML2_LIBRARIES} ${orocos_kdl_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${urdfdom_LIBRARIES})
if(catkin_FOUND)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES})
endif()
if(urdf_FOUND)
target_link_libraries(${PROJECT_NAME} ${urdf_LIBRARIES})
endif()
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE "KDL_PARSER_BUILDING_DLL")
target_compile_definitions(${PROJECT_NAME}
PRIVATE "KDL_PARSER_BUILDING_DLL")
endif()
add_executable(check_kdl_parser src/check_kdl_parser.cpp)
target_link_libraries(check_kdl_parser ${PROJECT_NAME})
if(catkin_FOUND AND CATKIN_ENABLE_TESTING)
if(CATKIN_ENABLE_TESTING)
find_package(catkin REQUIRED COMPONENTS roscpp rostest)
add_rostest_gtest(test_kdl_parser test/test_kdl_parser.launch test/test_kdl_parser.cpp )
add_rostest_gtest(test_kdl_parser test/test_kdl_parser.launch
test/test_kdl_parser.cpp)
target_link_libraries(test_kdl_parser ${PROJECT_NAME})
add_rostest_gtest(test_inertia_rpy test/test_inertia_rpy.launch test/test_inertia_rpy.cpp )
add_rostest_gtest(test_inertia_rpy test/test_inertia_rpy.launch
test/test_inertia_rpy.cpp)
target_link_libraries(test_inertia_rpy ${PROJECT_NAME})
endif()
if(catkin_FOUND)
# How does CATKIN do this?
# rosbuild_add_rostest(${PROJECT_SOURCE_DIR}/test/test_kdl_parser.launch)
# Install library
install(TARGETS ${PROJECT_NAME}
install(
TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION})
@ -94,9 +93,49 @@ if(catkin_FOUND)
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})
else()
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION include)
find_package(urdfdom CONFIG REQUIRED)
find_package(orocos-kdl CONFIG REQUIRED)
find_package(tinyxml REQUIRED CONFIG)
find_package(tinyxml2 REQUIRED CONFIG)
add_library(${PROJECT_NAME} src/kdl_parser.cpp)
if(WIN32)
set(BUILD_SHARED_LIBS ON)
target_compile_definitions(${PROJECT_NAME} PUBLIC "KDL_PARSER_BUILDING_DLL")
endif()
target_include_directories(
${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(
${PROJECT_NAME} PUBLIC urdfdom::urdfdom orocos-kdl::orocos-kdl
tinyxml::tinyxml tinyxml2::tinyxml2)
if(NOT BUILD_TESTING STREQUAL OFF)
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
include(GoogleTest)
add_executable(test_kdl_parser test/test_kdl_parser.launch
test/test_kdl_parser.cpp)
target_compile_definitions(
test_kdl_parser
PRIVATE ROBOT_URDF="${CMAKE_CURRENT_SOURCE_DIR}/test/test_robot.urdf")
target_link_libraries(test_kdl_parser ${PROJECT_NAME} GTest::gtest_main)
gtest_add_tests(TARGET test_kdl_parser)
add_executable(test_inertia_rpy test/test_inertia_rpy.launch
test/test_inertia_rpy.cpp)
target_compile_definitions(
test_inertia_rpy
PRIVATE
RPY_URDF1="${CMAKE_CURRENT_SOURCE_DIR}/test/testInertiaRPYmodel1.urdf"
RPY_URDF2="${CMAKE_CURRENT_SOURCE_DIR}/test/testInertiaRPYmodel2.urdf")
target_link_libraries(test_inertia_rpy ${PROJECT_NAME} GTest::gtest_main)
gtest_add_tests(TARGET test_inertia_rpy)
endif()
endif()

75
kdl_parser/conanfile.py Normal file
View File

@ -0,0 +1,75 @@
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.build import check_min_cppstd, can_run
from conan.errors import ConanInvalidConfiguration
class kdl_parserRecipe(ConanFile):
name = "kdl_parser"
version = "2.12.1"
package_type = "library"
license = ""
author = "orocos ()"
url = ""
description = " kdl_parser and kdl_parser_py provide tools to construct a KDL tree from an XML robot representation in URDF."
topics = ("KDL", "URDF", "parser")
settings = "os", "compiler", "build_type", "arch"
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {"shared": False, "fPIC": True}
exports_sources = (
"CMakeLists.txt",
"src/*",
"tests/*",
"include/*",
)
def requirements(self):
self.requires("orocos-kdl/[>=1.5.1 <2]")
self.requires("tinyxml/[>=2.6.0 <3]")
self.requires("tinyxml2/[>=11.0.0 <13.0.0]")
self.requires("urdfdom/[>=3.1.1 <5.0.0]")
self.requires("urdfdom_headers/[>=1.1.1 <2]")
self.tool_requires("cmake/[>=3.12 <5]")
self.test_requires("gtest/[>=1.11]")
def validate(self):
check_min_cppstd(self, "14")
def config_options(self):
if self.settings.os == "Windows":
self.options.rm_safe("fPIC")
def configure(self):
if self.settings.os == "Windows" and not self.options.shared:
raise ConanInvalidConfiguration(
"Static libraries are not supported on Windows. Please set option 'shared=True'."
)
if self.options.shared:
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self)
def generate(self):
deps = CMakeDeps(self)
deps.generate()
tc = CMakeToolchain(self)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.libs = ["kdl_parser"]

View File

@ -41,10 +41,17 @@
#include <kdl/jntarray.hpp>
#include <kdl/chainidsolver_recursive_newton_euler.hpp>
#include <ros/ros.h>
#include <ros/console.h>
#include "kdl_parser/kdl_parser.hpp"
#ifdef HAS_ROS
#include <ros/ros.h>
#else
// forward ROS warnings and errors to stderr
#define ROS_DEBUG(...) fprintf(stdout, __VA_ARGS__);
#define ROS_ERROR(...) fprintf(stderr, __VA_ARGS__);
#define ROS_WARN(...) fprintf(stderr, __VA_ARGS__);
#endif
int g_argc;
char **g_argv;
@ -63,8 +70,8 @@ protected:
}
};
TEST_F(TestInertiaRPY, test_torques) {
TEST_F(TestInertiaRPY, test_torques)
{
// workaround for segfault issue with parsing 2 trees instantiated on the stack
KDL::Tree *tree_1 = new KDL::Tree;
KDL::Tree *tree_2 = new KDL::Tree;
@ -115,10 +122,21 @@ TEST_F(TestInertiaRPY, test_torques) {
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
ros::init(argc, argv, "test_kdl_parser");
for (size_t i = 0; i < argc; ++i) {
#ifdef HAS_ROS
ros::init(argc, argv, "test_inertia_rpy");
#endif
for (size_t i = 0; i < argc; ++i)
{
std::cout << argv[i] << std::endl;
}
if (argc < 3)
{
static const char *default_argv[] = {argv[0], RPY_URDF1, RPY_URDF2};
argc = 3;
argv = const_cast<char **>(default_argv);
}
g_argc = argc;
g_argv = argv;
return RUN_ALL_TESTS();

View File

@ -35,9 +35,17 @@
/* Author: Wim Meeussen */
#include <gtest/gtest.h>
#include <ros/ros.h>
#include "kdl_parser/kdl_parser.hpp"
#ifdef HAS_ROS
#include <ros/ros.h>
#else
// forward ROS warnings and errors to stderr
#define ROS_DEBUG(...) fprintf(stdout, __VA_ARGS__);
#define ROS_ERROR(...) fprintf(stderr, __VA_ARGS__);
#define ROS_WARN(...) fprintf(stderr, __VA_ARGS__);
#endif
int g_argc;
char **g_argv;
@ -58,9 +66,10 @@ protected:
}
};
TEST_F(TestParser, test) {
for (int i = 1; i < g_argc - 2; i++) {
TEST_F(TestParser, test)
{
for (int i = 1; i < g_argc - 2; i++)
{
ROS_ERROR("Testing file %s", g_argv[i]);
ASSERT_FALSE(kdl_parser::treeFromFile(g_argv[i], my_tree));
}
@ -72,15 +81,24 @@ TEST_F(TestParser, test) {
ASSERT_EQ((unsigned int)1, my_tree.getRootSegment()->second.children.size());
ASSERT_TRUE(my_tree.getSegment("base_link")->second.parent == my_tree.getRootSegment());
ASSERT_EQ(10.0, my_tree.getSegment("base_link")->second.segment.getInertia().getMass());
ASSERT_NEAR(1.000, my_tree.getSegment(
"base_link")->second.segment.getInertia().getRotationalInertia().data[0], 0.001);
ASSERT_NEAR(1.000, my_tree.getSegment("base_link")->second.segment.getInertia().getRotationalInertia().data[0], 0.001);
SUCCEED();
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
#ifdef HAS_ROS
ros::init(argc, argv, "test_kdl_parser");
#endif
if (argc < 2)
{
static const char *default_argv[] = {argv[0], ROBOT_URDF};
argc = 2;
argv = const_cast<char **>(default_argv);
}
g_argc = argc;
g_argv = argv;
return RUN_ALL_TESTS();