This commit is contained in:
HiepLM 2026-01-05 18:29:34 +07:00
parent bd6aaac9d4
commit 5eb11f233f

View File

@ -1,4 +1,18 @@
cmake_minimum_required(VERSION 3.0.2)
# ========================================================
# Dual-mode CMakeLists.txt: Supports both Catkin and Standalone CMake
# ========================================================
# Detect if building with Catkin
if(DEFINED CATKIN_DEVEL_PREFIX OR DEFINED CATKIN_TOPLEVEL)
set(BUILDING_WITH_CATKIN TRUE)
message(STATUS "Building robot_cpp with Catkin")
else()
set(BUILDING_WITH_CATKIN FALSE)
message(STATUS "Building robot_cpp with Standalone CMake")
endif()
project(robot_cpp)
set(CMAKE_CXX_STANDARD 17)
@ -9,25 +23,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Find Packages
# ========================================================
if(DEFINED CATKIN_DEVEL_PREFIX OR DEFINED CATKIN_TOPLEVEL)
set(BUILDING_WITH_CATKIN TRUE)
message(STATUS "Building robot_cpp with Catkin")
else()
set(BUILDING_WITH_CATKIN FALSE)
message(STATUS "Building robot_cpp with Standalone CMake")
endif()
if(BUILDING_WITH_CATKIN)
## Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
robot_xmlrpcpp
robot_time
)
catkin_package(
INCLUDE_DIRS include
LIBRARIES robot_cpp
CATKIN_DEPENDS robot_xmlrpcpp robot_time
)
endif()
@ -45,7 +44,105 @@ if(PkgConfig_FOUND)
endif()
endif()
# If pkg-config didn't work, find shared library directly, prioritizing /usr/lib
if(NOT YAML_CPP_TARGET)
# First try system paths (avoid /usr/local which may have static library)
find_library(YAML_CPP_SHARED_LIB
NAMES yaml-cpp
PATHS /usr/lib
PATH_SUFFIXES x86_64-linux-gnu
NO_DEFAULT_PATH
)
if(YAML_CPP_SHARED_LIB AND EXISTS "${YAML_CPP_SHARED_LIB}")
# Verify it's actually a shared library (not a symlink to static)
get_filename_component(YAML_CPP_REAL_LIB "${YAML_CPP_SHARED_LIB}" REALPATH)
if(YAML_CPP_REAL_LIB MATCHES "\\.so")
set(YAML_CPP_TARGET ${YAML_CPP_SHARED_LIB})
message(STATUS "Found yaml-cpp shared library in /usr/lib: ${YAML_CPP_SHARED_LIB}")
# Also find include directory
find_path(YAML_CPP_INCLUDE_DIR
NAMES yaml-cpp/yaml.h
PATHS /usr/include
NO_DEFAULT_PATH
)
if(YAML_CPP_INCLUDE_DIR)
message(STATUS "Found yaml-cpp include directory: ${YAML_CPP_INCLUDE_DIR}")
endif()
endif()
endif()
endif()
# Now use find_package, but temporarily exclude /usr/local to avoid static library
set(CMAKE_PREFIX_PATH_SAVED ${CMAKE_PREFIX_PATH})
list(REMOVE_ITEM CMAKE_PREFIX_PATH "/usr/local")
find_package(yaml-cpp QUIET)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH_SAVED})
# Use target if available and we haven't found a library yet
if(NOT YAML_CPP_TARGET)
if(TARGET yaml-cpp::yaml-cpp)
set(YAML_CPP_TARGET yaml-cpp::yaml-cpp)
message(STATUS "Using yaml-cpp target: yaml-cpp::yaml-cpp")
elseif(TARGET yaml-cpp)
set(YAML_CPP_TARGET yaml-cpp)
message(STATUS "Using yaml-cpp target: yaml-cpp")
else()
# Last resort: try to find any library, but check if it's static
find_library(YAML_CPP_ANY_LIB
NAMES yaml-cpp
PATHS /usr/lib /usr/local/lib /lib
PATH_SUFFIXES x86_64-linux-gnu
)
if(YAML_CPP_ANY_LIB)
if(YAML_CPP_ANY_LIB MATCHES "\\.a$")
message(FATAL_ERROR
"yaml-cpp static library found at: ${YAML_CPP_ANY_LIB}\n"
"This cannot be linked into a shared library.\n"
"Solution: Remove static library or use system shared library:\n"
" sudo rm /usr/local/lib/libyaml-cpp.a\n"
"Or ensure /usr/lib/x86_64-linux-gnu/libyaml-cpp.so is found first."
)
else()
set(YAML_CPP_TARGET ${YAML_CPP_ANY_LIB})
message(STATUS "Found yaml-cpp library: ${YAML_CPP_TARGET}")
endif()
else()
set(YAML_CPP_TARGET yaml-cpp)
message(WARNING "yaml-cpp library not found. Using library name 'yaml-cpp'")
endif()
endif()
endif()
find_package(console_bridge REQUIRED)
# ========================================================
# Catkin specific configuration
# ========================================================
if(BUILDING_WITH_CATKIN)
## The catkin_package macro generates cmake config files for your package
## Note: yaml-cpp and console_bridge are system dependencies, not declared in DEPENDS
## as they don't provide the required INCLUDE_DIRS/LIBRARIES variables for catkin
catkin_package(
INCLUDE_DIRS include
LIBRARIES robot_cpp
CATKIN_DEPENDS robot_xmlrpcpp
)
endif()
###########
## Build ##
###########
## Compiler flags
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Warning flags - disabled to suppress warnings during build
# add_compile_options(-Wall -Wextra -Wpedantic -fPIC)
add_compile_options(-w -fPIC) # -w suppresses all warnings
endif()
## Include directories
include_directories(
include
@ -73,20 +170,32 @@ target_include_directories(${PROJECT_NAME}
## Link libraries
# Use the determined yaml-cpp target/library
if(BUILDING_WITH_CATKIN)
add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(${PROJECT_NAME} ${catkin_TARGETS})
else()
target_link_libraries(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME}
PUBLIC
${YAML_CPP_TARGET}
robot_xmlrpcpp
robot_time
PRIVATE
dl # Required for dladdr() function used in plugin_loader_helper.cpp
)
# Check if we're using static library and warn user
if(YAML_CPP_TARGET MATCHES "\\.a$" OR YAML_CPP_TARGET MATCHES "libyaml-cpp\\.a")
message(FATAL_ERROR
"yaml-cpp static library detected at: ${YAML_CPP_TARGET}\n"
"Static libraries cannot be linked into shared libraries without -fPIC.\n"
"Solution: Install shared library version:\n"
" sudo apt-get install libyaml-cpp-dev\n"
"Or rebuild yaml-cpp with -fPIC flag."
)
endif()
## Add cmake target dependencies
if(BUILDING_WITH_CATKIN)
add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)