Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: Add native cmake build support #15

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ Ifopt is a unified [Eigen]-based interface to use Nonlinear Programming solvers,

## <img align="center" height="20" src="https://i.imgur.com/x1morBF.png"/> Building

* Install the cmake build tool [catkin]: ``$ sudo apt-get install ros-kinetic-catkin``
This package can be built using either [catkin] or [CMake].

* Install [Eigen]: ``$ sudo apt-get install libeigen3-dev``

### Generic
* Install [CMake]: ``$ sudo apt-get install cmake``
* Install [Eigen]: ``$ sudo apt-get install libeigen3-dev``
* Depending on which solver you want to use, install either [Ipopt] or [Snopt]. Follow the instructions provided here:

* https://www.coin-or.org/Ipopt/documentation/node10.html (open source)
Expand All @@ -30,7 +31,8 @@ Ifopt is a unified [Eigen]-based interface to use Nonlinear Programming solvers,
* To build [ifopt_snopt](ifopt_snopt) or [ifopt_ipopt](ifopt_ipopt) set the location of the shared
libraries and header files directly in the [CMakeLists.txt](https://github.com/ethz-adrl/ifopt/blob/fbf7acda4e3e42711031f65e015f6c9f84c87fbd/ifopt_ipopt/CMakeLists.txt#L16-L17)
of the corresponding solver.

### Catkin
* Install the cmake build tool [catkin]: ``$ sudo apt-get install ros-kinetic-catkin``. _
* Clone this repo into your [catkin] workspace and build

$ cd catkin_workspace/src
Expand All @@ -40,7 +42,7 @@ of the corresponding solver.
$ source ./devel/setup.bash


## <img align="center" height="20" src="https://i.imgur.com/026nVBV.png"/> Unit Tests
#### <img align="center" height="20" src="https://i.imgur.com/026nVBV.png"/> Unit Tests

Make sure everything installed correctly by running the unit tests through

Expand All @@ -49,8 +51,28 @@ Make sure everything installed correctly by running the unit tests through
This should also solve the [example problem](ifopt_core/include/ifopt/ex_problem.h) with your installed solvers.
If you have [IPOPT] installed and linked correctly, this should also execute the
binary [ifopt_ipopt-test](ifopt_ipopt/test/ex_test_ipopt.cc).



### CMake
* Clone this repo and configure (``cd`` to desired directory before doing the following)

$ git clone https://github.com/ethz-adrl/ifopt.git
$ mkdir build ; cd build
$ cmake -DCATKIN_BUILD=OFF -DCMAKE_INSTALL_PREFIX=path_to_build_dir ..
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best case this is just cmake .. and the system automatically detects that it should build without catkin and where the files should be installed. Possibly its even better to avoid system-wide installation and just keep all files local in the build folder.


Set ``path_to_build_dir`` to your desired installation target.

* Build

$ make

* Run unit tests

$ make test

* Install

$ make install

## <img align="center" height="20" src="https://i.imgur.com/vAYeCzC.png"/> Usage

For an example of how to use this to efficiently generate dynamic motions for legged robots, check-out [towr].
Expand Down Expand Up @@ -193,5 +215,6 @@ Please report bugs and request features using the [Issue Tracker](https://github
[ROS]: http://www.ros.org
[rviz]: http://wiki.ros.org/rviz
[Fa2png]: http://fa2png.io/r/font-awesome/link/
[CMake]: https://cmake.org/


63 changes: 61 additions & 2 deletions ifopt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,63 @@
cmake_minimum_required(VERSION 2.8.3)
project(ifopt)
find_package(catkin REQUIRED)
catkin_metapackage()
option(CATKIN_BUILD "CATKIN_BUILD" ON)
MESSAGE(STATUS "CATKIN_BUILD is " ${CATKIN_BUILD})

if(${CATKIN_BUILD})
find_package(catkin REQUIRED)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually returns a variable CATKIN_FOUND that could be used instead of the CATKIN_BUILD, that way this flag does not have to be set by the user.

catkin_metapackage()
else()
# do native cmake build
# add gtest and gmock support
# - see http://www.kaizou.org/2014/11/gtest-cmake/
# ------------- BEGIN FROM BLOG ------------------
Copy link
Member

@awinkler awinkler Jun 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole section for unit testing with gtest seems a bit long, as well as there exist some native cmake functions that should handle that (https://cmake.org/cmake/help/v2.8.3/cmake.html#module:FindGTest). I would prefer to do something like they did here (create and download manually, cmake only checks if folder exists,...):
https://github.com/ethz-asl/kindr
They also nicely use .cmake and find scripts, which I think is a good guidline.

# We need thread support
find_package(Threads REQUIRED)

# Enable ExternalProject CMake module
include(ExternalProject)

# Download and install GoogleTest
ExternalProject_Add(
gtest
URL https://github.com/google/googletest/archive/master.zip
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest
# Disable install step
INSTALL_COMMAND ""
)

# Get GTest source and binary directories from CMake project
ExternalProject_Get_Property(gtest source_dir binary_dir)

# Create a libgtest target to be used as a dependency by test programs
add_library(libgtest IMPORTED STATIC GLOBAL)
add_dependencies(libgtest gtest)

# Set libgtest properties
set_target_properties(libgtest PROPERTIES
"IMPORTED_LOCATION" "${binary_dir}/googlemock/gtest/libgtest.a"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
)

# Create a libgmock target to be used as a dependency by test programs
add_library(libgmock IMPORTED STATIC GLOBAL)
add_dependencies(libgmock gtest)

# Set libgmock properties
set_target_properties(libgmock PROPERTIES
"IMPORTED_LOCATION" "${binary_dir}/googlemock/libgmock.a"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
)

# I couldn't make it work with INTERFACE_INCLUDE_DIRECTORIES
include_directories("${source_dir}/googletest/include"
"${source_dir}/googlemock/include")
# ------------- END FROM BLOG ------------------

enable_testing()

# add subdirectories
add_subdirectory("../ifopt_core" "../../ifopt_core/build")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we want to add the base and the "/build" repos here.

add_subdirectory("../ifopt_ipopt" "../../ifopt_ipopt/build")
add_subdirectory("../ifopt_snopt" "../../ifopt_snopt/build")
endif()
94 changes: 57 additions & 37 deletions ifopt_core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
cmake_minimum_required(VERSION 2.8.3)
project(ifopt_core)
option(CATKIN_BUILD "CATKIN_BUILD" ON)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be set from the return value of
find_package(catkin QUIET)`. That way the user doesn't have to worry about it


add_compile_options(-std=c++11)

find_package(catkin REQUIRED)
find_package(Eigen3 REQUIRED)


###################################
## catkin specific configuration ##
###################################
catkin_package(
INCLUDE_DIRS include ${EIGEN3_INCLUDE_DIR}
LIBRARIES ${PROJECT_NAME}
)

if(${CATKIN_BUILD})
find_package(catkin REQUIRED)
catkin_package(
INCLUDE_DIRS include ${EIGEN3_INCLUDE_DIR}
LIBRARIES ${PROJECT_NAME}
)
endif()

###########
## Build ##
Expand All @@ -34,35 +35,54 @@ add_library(${PROJECT_NAME}
#############
## Install ##
#############
# Mark library for installation
install(
TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Mark header files for installation
install(
DIRECTORY include/ifopt/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/ifopt
FILES_MATCHING PATTERN "*.h"
)

if(${CATKIN_BUILD})
# Mark library for installation
install(
TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

#############
## Testing ##
#############
if (CATKIN_ENABLE_TESTING)
catkin_add_gtest(${PROJECT_NAME}-test
test/gtest_main.cc
test/composite_test.cc
test/problem_test.cc)
if(TARGET ${PROJECT_NAME}-test)
target_link_libraries(${PROJECT_NAME}-test
${PROJECT_NAME}
pthread
)
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if the code for cmake build wouldn't have to be repeated for catkin build. But i'm not sure how to handle this in the most flexible way.

# Mark header files for installation
install(
DIRECTORY include/ifopt/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/ifopt
FILES_MATCHING PATTERN "*.h"
)
#############
## Testing ##
#############
if (CATKIN_ENABLE_TESTING)
catkin_add_gtest(${PROJECT_NAME}-test
test/gtest_main.cc
test/composite_test.cc
test/problem_test.cc)
if(TARGET ${PROJECT_NAME}-test)
target_link_libraries(${PROJECT_NAME}-test
${PROJECT_NAME}
pthread
)
endif()
endif()
else()
# cmake native build
file(GLOB CORE_HFILES include/ifopt/*.h)
install(FILES ${CORE_HFILES} DESTINATION include)
install(TARGETS ${PROJECT_NAME} DESTINATION lib)

#############
## Testing ##
#############
file(GLOB CORE_TEST test/*.cc)
add_executable(${PROJECT_NAME}-test ${CORE_TEST})
target_link_libraries(${PROJECT_NAME}-test
${PROJECT_NAME}
libgtest
libgmock
)
add_test(
NAME ${PROJECT_NAME}-test
COMMAND ${PROJECT_NAME}-test
)
endif()

95 changes: 57 additions & 38 deletions ifopt_ipopt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ project(ifopt_ipopt)

add_compile_options(-std=c++11)

find_package(catkin REQUIRED)
find_package(ifopt_core REQUIRED)


################
## Find IPOPT ##
################
Expand All @@ -22,16 +18,18 @@ else()
return()
endif()


#################################
## Generate cmake config files ##
#################################
# These can then be used to "find_package(ifopt_ipopt)"
catkin_package(
INCLUDE_DIRS include ${IPOPT_INCLUDE_DIRS} ${ifopt_core_INCLUDE_DIRS}
LIBRARIES ${PROJECT_NAME}
)

if(${CATKIN_BUILD})
find_package(catkin REQUIRED)
find_package(ifopt_core REQUIRED)
#################################
## Generate cmake config files ##
#################################
# These can then be used to "find_package(ifopt_ipopt)"
catkin_package(
INCLUDE_DIRS include ${IPOPT_INCLUDE_DIRS} ${ifopt_core_INCLUDE_DIRS}
LIBRARIES ${PROJECT_NAME}
)
endif()

###########
## Build ##
Expand All @@ -49,37 +47,58 @@ target_link_libraries(${PROJECT_NAME}
${IPOPT_LIBRARIES}
)


#############
## Install ##
#############
# For this to work, first make sure IPOPT headers and library are installed
# somewhere in the default search paths.
# Mark library for installation
install(
TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
if(${CATKIN_BUILD})
install(
TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Mark header files for installation
install(
DIRECTORY include/ifopt_ipopt/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
)
# Mark header files for installation
install(
DIRECTORY include/ifopt_ipopt/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
)

#############
## Testing ##
#############
if (CATKIN_ENABLE_TESTING)
catkin_add_gtest(${PROJECT_NAME}-test test/ex_test_ipopt.cc)
if(TARGET ${PROJECT_NAME}-test)
target_link_libraries(${PROJECT_NAME}-test
${PROJECT_NAME}
pthread
)
endif()
endif()
else()
# cmake native build
file(GLOB IPOPT_HFILES include/ifopt_ipopt/*.h)
install(FILES ${IPOPT_HFILES} DESTINATION include)
install(TARGETS ${PROJECT_NAME} DESTINATION lib)

#############
## Testing ##
#############
if (CATKIN_ENABLE_TESTING)
catkin_add_gtest(${PROJECT_NAME}-test test/ex_test_ipopt.cc)
if(TARGET ${PROJECT_NAME}-test)
target_link_libraries(${PROJECT_NAME}-test
${PROJECT_NAME}
pthread
)
#############
## Testing ##
#############
file(GLOB IPOPT_TEST test/*.cc)
add_executable(${PROJECT_NAME}-test ${IPOPT_TEST})
target_link_libraries(${PROJECT_NAME}-test
${PROJECT_NAME}
libgtest
libgmock
)

add_test(
NAME ${PROJECT_NAME}-test
COMMAND ${PROJECT_NAME}-test
)
endif()
endif()
Loading