Skip to content

Commit

Permalink
Merge pull request #2 from asmodehn/install_rules
Browse files Browse the repository at this point in the history
Install rules
  • Loading branch information
asmodehn committed Apr 3, 2016
2 parents a3acf1b + 6f9b629 commit 13864cf
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 139 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build
test/mypippkg
.idea
133 changes: 133 additions & 0 deletions cmake/catkin-pip-setup.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#
# This script is in charge of doing the pip setup in a workspace.
# It will be configured by cmake and dropped in devel or install workspace
# where is will setup a workspace emulation of virtualenvs
#

message(STATUS "Loading ${CMAKE_CURRENT_LIST_FILE}... ")

# Make sure the pip target directory for the workspace is in python path
# this is only needed if the user didn't source the current workspace setup.bash (happens the first time)
string(FIND $ENV{PYTHONPATH} @CONFIGURE_PREFIX@/${CATKIN_GLOBAL_PYTHON_DESTINATION} FOUND_PPATH)
if ( FOUND_PPATH LESS 0 )
set(ENV{PYTHONPATH} "@CONFIGURE_PREFIX@/${CATKIN_GLOBAL_PYTHON_DESTINATION}:$ENV{PYTHONPATH}")
endif()

# Make sure the bin target directory for the workspace is in system path
# this is only needed if the user didn't source the current workspace setup.bash (happens the first time)
string(FIND $ENV{PATH} @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@ FOUND_SPATH)
if ( FOUND_SPATH LESS 0 )
set(ENV{PATH} "@CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@:$ENV{PATH}")
endif()

message(STATUS "Catkin pip PYTHONPATH : $ENV{PYTHONPATH}")
message(STATUS "Catkin pip PATH : $ENV{PATH}")

# Note : this is obviously not changing anything in the shell environment where cmake was started from.
# And WE DO NOT WANT to do it there. The user controls his bash environment independently of what runs in it.


# Note : we need to install our fixups as normal requirements

macro(catkin_pip_requirements_prefix requirements_txt )
message(STATUS " ... Retrieving Pip requirements ${requirements_txt} into @CONFIGURE_PREFIX@...")

execute_process(
COMMAND ${CATKIN_PIP} install -r ${requirements_txt} --ignore-installed --prefix "@CONFIGURE_PREFIX@" --install-option "--install-layout=deb"
WORKING_DIRECTORY @CMAKE_CURRENT_SOURCE_DIR@
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE
ERROR_VARIABLE PIP_ERROR
)

message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}")
if (PIP_RESULT)
message(STATUS "Command ${CATKIN_PIP} install -r ${requirements_txt} --ignore-installed --prefix \"@CONFIGURE_PREFIX@\" --install-option \"--install-layout=deb\" FAILED")
message(FATAL_ERROR "${PIP_ERROR}")
endif()
endmacro()

macro(catkin_pip_package_prefix package_path)
string(REPLACE ";" " " PIP_PACKAGE_INSTALL_CMDSTR "@PIP_PACKAGE_INSTALL_COMMAND@")
message(STATUS " ... Running ${PIP_PACKAGE_INSTALL_CMDSTR} ...")

execute_process(
COMMAND @PIP_PACKAGE_INSTALL_COMMAND@
WORKING_DIRECTORY @CMAKE_CURRENT_SOURCE_DIR@
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE
ERROR_VARIABLE PIP_ERROR
)

message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}")
if (PIP_RESULT)
message(STATUS "Command ${PIP_PACKAGE_INSTALL_CMDSTR} FAILED !")
message(FATAL_ERROR "${PIP_ERROR}")
endif()
endmacro()


# Trying to find our own pip
# Careful this creates a CACHE variable
find_program(CATKIN_PIP NAMES pip pip2 pip2.7 PATHS @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@ NO_DEFAULT_PATH)

if (CATKIN_PIP)
message(STATUS " ... Catkin pip was found at ${CATKIN_PIP} ...")
else ()
# If not found, it means we need to do the whole setup...
unset(CATKIN_PIP CACHE)
message(STATUS " ... Catkin pip was not found in @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@ ...")
# Assuming Ubuntu Trusty here. platform detection is another hurdle
set(CMAKE_SYSTEM_PREFIX_PATH / /usr /usr/local)
find_program(CATKIN_SYS_PIP NAMES pip pip2 pip2.7 NO_SYSTEM_ENVIRONMENT_PATH) # we need to make sure we dont find any other catkin-pip from somewhere else if our path is not clean (careful with underlays)
if(NOT CATKIN_SYS_PIP)
message( FATAL_ERROR "pip system command not found. Make sure you have installed the python-pip package on your system.")
endif()

