Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • ostasse/dynamic-graph-python
  • gsaurel/dynamic-graph-python
  • stack-of-tasks/dynamic-graph-python
3 results
Select Git revision
Show changes
......@@ -8,30 +8,33 @@
#endif
#include <iostream>
#include "dynamic-graph/debug.h"
#include "dynamic-graph/python/interpreter.hh"
std::ofstream dg_debugfile("/tmp/dynamic-graph-traces.txt", std::ios::trunc& std::ios::out);
std::ofstream dg_debugfile("/tmp/dynamic-graph-traces.txt",
std::ios::trunc& std::ios::out);
// Python initialization commands
namespace dynamicgraph {
namespace python {
static const std::string pythonPrefix[8] = {"from __future__ import print_function\n",
"import traceback\n",
"class StdoutCatcher:\n"
" def __init__(self):\n"
" self.data = ''\n"
" def write(self, stuff):\n"
" self.data = self.data + stuff\n"
" def fetch(self):\n"
" s = self.data[:]\n"
" self.data = ''\n"
" return s\n",
"stdout_catcher = StdoutCatcher()\n",
"stderr_catcher = StdoutCatcher()\n",
"import sys\n",
"sys.stdout = stdout_catcher",
"sys.stderr = stderr_catcher"};
static const std::string pythonPrefix[8] = {
"from __future__ import print_function\n",
"import traceback\n",
"class StdoutCatcher:\n"
" def __init__(self):\n"
" self.data = ''\n"
" def write(self, stuff):\n"
" self.data = self.data + stuff\n"
" def fetch(self):\n"
" s = self.data[:]\n"
" self.data = ''\n"
" return s\n",
"stdout_catcher = StdoutCatcher()\n",
"stderr_catcher = StdoutCatcher()\n",
"import sys\n",
"sys.stdout = stdout_catcher",
"sys.stderr = stderr_catcher"};
bool HandleErr(std::string& err, PyObject* globals_, int PythonInputType) {
dgDEBUGIN(15);
......@@ -41,7 +44,8 @@ bool HandleErr(std::string& err, PyObject* globals_, int PythonInputType) {
if (PyErr_Occurred() != NULL) {
bool is_syntax_error = PyErr_ExceptionMatches(PyExc_SyntaxError);
PyErr_Print();
PyObject* stderr_obj = PyRun_String("stderr_catcher.fetch()", Py_eval_input, globals_, globals_);
PyObject* stderr_obj = PyRun_String("stderr_catcher.fetch()", Py_eval_input,
globals_, globals_);
err = obj_to_str(stderr_obj);
Py_DECREF(stderr_obj);
......@@ -69,7 +73,9 @@ Interpreter::Interpreter() {
dlopen(PYTHON_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
#endif
Py_Initialize();
#if PY_MAJOR_VERSION < 3 || PY_MINOR_VERSION < 7
PyEval_InitThreads();
#endif
mainmod_ = PyImport_AddModule("__main__");
Py_INCREF(mainmod_);
globals_ = PyModule_GetDict(mainmod_);
......@@ -95,7 +101,8 @@ Interpreter::~Interpreter() {
// Ideally, we should call Py_Finalize but this is not really supported by
// Python.
// Instead, we merelly remove variables.
// Code was taken here: https://github.com/numpy/numpy/issues/8097#issuecomment-356683953
// Code was taken here:
// https://github.com/numpy/numpy/issues/8097#issuecomment-356683953
{
PyObject* poAttrList = PyObject_Dir(mainmod_);
PyObject* poAttrIter = PyObject_GetIter(poAttrList);
......@@ -105,11 +112,13 @@ Interpreter::~Interpreter() {
std::string oAttrName(obj_to_str(poAttrName));
// Make sure we don't delete any private objects.
if (oAttrName.compare(0, 2, "__") != 0 || oAttrName.compare(oAttrName.size() - 2, 2, "__") != 0) {
if (oAttrName.compare(0, 2, "__") != 0 ||
oAttrName.compare(oAttrName.size() - 2, 2, "__") != 0) {
PyObject* poAttr = PyObject_GetAttr(mainmod_, poAttrName);
// Make sure we don't delete any module objects.
if (poAttr && poAttr->ob_type != mainmod_->ob_type) PyObject_SetAttr(mainmod_, poAttrName, NULL);
if (poAttr && poAttr->ob_type != mainmod_->ob_type)
PyObject_SetAttr(mainmod_, poAttrName, NULL);
Py_DECREF(poAttr);
}
......@@ -132,7 +141,8 @@ std::string Interpreter::python(const std::string& command) {
return lres;
}
void Interpreter::python(const std::string& command, std::string& res, std::string& out, std::string& err) {
void Interpreter::python(const std::string& command, std::string& res,
std::string& out, std::string& err) {
res = "";
out = "";
err = "";
......@@ -147,18 +157,21 @@ void Interpreter::python(const std::string& command, std::string& res, std::stri
PyEval_RestoreThread(_pyState);
std::cout << command.c_str() << std::endl;
PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, globals_);
PyObject* result =
PyRun_String(command.c_str(), Py_eval_input, globals_, globals_);
// Check if the result is null.
if (result == NULL) {
// Test if this is a syntax error (due to the evaluation of an expression)
// else just output the problem.
if (!HandleErr(err, globals_, Py_eval_input)) {
// If this is a statement, re-parse the command.
result = PyRun_String(command.c_str(), Py_single_input, globals_, globals_);
result =
PyRun_String(command.c_str(), Py_single_input, globals_, globals_);
// If there is still an error build the appropriate err string.
if (result == NULL) HandleErr(err, globals_, Py_single_input);
// If there is no error, make sure that the previous error message is erased.
// If there is no error, make sure that the previous error message is
// erased.
else
err = "";
} else
......@@ -166,7 +179,8 @@ void Interpreter::python(const std::string& command, std::string& res, std::stri
}
PyObject* stdout_obj = 0;
stdout_obj = PyRun_String("stdout_catcher.fetch()", Py_eval_input, globals_, globals_);
stdout_obj =
PyRun_String("stdout_catcher.fetch()", Py_eval_input, globals_, globals_);
out = obj_to_str(stdout_obj);
Py_DECREF(stdout_obj);
// Local display for the robot (in debug mode or for the logs)
......@@ -207,7 +221,8 @@ void Interpreter::runPythonFile(std::string filename, std::string& err) {
PyEval_RestoreThread(_pyState);
err = "";
PyObject* run = PyRun_File(pFile, filename.c_str(), Py_file_input, globals_, globals_);
PyObject* run =
PyRun_File(pFile, filename.c_str(), Py_file_input, globals_, globals_);
if (run == NULL) {
HandleErr(err, globals_, Py_file_input);
std::cerr << err << std::endl;
......
# Copyright 2010-2020, Florent Lamiraux, Thomas Moulard, Olivier Stasse, Guilhem Saurel, JRL, CNRS/AIST, LAAS-CNRS
# Copyright 2010-2020, Florent Lamiraux, Thomas Moulard, Olivier Stasse, Guilhem
# Saurel, JRL, CNRS/AIST, LAAS-CNRS
# Test the interpreter
ADD_UNIT_TEST(interpreter-test interpreter-test.cc)
TARGET_LINK_LIBRARIES(interpreter-test PRIVATE ${PROJECT_NAME})
add_unit_test(interpreter-test interpreter-test.cc)
target_link_libraries(interpreter-test PRIVATE ${PROJECT_NAME})
# Test runfile
ADD_UNIT_TEST(interpreter-test-runfile interpreter-test-runfile.cc)
TARGET_LINK_LIBRARIES(interpreter-test-runfile PRIVATE ${PROJECT_NAME} Boost::unit_test_framework)
TARGET_COMPILE_DEFINITIONS(interpreter-test-runfile PRIVATE PATH="${CMAKE_CURRENT_LIST_DIR}/")
add_unit_test(interpreter-test-runfile interpreter-test-runfile.cc)
target_link_libraries(interpreter-test-runfile PRIVATE ${PROJECT_NAME})
target_include_directories(interpreter-test-runfile
PRIVATE Boost::unit_test_framework)
target_compile_definitions(interpreter-test-runfile
PRIVATE PATH="${CMAKE_CURRENT_LIST_DIR}/")
# Test the module generation
## Create an entity
# Test the module generation Create an entity
SET(LIBRARY_NAME "custom_entity")
ADD_LIBRARY(${LIBRARY_NAME} SHARED "${LIBRARY_NAME}.cpp")
IF(SUFFIX_SO_VERSION)
SET_TARGET_PROPERTIES(${LIBRARY_NAME}
PROPERTIES SOVERSION ${PROJECT_VERSION})
ENDIF(SUFFIX_SO_VERSION)
set(LIBRARY_NAME "custom_entity")
add_library(${LIBRARY_NAME} SHARED "${LIBRARY_NAME}.cpp")
if(SUFFIX_SO_VERSION)
set_target_properties(${LIBRARY_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION})
endif(SUFFIX_SO_VERSION)
target_link_libraries(${LIBRARY_NAME} PRIVATE dynamic-graph::dynamic-graph)
## Create its bindings
## This mimics DYNAMIC_GRAPH_PYTHON_MODULE(${LIBRARY_NAME} ${LIBRARY_NAME} "${LIBRARY_NAME}-wrap")
# Create its bindings This mimics DYNAMIC_GRAPH_PYTHON_MODULE(${LIBRARY_NAME}
# ${LIBRARY_NAME} "${LIBRARY_NAME}-wrap")
CONFIGURE_FILE(
${PROJECT_SOURCE_DIR}/cmake/dynamic_graph/submodule/__init__.py.cmake
${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}/__init__.py
)
SET(PYTHON_MODULE "${LIBRARY_NAME}-wrap")
set(DYNAMICGRAPH_MODULE_HEADER "${CMAKE_SOURCE_DIR}/tests/custom_entity_module.h")
configure_file(
${PROJECT_SOURCE_DIR}/cmake/dynamic_graph/python-module-py.cc.in
${CMAKE_CURRENT_BINARY_DIR}/python-module-py.cc
@ONLY
)
ADD_LIBRARY(${PYTHON_MODULE} MODULE ${CMAKE_CURRENT_BINARY_DIR}/python-module-py.cc)
SET_TARGET_PROPERTIES(${PYTHON_MODULE} PROPERTIES
PREFIX ""
OUTPUT_NAME ${LIBRARY_NAME}/wrap)
IF(UNIX AND NOT APPLE)
TARGET_LINK_LIBRARIES(${PYTHON_MODULE} PRIVATE "-Wl,--no-as-needed")
ENDIF(UNIX AND NOT APPLE)
TARGET_LINK_LIBRARIES(${PYTHON_MODULE} PRIVATE
${LIBRARY_NAME} dynamic-graph-python
${PYTHON_LIBRARY})
TARGET_LINK_BOOST_PYTHON(${PYTHON_MODULE} PRIVATE)
TARGET_INCLUDE_DIRECTORIES(${PYTHON_MODULE} SYSTEM PRIVATE ${PYTHON_INCLUDE_DIRS})
## Test it
ADD_PYTHON_UNIT_TEST("test-custom-entity" "tests/test_custom_entity.py" src tests)
${PROJECT_SOURCE_DIR}/cmake/dynamic_graph/submodule/__init__.py.cmake
${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}/__init__.py)
set(PYTHON_MODULE "${LIBRARY_NAME}-wrap")
set(DYNAMICGRAPH_MODULE_HEADER
"${CMAKE_SOURCE_DIR}/tests/custom_entity_module.h")
configure_file(${PROJECT_SOURCE_DIR}/cmake/dynamic_graph/python-module-py.cc.in
${CMAKE_CURRENT_BINARY_DIR}/python-module-py.cc @ONLY)
add_library(${PYTHON_MODULE} MODULE
${CMAKE_CURRENT_BINARY_DIR}/python-module-py.cc)
set_target_properties(${PYTHON_MODULE}
PROPERTIES PREFIX "" OUTPUT_NAME ${LIBRARY_NAME}/wrap)
if(UNIX AND NOT APPLE)
target_link_libraries(${PYTHON_MODULE} PRIVATE "-Wl,--no-as-needed")
endif(UNIX AND NOT APPLE)
target_link_libraries(${PYTHON_MODULE} PRIVATE ${LIBRARY_NAME} ${PROJECT_NAME})
# Test it
add_python_unit_test("test-custom-entity" "tests/test_custom_entity.py" src
tests)
# also test other bindings, using this custom entity
ADD_PYTHON_UNIT_TEST("test-bindings" "tests/test_bindings.py" src tests)
add_python_unit_test("test-bindings" "tests/test_bindings.py" src tests)
......@@ -16,12 +16,15 @@
#include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <boost/bind.hpp>
namespace dynamicgraph {
CustomEntity::CustomEntity(const std::string n)
: Entity(n),
m_sigdSIN(NULL, "CustomEntity(" + name + ")::input(double)::in_double"),
m_sigdTimeDepSOUT(boost::bind(&CustomEntity::update, this, _1, _2), m_sigdSIN,
m_sigdTimeDepSOUT(boost::bind(&CustomEntity::update, this, _1, _2),
m_sigdSIN,
"CustomEntity(" + name + ")::input(double)::out_double")
{
......@@ -29,10 +32,14 @@ CustomEntity::CustomEntity(const std::string n)
using namespace dynamicgraph::command;
this->addCommand("act", makeCommandVoid0(*this, &CustomEntity::act, docCommandVoid0("act on input signal")));
this->addCommand("act",
makeCommandVoid0(*this, &CustomEntity::act,
docCommandVoid0("act on input signal")));
}
void CustomEntity::addSignal() { signalRegistration(m_sigdSIN << m_sigdTimeDepSOUT); }
void CustomEntity::addSignal() {
signalRegistration(m_sigdSIN << m_sigdTimeDepSOUT);
}
void CustomEntity::rmValidSignal() {
signalDeregistration("in_double");
......@@ -43,14 +50,22 @@ double &CustomEntity::update(double &res, const int &inTime) {
const double &aDouble = m_sigdSIN(inTime);
res = aDouble;
logger().stream(MSG_TYPE_ERROR) << "start update " << res << '\n';
DYNAMIC_GRAPH_ENTITY_DEBUG(*this) << "This is a message of level MSG_TYPE_DEBUG\n";
DYNAMIC_GRAPH_ENTITY_INFO(*this) << "This is a message of level MSG_TYPE_INFO\n";
DYNAMIC_GRAPH_ENTITY_WARNING(*this) << "This is a message of level MSG_TYPE_WARNING\n";
DYNAMIC_GRAPH_ENTITY_ERROR(*this) << "This is a message of level MSG_TYPE_ERROR\n";
DYNAMIC_GRAPH_ENTITY_DEBUG_STREAM(*this) << "This is a message of level MSG_TYPE_DEBUG_STREAM\n";
DYNAMIC_GRAPH_ENTITY_INFO_STREAM(*this) << "This is a message of level MSG_TYPE_INFO_STREAM\n";
DYNAMIC_GRAPH_ENTITY_WARNING_STREAM(*this) << "This is a message of level MSG_TYPE_WARNING_STREAM\n";
DYNAMIC_GRAPH_ENTITY_ERROR_STREAM(*this) << "This is a message of level MSG_TYPE_ERROR_STREAM\n";
DYNAMIC_GRAPH_ENTITY_DEBUG(*this)
<< "This is a message of level MSG_TYPE_DEBUG\n";
DYNAMIC_GRAPH_ENTITY_INFO(*this)
<< "This is a message of level MSG_TYPE_INFO\n";
DYNAMIC_GRAPH_ENTITY_WARNING(*this)
<< "This is a message of level MSG_TYPE_WARNING\n";
DYNAMIC_GRAPH_ENTITY_ERROR(*this)
<< "This is a message of level MSG_TYPE_ERROR\n";
DYNAMIC_GRAPH_ENTITY_DEBUG_STREAM(*this)
<< "This is a message of level MSG_TYPE_DEBUG_STREAM\n";
DYNAMIC_GRAPH_ENTITY_INFO_STREAM(*this)
<< "This is a message of level MSG_TYPE_INFO_STREAM\n";
DYNAMIC_GRAPH_ENTITY_WARNING_STREAM(*this)
<< "This is a message of level MSG_TYPE_WARNING_STREAM\n";
DYNAMIC_GRAPH_ENTITY_ERROR_STREAM(*this)
<< "This is a message of level MSG_TYPE_ERROR_STREAM\n";
logger().stream(MSG_TYPE_ERROR) << "end update\n";
return res;
}
......
......@@ -5,11 +5,12 @@
#define ENABLE_RT_LOG
#include <sstream>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <sstream>
namespace dynamicgraph {
class CustomEntity : public Entity {
public:
......
......@@ -2,7 +2,10 @@
* Copyright
*/
#include <iostream>
#include "dynamic-graph-python-test.hh"
GraphTest::GraphTest() { std::cout << "Constructor of unitTesting object of class Graph." << std::endl; }
#include <iostream>
GraphTest::GraphTest() {
std::cout << "Constructor of unitTesting object of class Graph." << std::endl;
}
......@@ -2,7 +2,10 @@
* Copyright
*/
#include <iostream>
#include "dynamic-graph-python-test.hh"
GraphTest::GraphTest() { std::cout << "Constructor of unitTesting object of class Graph." << std::endl; }
#include <iostream>
GraphTest::GraphTest() {
std::cout << "Constructor of unitTesting object of class Graph." << std::endl;
}
// The purpose of this unit test is to check the interpreter::runPythonFile method
// The purpose of this unit test is to check the interpreter::runPythonFile
// method
#include <cstring>
#include <iostream>
#include "dynamic-graph/python/interpreter.hh"
bool testFile(const std::string& filename, const std::string& expectedOutput, int numTest) {
bool testFile(const std::string& filename, const std::string& expectedOutput,
int numTest) {
std::string err = "";
dynamicgraph::python::Interpreter interp;
for (int i = 0; i < numTest; ++i) {
interp.runPythonFile(filename, err);
if (err != expectedOutput) {
std::cerr << "At iteration " << i << ", the output was not the one expected:" << std::endl;
std::cerr << "At iteration " << i
<< ", the output was not the one expected:" << std::endl;
std::cerr << " expected: " << expectedOutput << std::endl;
std::cerr << " err: " << err << std::endl;
return false;
......@@ -19,7 +22,8 @@ bool testFile(const std::string& filename, const std::string& expectedOutput, in
return true;
}
bool testInterpreterDestructor(const std::string& filename, const std::string& expectedOutput) {
bool testInterpreterDestructor(const std::string& filename,
const std::string& expectedOutput) {
std::string err = "";
{
dynamicgraph::python::Interpreter interp;
......@@ -50,19 +54,26 @@ int main(int argc, char** argv) {
// because re as been imported in a previous test and it is not
// safe to delete imported module...
res = testFile(PATH "test_python-name_error.py",
std::string("Traceback (most recent call last):\n"
" File \"" PATH "test_python-name_error.py\", line 7, in <module>\n"
" pathList = re.split(':', pkgConfigPath) # noqa\n"
"NameError: name 're' is not defined\n"),
std::string(
"Traceback (most recent call last):\n"
" File \"" PATH
"test_python-name_error.py\", line 7, in <module>\n"
" pathList = re.split(\":\", pkgConfigPath) # noqa\n"
"NameError: name 're' is not defined\n"),
numTest) &&
res;
res = testFile(PATH "test_python-ok.py", "", numTest) && res;
res = testFile(PATH "unexistant_file.py", PATH "unexistant_file.py cannot be open", numTest) && res;
res = testFile(PATH "unexistant_file.py",
PATH "unexistant_file.py cannot be open", numTest) &&
res;
res = testFile(PATH "test_python-syntax_error.py",
std::string(" File \"" PATH "test_python-syntax_error.py\", line 2\n"
std::string(" File \"" PATH
"test_python-syntax_error.py\", line 2\n"
" hello world\n"
#if PY_MINOR_VERSION >= 8
#if PY_MINOR_VERSION >= 10
" ^^^^^\n"
#elif PY_MINOR_VERSION >= 8
" ^\n"
#else
" ^\n"
......@@ -70,6 +81,8 @@ int main(int argc, char** argv) {
"SyntaxError: invalid syntax\n"),
numTest) &&
res;
res = testInterpreterDestructor(PATH "test_python-restart_interpreter.py", "") && res;
res = testInterpreterDestructor(PATH "test_python-restart_interpreter.py",
"") &&
res;
return (res ? 0 : 1);
}
......@@ -3,10 +3,14 @@ import unittest
import dynamic_graph as dg
from custom_entity import CustomEntity
ERR = """Python argument types in
ERR = (
"""Python argument types in
dynamic_graph.wrap.plug(%s, %s)
did not match C++ signature:
plug(dynamicgraph::SignalBase<int>* signalOut, dynamicgraph::SignalBase<int>* signalIn)"""
plug("""
"dynamicgraph::SignalBase<int>* signalOut, "
"dynamicgraph::SignalBase<int>* signalIn)"
)
class BindingsTests(unittest.TestCase):
......@@ -14,38 +18,44 @@ class BindingsTests(unittest.TestCase):
"""
test the type checking in signal plugs
"""
first = CustomEntity('first_entity')
second = CustomEntity('second_entity')
first = CustomEntity("first_entity")
second = CustomEntity("second_entity")
# Check that we can connect first.out to second.in
dg.plug(first.signal('out_double'), second.signal('in_double'))
dg.plug(first.signal("out_double"), second.signal("in_double"))
# Check that we can't connect first.out to second
with self.assertRaises(TypeError) as cm_in:
dg.plug(first.signal('out_double'), second)
self.assertEqual(str(cm_in.exception), ERR % ("SignalTimeDependentDouble", "CustomEntity"))
dg.plug(first.signal("out_double"), second)
self.assertEqual(
str(cm_in.exception), ERR % ("SignalTimeDependentDouble", "CustomEntity")
)
# Check that we can't connect first to second.in
with self.assertRaises(TypeError) as cm_out:
dg.plug(first, second.signal('in_double'))
self.assertEqual(str(cm_out.exception), ERR % ("CustomEntity", "SignalPtrDouble"))
dg.plug(first, second.signal("in_double"))
self.assertEqual(
str(cm_out.exception), ERR % ("CustomEntity", "SignalPtrDouble")
)
def test_dg_exc(self):
"""
test that exceptions from dynamic graph are correctly raised
"""
ent = CustomEntity('test_dg_exc')
ent = CustomEntity("test_dg_exc")
# check that accessing a non initialized signal raises
with self.assertRaises(RuntimeError) as cm:
ent.act()
self.assertEqual(
str(cm.exception),
'In SignalPtr: SIN ptr not set. (in signal <CustomEntity(test_dg_exc)::input(double)::in_double>)')
"In SignalPtr: SIN ptr not set. "
"(in signal <CustomEntity(test_dg_exc)::input(double)::in_double>)",
)
# check that accessing an initialized signal doesn't raise
ent_2 = CustomEntity('another_entity')
dg.plug(ent_2.signal('out_double'), ent.signal('in_double'))
ent_2 = CustomEntity("another_entity")
dg.plug(ent_2.signal("out_double"), ent.signal("in_double"))
ent.act()
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()
......@@ -5,8 +5,13 @@ import os
import time
from custom_entity import CustomEntity
from dynamic_graph import (addLoggerCoutOutputStream, addLoggerFileOutputStream, closeLoggerFileOutputStream,
real_time_logger_destroy, real_time_logger_spin_once)
from dynamic_graph import (
addLoggerCoutOutputStream,
addLoggerFileOutputStream,
closeLoggerFileOutputStream,
real_time_logger_destroy,
real_time_logger_spin_once,
)
from dynamic_graph.entity import VerbosityLevel
print(os.getcwd())
......
......@@ -3,7 +3,7 @@ import os
pkgConfigPath = os.environ.get("PKG_CONFIG_PATH")
if pkgConfigPath is None:
pkgConfigPath = ''
pathList = re.split(':', pkgConfigPath) # noqa
pkgConfigPath = ""
pathList = re.split(":", pkgConfigPath) # noqa
print(pathList)
......@@ -3,7 +3,7 @@ import re
pkgConfigPath = os.environ.get("PKG_CONFIG_PATH")
if pkgConfigPath is None:
pkgConfigPath = ''
pathList = re.split(':', pkgConfigPath)
pkgConfigPath = ""
pathList = re.split(":", pkgConfigPath)
print(pathList)
......@@ -3,6 +3,6 @@ import numpy # noqa
# Make sure the variable is deleted.
if "var" in locals() or "var" in globals():
raise ValueError('Not cleaned')
raise ValueError("Not cleaned")
var = "This string should have been deleted."
#!/bin/bash
. `dirname $0`/common.sh
# Set debug mode
set -x
set -v
# build_package
# -------------
#
# Build the package using the last Eigen release (3.2) which is not
# available as a Debian package on Ubuntu 12.04.
build_package()
{
echo "--> Building package..."
cd "$build_dir"
if [[ ";${DO_COVERAGE_ON_BRANCH};" == *";${CI_BRANCH};"* ]]; then
cmake "$root_dir" -DCMAKE_INSTALL_PREFIX="$install_dir" \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_EXE_LINKER_FLAGS="--coverage" \
-DCMAKE_MODULE_LINKER_FLAGS="--coverage" \
${CMAKE_ADDITIONAL_OPTIONS}
else
cmake "$root_dir" -DCMAKE_INSTALL_PREFIX="$install_dir" \
${CMAKE_ADDITIONAL_OPTIONS}
fi
${MAKE_PREFIX} make
make install
ALLOW_TESTSUITE_FAILURE=${ALLOW_TESTSUITE_FAILURE:-false}
make test || ${ALLOW_TESTSUITE_FAILURE}
if [[ ";${DO_CPPCHECK_ON_BRANCH};" == *";${CI_BRANCH};"* ]]; then
cppcheck --quiet --enable=all \
-I $root_dir/src -I $root_dir/tests -I $root_dir/include \
-I $root_dir/tests/shared-tests \
-I $build_dir/include -I $install_dir/include \
-i $build_dir/CMakeFiles \
$root_dir || true
fi
}
# debian_build_package
# --------------------
#
# Use git-buildpackage and pbuilder to build the package in a sid
# sandbox.
debian_build_package()
{
export GNUPGHOME="$root_dir/.travis/.gnupg"
export NAME="Thomas Moulard (Travis Automatic Builds)"
export DEBEMAIL="thomas.moulard+travis@gmail.com"
echo "--> Building Debian package..."
cd "$root_dir"
buildNumber=$(git rev-list \
$(git describe --tags --match "debian/*" --abbrev=0)..HEAD | wc -l) \
|| buildNumber=1
dch --force-distribution --distribution ${DIST} \
--local ppa$buildNumber+$DIST "Travis automatic build"
echo "debian/changelog first line:"
head -n 1 debian/changelog
git add debian/changelog
git commit -m "Travis automatic commit"
${SUDO_CMD} chmod -R 777 /var/cache/pbuilder/ccache
# If orig tarball exists, delete it.
rm -f "$build_dir/export/*_*.orig.tar*"
git-buildpackage \
--git-submodules \
--git-no-pristine-tar \
--git-ignore-branch \
--git-debian-branch=HEAD \
--git-export-dir="$build_dir/export" \
--git-tag \
--git-upstream-branch=master \
--git-dist=${DIST} \
--git-pbuilder \
--git-force-create \
--git-ignore-new \
--git-retag \
-p\"gpg\\ --passphrase\\ ${GNUPG_PASSPHRASE}\" \
-k${DEBSIGN_KEYID} || exit 1
git-buildpackage \
--git-submodules \
--git-no-pristine-tar \
--git-debian-branch=HEAD \
--git-ignore-branch \
--git-export-dir="$build_dir/export" \
--git-tag \
--git-upstream-branch=master \
--git-dist=${DIST} \
--git-ignore-new \
--git-retag \
-p\"gpg --passphrase ${GNUPG_PASSPHRASE}\" \
-k${DEBSIGN_KEYID} \
-S -sa || exit 1
}
# setup_ros_build_environment
# ---------------------------
#
# Source ROS setup scripts if they exist
setup_ros_build_environment()
{
if [ -e /opt/ros/${ROS_DISTRO}/setup.sh ]; then
. /opt/ros/${ROS_DISTRO}/setup.sh
fi
CATKIN_DEP_WORKSPACE=/tmp/_ci/catkin_dep_ws
if [ -e ${CATKIN_DEP_WORKSPACE}/devel/setup.sh ]; then
. ${CATKIN_DEP_WORKSPACE}/devel/setup.sh
fi
# Limit the number of parallel jobs when running catkin_make
PARALLEL_JOBS=${PARALLEL_JOBS:-1}
export ROS_PARALLEL_JOBS="-j ${PARALLEL_JOBS}"
}
# build_catkin_package
# --------------------
#
# build all the packages using catkin_make.
# Also check the installation (catkin_make install)
# and check whether the catkin package is well written (catkin_lint)
build_catkin_package()
{
# Main package workspace
CATKIN_WORKSPACE=$build_dir/..
ln -s $root_dir/.. $CATKIN_WORKSPACE/src
cd $CATKIN_WORKSPACE/src
catkin_init_workspace
cd $CATKIN_WORKSPACE
catkin_make
for pack in `ls -d ./src/*/ ./src/*/*/`; do
if test -f $pack/package.xml; then
rosdoc_lite $pack
fi
done
catkin_make install
# run catkin_lint on every directory.
ALLOW_CATKINLINT_FAILURE=${ALLOW_CATKINLINT_FAILURE:-false}
catkin_lint `ls -d ./src/*/ ./src/*/*/` || ${ALLOW_CATKINLINT_FAILURE}
}
setup_ros_build_environment
# Realize a normal build in all branches except the one containing a
# debian/ folder.
if [ -d debian ]; then
if `test x${DIST} = x`; then
echo "distribution is not set, skipping this build"
exit 0
fi
echo "Target distribution: ${DIST}"
debian_build_package
else
if [ ! x${DIST} = x ]; then
echo "skipping this build"
exit 0
fi
# checking if it is a ros folder. Taking appropriate measure.
#The current repository is a package
build_package
fi
# End debug mode
set +v
set +x
#!/bin/bash
rm -rf "$build_dir" "$install_dir"
. `dirname $0`/common.sh
# Set debug mode
set -x
set -v
# Add robotpkg
sudo sh -c "echo \"deb [arch=amd64] http://robotpkg.openrobots.org/wip/packages/debian/pub $(lsb_release -cs) robotpkg\" >> /etc/apt/sources.list "
sudo sh -c "echo \"deb [arch=amd64] http://robotpkg.openrobots.org/packages/debian/pub $(lsb_release -cs) robotpkg\" >> /etc/apt/sources.list "
curl http://robotpkg.openrobots.org/packages/debian/robotpkg.key | sudo apt-key add -
# show memory usage before install
sudo free -m -t
# Setup environment variables.
export APT_DEPENDENCIES="doxygen libboost-system-dev libboost-test-dev libboost-filesystem-dev libboost-program-options-dev libeigen3-dev libtinyxml-dev libconsole-bridge-dev robotpkg-dynamic-graph-v3 robotpkg-py27-dynamic-graph-v3"
# Add Python dependency
export APT_DEPENDENCIES=$APT_DEPENDENCIES" libboost-python-dev robotpkg-py27-eigenpy python2.7-dev python-numpy"
# Add Geometry dependencies
if [[ $BUILD_WITH_COLLISION_SUPPORT -eq ON ]]; then
export APT_DEPENDENCIES=$APT_DEPENDENCIES" robotpkg-hpp-fcl"
fi
##############################
# -- Helper functions -- #
##############################
_linux_setup_package_source()
{
# Speed up apt
${SUDO_CMD} sh -c "echo \"force-unsafe-io\" > /etc/dpkg/dpkg.cfg.d/02apt-speedup"
# Update the apt local cache.
${SUDO_CMD} apt-get update -qq
}
_osx_setup_package_source()
{
# Update homebrew
brew update
}
# setup_package_source
# ---------------------
#
# Setup the package source (e.g. homebrew on osx, apt on debian-like systems)
setup_package_source()
{
if [[ ${CI_OS_NAME} = linux ]]; then
_linux_setup_package_source
fi
if [[ ${CI_OS_NAME} = osx ]]; then
_osx_setup_package_source
fi
}
# setup_pbuilder
# --------------
#
# Setup a pbuilder environment
setup_pbuilder()
{
if `test x${DIST} = x`; then
echo "distribution is not set, skipping this build"
exit 0
fi
echo "Target distribution: ${DIST}"
# If we are, we install Debian package development tools and
# create a sid pbuilder. Package dependencies will be installed
# automatically.
${SUDO_CMD} apt-get install -qq \
debootstrap devscripts \
git-buildpackage debian-archive-keyring \
pkg-kde-tools dput eatmydata ccache
# Fix ccache use in pbuilder
${SUDO_CMD} addgroup --system --gid 1234 ccache
${SUDO_CMD} adduser --quiet --system --uid 1234 --ingroup ccache \
--home /var/cache/pbuilder --no-create-home pbuilder
${SUDO_CMD} mkdir -p /var/cache/pbuilder/ccache
${SUDO_CMD} chown -R pbuilder:ccache /var/cache/pbuilder/ccache
${SUDO_CMD} chmod -R g+ws /var/cache/pbuilder/ccache
# Remove previous sandbox.
${SUDO_CMD} rm -rf /var/cache/pbuilder/base-${DIST}.cow || true
# Create a pbuilder sandbox.
cp -f `dirname $0`/pbuilderrc $HOME/.pbuilderrc
sed -i "s|@DIST@|${DIST}|g" $HOME/.pbuilderrc
git-pbuilder create
# Speed up pbuilder.
echo "echo \"force-unsafe-io\" > /etc/dpkg/dpkg.cfg.d/02apt-speedup" | \
git-pbuilder login --save-after-exec
# Add additional PPAs
for ppa in ${DEBIAN_PPA}; do
echo "apt-add-repository ppa:${ppa}" | \
git-pbuilder login --save-after-exec
done
# Retrieve PPA package list.
git-pbuilder update
# FIXME There is something fishy here...
# ccache is not necessary in our case and may cause permission
# issues.
echo "apt-get -y remove ccache" | \
git-pbuilder login --save-after-exec
}
# catkin_git_dependency
# --------------------
#
# Clone catkin package into the workspace
# See arguments of build_git_dependency
# Branch defaults to $ROS_DISTRO instead of master
catkin_git_dependency()
{
git_dependency_parsing $1 $ROS_DISTRO
echo "--> Getting $git_dep (branch $git_dep_branch)"
CATKIN_DEP_WORKSPACE=/tmp/_ci/catkin_dep_ws
cd $CATKIN_DEP_WORKSPACE/src
$git_clone -b $git_dep_branch "$git_dep_uri" "$git_dep"
}
# catkin_build_workspace
# ----------------------
#
# Build catkin workspace
catkin_build_workspace()
{
CATKIN_DEP_WORKSPACE=/tmp/_ci/catkin_dep_ws
cd $CATKIN_DEP_WORKSPACE
catkin_make
}
# build_git_dependency
# --------------------
#
# Build a dependency directly from the Git development tree.
# First argument: repository's GitHub URL or repository's URI + optional branch
# For example: "jrl-umi3218/jrl-travis" or "jrl-umi3218/jrl-travis#dev"
# Or: user@host:path/to/repo or git@github.com:organization/repo#branch
build_git_dependency()
{
git_dependency_parsing $1
echo "--> Compiling $git_dep (branch $git_dep_branch)"
cd "$build_dir"
mkdir -p "$git_dep"
$git_clone -b $git_dep_branch "$git_dep_uri" "$git_dep"
cd "$git_dep"
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX:STRING="$install_dir" \
-DDISABLE_TESTS:BOOL=ON ${CMAKE_ADDITIONAL_OPTIONS}
make install || make
}
_osx_install_dependencies()
{
# Install user-specified packages
brew install cppcheck ${HOMEBREW_DEPENDENCIES}
}
_linux_install_dependencies()
{
# Add additional PPAs
for ppa in ${MASTER_PPA}; do
${SUDO_CMD} add-apt-repository -y ppa:${ppa}
done
${SUDO_CMD} apt-get update -qq
${SUDO_CMD} apt-get install -qq curl cppcheck ${APT_DEPENDENCIES}
# Install lcov from github
cd "$build_dir"
wget https://github.com/linux-test-project/lcov/releases/download/v1.12/lcov-1.12.tar.gz
tar zxvf lcov-1.12.tar.gz
cd lcov-1.12
# Reset lcov to release 1.12
${SUDO_CMD} make install
gem install coveralls-lcov
}
install_dependencies()
{
if [[ ${CI_OS_NAME} = linux ]]; then
_linux_install_dependencies
fi
if [[ ${CI_OS_NAME} = osx ]]; then
_osx_install_dependencies
fi
# and we build directly dependencies from the Git repository
for package in ${ROS_GIT_DEPENDENCIES}; do
catkin_git_dependency "$package"
done
if `test "x${ROS_GIT_DEPENDENCIES}" != x`; then
catkin_build_workspace
fi
for package in ${GIT_DEPENDENCIES}; do
build_git_dependency "$package"
done
}
#########################
# -- Main script -- #
#########################
# Print Git version
git --version
# Setup Git identity.
git config --global user.name "JRL/IDH Continuous Integration Tool"
git config --global user.email "jrl-idh+ci@gmail.com"
# Retrieve the submodules.
git submodule update --quiet --init --recursive
# Fetch tags to compute the distance between the last release tag
# and us.
git fetch --quiet --tags
# Shortcuts.
git_clone="git clone --quiet --recursive"
# Display environment
echo "Environment:"
env
setup_package_source
# Check if we are in a debian branch...
if [ -d debian ]; then
setup_pbuilder
else
if [ ! x${DIST} = x ]; then
echo "skipping this build"
exit 0
fi
install_dependencies
fi
# End debug mode
set +v
set +x