message(STATUS " ... Retrieving catkin_pure_python requirements using system pip ...")

file(MAKE_DIRECTORY @CONFIGURE_PREFIX@/${CATKIN_GLOBAL_PYTHON_DESTINATION})

# We need to find a pip command that works for old pip versions (indigo supports trusty which is pip v1.5.4)
# Note --target here means we cannot check if a package is already installed or not before installing, using old pip.
# which means we have to reinstall dependencies everytime and specify --exists-action w to avoid "already exists" errors
# Avoid --install-option since the setuptools version found will be different the first time and the following times
execute_process(
COMMAND ${CATKIN_SYS_PIP} install -r "@CATKIN_PIP_REQUIREMENTS_PATH@/catkin-pip-base.req" --download-cache "${CMAKE_BINARY_DIR}/pip-cache" --target "@CONFIGURE_PREFIX@/${CATKIN_GLOBAL_PYTHON_DESTINATION}" --exists-action w
WORKING_DIRECTORY @CMAKE_CURRENT_SOURCE_DIR@
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE
ERROR_VARIABLE PIP_ERROR
)

message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}")
if (PIP_RESULT)
message(STATUS "Command ${CATKIN_SYS_PIP} install -r \"@CATKIN_PIP_REQUIREMENTS_PATH@/catkin-pip-base.req\" --download-cache \"${CMAKE_BINARY_DIR}/pip-cache\" --target \"@CONFIGURE_PREFIX@/${CATKIN_GLOBAL_PYTHON_DESTINATION}\" --exists-action w FAILED")
message(FATAL_ERROR "${PIP_ERROR}")
endif()

set(CATKIN_PIP python -m pip) # to make sure we use our recently downloaded pip version (its entrypoints were not installed by old pip/setuptools)
unset(CATKIN_SYS_PIP CACHE) # we dont need this any longer

# Fixing security since python 2.7.6 on trusty is broken : https://stackoverflow.com/questions/29099404/ssl-insecureplatform-error-when-using-requests-package
catkin_pip_requirements_prefix("@CATKIN_PIP_REQUIREMENTS_PATH@/catkin-pip-fixups.req")

unset(CATKIN_PIP)
# now we can finally use the simple "pip" entry_point (forcing cmake to find it)
find_program( CATKIN_PIP NAMES pip pip2 pip2.7 PATHS @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@ NO_DEFAULT_PATH)
if (CATKIN_PIP)
message( STATUS "Found catkin_pure_python pip command at ${CATKIN_PIP}.")
else()
message( FATAL_ERROR "catkin_pure_python pip command not found in @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@. Make sure you have installed the pip pip package on @CONFIGURE_PREFIX@ workspace.")
endif()

# Providing another catkin nosetests usage...
# now we can finally use the simple "nosetests" entry_point (forcing cmake to find it)
find_program( PIP_NOSETESTS NAMES nosetests PATHS @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@ NO_DEFAULT_PATH)
if(PIP_NOSETESTS)
message( STATUS "Found catkin_pure_python nosetests command at ${PIP_NOSETESTS}.")
else()
message( FATAL_ERROR "catkin_pure_python nosetests command not found in @CONFIGURE_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@. Make sure you have installed the nose pip package on your @CONFIGURE_PREFIX@ workspace.")
endif()

endif()
156 changes: 19 additions & 137 deletions cmake/catkin-pip.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,129 +4,28 @@ if ( NOT CATKIN_PIP_REQUIREMENTS_PATH )
set (CATKIN_PIP_REQUIREMENTS_PATH ${CMAKE_CURRENT_LIST_DIR})
endif()

# Make sure the pip target directory for devel workspace is in python path
# this is only needed if the user didn't source the current workspace devel setup.bash (happens the first time)
string(FIND $ENV{PYTHONPATH} ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION} FOUND_DEVEL_PPATH)
if ( FOUND_DEVEL_PPATH LESS 0 )
set(ENV{PYTHONPATH} "${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}:$ENV{PYTHONPATH}")
endif()

# Make sure the bin target directory for devel is in system path
# this is only needed if the user didn't source the current workspace devel setup.bash (happens the first time)
string(FIND $ENV{PATH} ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} FOUND_DEVEL_SPATH)
if ( FOUND_DEVEL_SPATH LESS 0 )
set(ENV{PATH} "${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}:$ENV{PATH}")
endif()
# Since we need (almost) the same configuration for both devel and install space, we create cmake files for each workspace setup.
set(CONFIGURE_PREFIX ${CATKIN_DEVEL_PREFIX})
set(PIP_PACKAGE_INSTALL_COMMAND \${CATKIN_PIP} install -e \${package_path} --install-option "--install-dir=${CONFIGURE_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}" --install-option "--script-dir=${CONFIGURE_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}")
configure_file(${CMAKE_CURRENT_LIST_DIR}/catkin-pip-setup.cmake.in ${CONFIGURE_PREFIX}/.catkin-pip-setup.cmake @ONLY)

# Note : this is obviously not changing anything in the shell environment where cmake was started from.
# And WE DO NOT WANT to do it there. The user controls his bash environment independently of what runs in it.
set(CONFIGURE_PREFIX ${CMAKE_INSTALL_PREFIX})
set(PIP_PACKAGE_INSTALL_COMMAND \${CATKIN_PIP} install \${package_path} --prefix "${CONFIGURE_PREFIX}" --install-option "--install-layout=deb")
configure_file(${CMAKE_CURRENT_LIST_DIR}/catkin-pip-setup.cmake.in ${CONFIGURE_PREFIX}/.catkin-pip-setup.cmake @ONLY)

# Defining this macro early since we use it here on include time
macro(catkin_pip_requirements requirements_txt)
unset(CONFIGURE_PREFIX)
unset(PIP_PACKAGE_INSTALL_COMMAND)

message(STATUS " ... Retrieving Pip requirements ${requirements_txt}...")
# And here we need to do the devel workspace setup.
include(${CATKIN_DEVEL_PREFIX}/.catkin-pip-setup.cmake)

execute_process(
COMMAND ${CATKIN_PIP} install -r ${requirements_txt} --ignore-installed --prefix "${CATKIN_DEVEL_PREFIX}" --install-option "--install-layout=deb"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE
ERROR_VARIABLE PIP_ERROR
)

message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}")
if (PIP_RESULT)
message(STATUS "Command ${CATKIN_PIP} install -r ${requirements_txt} --ignore-installed --prefix \"${CATKIN_DEVEL_PREFIX}\" --install-option \"--install-layout=deb\" FAILED")
message(FATAL_ERROR "${PIP_ERROR}")
endif()
macro(catkin_pip_requirements requirements_txt )

# Setting up the command for install space
install(CODE "
message(STATUS \" ... Installing Pip requirements ...\")
execute_process(
COMMAND ${CATKIN_PIP} install -r ${requirements_txt} --ignore-installed --prefix \"${CATKIN_DEVEL_PREFIX}\" --install-option \"--install-layout=deb\"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE)
message(STATUS \" ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}\")
")
catkin_pip_requirements_prefix(${requirements_txt})

endmacro()


# Trying to find our own pip
# Careful this creates a CACHE variable
find_program(CATKIN_PIP NAMES pip PATHS ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION})

# Make sure we find the right one
# message(STATUS " ... FINDING ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} in ${CATKIN_PIP} ...")
string(FIND ${CATKIN_PIP} ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} FOUND_CATKIN_PIP)
# message(STATUS " ... RESULT ${FOUND_CATKIN_PIP} ...")

if (NOT FOUND_CATKIN_PIP LESS 0)
message(STATUS " ... Catkin pip was found at ${CATKIN_PIP} ...")
else ()
# If not found, it means we need to do the whole setup...
unset(CATKIN_PIP CACHE)
message(STATUS " ... Catkin pip was not found in devel workspace ...")
find_program(CATKIN_SYS_PIP NAMES pip)
if(NOT CATKIN_SYS_PIP)
message( FATAL_ERROR "pip system command not found. Make sure you have installed the python-pip package on your system.")
endif()

message(STATUS " ... Retrieving catkin_pure_python requirements using system pip ...")

file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION})

# We need to find a pip command that works for old pip versions (indigo supports trusty which is pip v1.5.4)
# Note --target here means we cannot check if a package is already installed or not before installing, using old pip.
# which means we have to reinstall dependencies everytime and specify --exists-action w to avoid "already exists" errors
# Avoid --install-option since the setuptools version found will be different the first time and the following times
execute_process(
COMMAND ${CATKIN_SYS_PIP} install -r "${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-base.req" --download-cache "${CMAKE_BINARY_DIR}/pip-cache" --target "${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}" --exists-action w
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE
ERROR_VARIABLE PIP_ERROR
)

message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}")
if (PIP_RESULT)
message(STATUS "Command ${CATKIN_SYS_PIP} install -r \"${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-base.req\" --download-cache \"${CMAKE_BINARY_DIR}/pip-cache\" --target \"${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}\" --exists-action w FAILED")
message(FATAL_ERROR "${PIP_ERROR}")
endif()

# Setting up the command for install space is not needed here. It will be done by the fixups from our catkin pip.

set(CATKIN_PIP python -m pip) # to make sure we use our recently downloaded pip version (its entrypoints were not installed by old pip/setuptools)
unset(CATKIN_SYS_PIP CACHE) # we dont need this any longer

# Fixing security since python 2.7.6 on trusty is broken : https://stackoverflow.com/questions/29099404/ssl-insecureplatform-error-when-using-requests-package
catkin_pip_requirements("${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-fixups.req")

unset(CATKIN_PIP)
# now we can finally use the simple "pip" entry_point (forcing cmake to find it)
find_program( CATKIN_PIP NAMES pip PATHS ${CMAKE_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION})
string(FIND ${CATKIN_PIP} ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} FOUND_CATKIN_PIP)

if (CATKIN_PIP AND NOT FOUND_CATKIN_PIP LESS 0)
message( STATUS "Found catkin_pure_python pip command at ${CATKIN_PIP}.")
else()
message( FATAL_ERROR "catkin_pure_python pip command not found in ${CMAKE_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}. Make sure you have installed the pip pip package on your devel workspace.")
endif()

# Providing another catkin nosetests usage...
# now we can finally use the simple "pip" entry_point (forcing cmake to find it)
find_program( PIP_NOSETESTS NAMES nosetests PATHS ${CMAKE_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION})
string(FIND ${PIP_NOSETESTS} ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} FOUND_CATKIN_PIP_NOSETESTS)
if(PIP_NOSETESTS AND NOT FOUND_CATKIN_PIP_NOSETESTS LESS 0)
message( STATUS "Found catkin_pure_python nosetests command at ${PIP_NOSETESTS}.")
else()
message( FATAL_ERROR "catkin_pure_python nosetests command not found in ${CMAKE_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}. Make sure you have installed the nose pip package on your devel workspace.")
endif()

endif()

macro(catkin_pip_package)

set (extra_macro_args ${ARGN})
Expand All @@ -135,35 +34,18 @@ macro(catkin_pip_package)
list(LENGTH extra_macro_args num_extra_args)
if (${num_extra_args} GREATER 0)
list(GET extra_macro_args 0 package_path)
message ("Got package_path: ${package_path}")
#message ("Got package_path: ${package_path}")
else()
set(package_path .)
endif()
message(STATUS " ... Configuring ${package_path} as a Pip package ...")

execute_process(
COMMAND ${CATKIN_PIP} install -e ${package_path} --install-option "--install-dir=${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}" --install-option "--script-dir=${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE
ERROR_VARIABLE PIP_ERROR
)

message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}")
if (PIP_RESULT)
message(STATUS "Command ${CATKIN_PIP} install -e ${package_path} --install-option \"--install-dir=${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}\" --install-option \"--script-dir=${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}\" FAILED")
message(FATAL_ERROR "${PIP_ERROR}")
endif()
catkin_pip_package_prefix(${package_path})

# Setting up the command for install space
# Setting up the command for install space for user convenience
install(CODE "
message(STATUS \" ... Installing as a Pip package ...\")
execute_process(
COMMAND ${CATKIN_PIP} install ${package_path} --install-option \"--install-dir=${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}\" --install-option \"--script-dir=${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION}\"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE PIP_RESULT
OUTPUT_VARIABLE PIP_VARIABLE)
message(STATUS \" ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}\")
#Setting paths for install by including our configured install cmake file
include(${CMAKE_INSTALL_PREFIX}/.catkin-pip-setup.cmake)
catkin_pip_package_prefix(${package_path})
")
endmacro()

Expand Down
4 changes: 2 additions & 2 deletions test/mypippkg.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.3)
project(mypippkg)

# This is a full project CMakeLists (in case we call it independently for tests or so)
set (PIP_PROJECT_DIR mypippkg)
set (PIP_PROJECT_DIR ./mypippkg)

find_package(catkin REQUIRED)
# Include our own extension from source (to be sure)
Expand All @@ -12,7 +12,7 @@ include(../cmake/catkin-pip.cmake)

# We need to install the pip dependencies in the workspace being created
catkin_pip_requirements(${PIP_PROJECT_DIR}/requirements.txt)
# CAREFUL : all projects here share the same workspace. pip might have conflicts...
# CAREFUL : all projects for test here will share the same workspace. pip might have conflicts...

# defining current package as a package that should be managed by pip (not catkin - even though we make it usable with workspaces)
catkin_pip_package(${PIP_PROJECT_DIR})
Expand Down

0 comments on commit 13864cf

Please sign in to comment.