Commit 77f26815 authored by Manuel Günther's avatar Manuel Günther
Browse files

First working version of FindBob.cmake and its test case; works only with...

First working version of FindBob.cmake and its test case; works only with latest versions of bob.extension, bob.io.base and bob.io.image
parents
*~
*.swp
*.pyc
*.so
*.dylib
bin
eggs
parts
.installed.cfg
.mr.developer.cfg
*.egg-info
develop-eggs
sphinx
dist
.nfs*
.gdb_history
build
test.hdf5
*.egg
src/
language: python
env:
global:
- secure: F8PfOJ9nGrtZdTcv132jrx5spnzFfpFCSMtea4TLwvotbFc7/gHVEu2UeLktWuVVnL715MSbJ8aXAFR918qwwJsCop0fnPNtgC70nLbYUNWvyOSzvm6JwXA9cYHvAgxYA4Y1folXcz+0bIQqD0MkBM/1yiLivS1kHP3K2jrdWNk=
- secure: YAMap+9kNi9om5b4h1leawWrpgkvt1iIv3UVkfp0zTSM9kb1qVjJxWd75IxjbVSGXQ5hoMAgyOzCwOFoa4r3LMf8bBtStZ4zeoaichxEQHr05C5BXgHFDWUnFdpInvODMbfznySdxiLLWQ6kJFldmdFwYizJxcKxSWqL4EQ3Snw=
- BOB_UPLOAD_WHEEL=1
matrix:
include:
- python: 2.7
env:
- BOB_DOCUMENTATION_SERVER=https://www.idiap.ch/software/bob/docs/latest/bioidiap/%s/master
- python: 3.3
- python: 3.4
- python: 3.5
before_install:
- sudo add-apt-repository -y ppa:biometrics/bob
- sudo apt-get update -qq
- sudo apt-get install -qq --force-yes libboost-all-dev libblitz1-dev libjpeg8-dev libpng12-dev libtiff4-dev libgif-dev libhdf5-serial-dev libatlas-dev libatlas-base-dev liblapack-dev texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended
- pip install --upgrade pip
- pip install --find-links https://www.idiap.ch/software/bob/wheels/travis/ --use-wheel sphinx nose coverage cpp-coveralls
- pip install --find-links https://www.idiap.ch/software/bob/wheels/travis/ --use-wheel bob.extension bob.blitz --pre coveralls
install:
- python bootstrap-buildout.py
- CPPFLAGS=--coverage LDFLAGS=--coverage ./bin/buildout buildout:debug=false
- mkdir build
- cd build
- cmake ..
- make
- cd ..
script:
- ./build/my_test
cmake_minimum_required(VERSION 2.8)
project(test)
# Set the module path so that "FindBob.cmake" is found
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
# Find all Bob packages recursively
find_package(Bob COMPONENTS bob.io.image REQUIRED)
# Add Bob's include directories
include_directories(${Bob_INCLUDE_DIRS})
# Add Bob's library directories
link_directories(${Bob_LIBRARY_DIRS})
# Add Bob's libraries
link_libraries(${Bob_LIBRARIES} boost_system)
# Add Bob's definitions
add_definitions(${Bob_DEFINITIONS})
# create an "my_test" executable from file "test.cpp"
add_executable(my_test test.cpp)
macro(_convert_package_to_string package)
string(REPLACE "." "_" PACKAGE_LIB "${package}")
string(REPLACE "." "/" PACKAGE_DIR "${package}")
string(TOUPPER "${PACKAGE_LIB}" PACKAGE)
endmacro()
macro(_find_python)
if (NOT _python)
set(_possible_paths ${CMAKE_SOURCE_DIR}/bin)
if (BOB_PREFIX_PATH)
list(APPEND _possible_paths ${BOB_PREFIX_PATH}/bin)
endif()
if (ENV{BOB_PREFIX_PATH})
list(APPEND _possible_paths $ENV{BOB_PREFIX_PATH}/bin)
endif()
find_program(_python python HINTS ${_possible_paths})
endif()
endmacro()
macro(_get_external_includes package)
_find_python()
execute_process(COMMAND ${_python} -c "exec(\"import ${package},sys\\nif hasattr(${package}, 'get_include_directories'): sys.stdout.write(';'.join(${package}.get_include_directories()))\")" OUTPUT_VARIABLE _external_includes)
endmacro()
macro(_get_external_macros package)
_find_python()
execute_process(COMMAND ${_python} -c "exec(\"import ${package},sys\\nif hasattr(${package}, 'get_macros'): sys.stdout.write(';'.join('-D%s=%s' % m for m in ${package}.get_macros()))\")" OUTPUT_VARIABLE _external_macros)
endmacro()
macro(_recurse_requirements requirements)
# recurses through the requirements and get all bob packages
file(STRINGS ${requirements} _reqs)
# message(STATUS "Read requirements from '${requirements}' to '${_reqs}'")
#TODO: check requirements recursively
foreach (_req IN LISTS _reqs)
# check if string starts with bob
string(FIND ${_req} bob _pos)
if (NOT ${_pos} EQUAL -1)
# message(STATUS "Searching recursively for required Bob package ${_req}")
find_bob_package(${_req})
endif()
endforeach()
endmacro()
# Function to find a specific Bob package;
# This function will search for Bob packages in several directories
# If found, it will add include directories -- and library directories and libraries if applicable
function(find_bob_package package)
# get the uppercase package name in ${PACKAGE}
# the package directory in ${PACKAGE_DIR}
# and the possible lib name in ${PACKAGE_LIB}
_convert_package_to_string(${package})
if (${PACKAGE}_FOUND)
return()
endif()
# message(STATUS "\n")
message(STATUS "Searching for Bob package '${package}'")
# define possible path
set(_possible_paths
${CMAKE_SOURCE_DIR}/src/${package}
)
# .. egg directory
file(GLOB _egg_dir ${CMAKE_SOURCE_DIR}/eggs/${package}*.egg)
if (_egg_dir)
list(APPEND _possible_paths ${_egg_dir})
endif()
# .. BOB_PREFIX_PATH
if (BOB_PREFIX_PATH)
list(APPEND _possible_paths ${BOB_PREFIX_PATH}/lib/*/site-packages)
endif()
if (ENV{BOB_PREFIX_PATH})
list(APPEND _possible_paths $ENV{BOB_PREFIX_PATH}/lib/*/site-packages)
endif()
# message(STATUS "Possible paths are '${_possible_paths}'")
# add common path to locations
set(_bob_paths)
foreach(_path IN LISTS _possible_paths)
list(APPEND _bob_paths ${_path}/${PACKAGE_DIR})
endforeach()
# message(STATUS "Bob paths are '${_bob_paths}'")
# check if we find any bob directory
find_path(_package_dir
NAMES __init__.py
HINTS ${_bob_paths}
)
# message(STATUS "Package dir is '${_package_dir}'")
if (NOT _package_dir)
if (Bob_FIND_REQUIRED)
message(FATAL_ERROR "Could not find bob package '${package}'")
endif()
set(${PACKAGE} ${PACKAGE}-NOTFOUND PARENT_SCOPE)
return()
endif()
set(${PACKAGE}_FOUND TRUE PARENT_SCOPE)
# first, parse the requirements
# TODO: get the requirements file;
# * either from the requirements.txt inside the ${_package_dir - ${PACKAGE_DIR}}
# * or from the requires.txt inside ${_package_dir - ${PACKAGE_DIR}}/${package}*.egg-info
string(FIND ${_package_dir} /${PACKAGE_DIR} _pos)
string(SUBSTRING ${_package_dir} 0 ${_pos} _base_dir)
file(GLOB _egg_info_dir ${_base_dir}/${package}*.egg-info ${_base_dir}/EGG-INFO)
find_file(
_requirements
NAMES requires.txt
HINTS ${_egg_info_dir}
NO_CMAKE_PATH
)
if (_requirements)
set(_r ${_requirements})
unset(_requirements CACHE)
set(_p ${_package_dir})
unset(_package_dir CACHE)
_recurse_requirements(${_r})
set(_package_dir ${_p} CACHE STRING INTERNAL)
endif()
# find include directories
find_path(_include_dir
NAMES include
HINTS ${_package_dir}
)
# message(STATUS "Include dir is '${_include_dir}/include'")
# check if we have found an include directory
if (_include_dir)
list(APPEND Bob_INCLUDE_DIRS ${_include_dir}/include)
set(Bob_INCLUDE_DIRS ${Bob_INCLUDE_DIRS} PARENT_SCOPE)
endif()
# find external dependencies
_get_external_includes(${package})
# message(STATUS "External includes are '${_external_includes}'")
if (_external_includes)
list(APPEND Bob_INCLUDE_DIRS ${_external_includes})
set(Bob_INCLUDE_DIRS ${Bob_INCLUDE_DIRS} PARENT_SCOPE)
endif()
_get_external_macros(${package})
# message(STATUS "External macros are '${_external_macros}'")
if (_external_includes)
list(APPEND Bob_DEFINITIONS ${_external_macros})
set(Bob_DEFINITIONS ${Bob_DEFINITIONS} PARENT_SCOPE)
endif()
# find library
find_library(_library
NAMES ${PACKAGE_LIB}
HINTS ${_package_dir}
)
# message(STATUS "Library is '${_library}'")
# check if we have found a library
if (_library)
set(Bob_LIBRARY_DIRS ${Bob_LIBRARY_DIRS} ${_package_dir} PARENT_SCOPE)
set(Bob_LIBRARIES ${Bob_LIBRARIES} ${PACKAGE_LIB} PARENT_SCOPE)
endif()
# clean up so that the next package is acually searched and not skipped
unset(_package_dir CACHE)
unset(_include_dir CACHE)
unset(_library CACHE)
endfunction()
# HERE the main FIND_BOB starts
# get the list of components
if (NOT Bob_FIND_COMPONENTS)
message(FATAL_ERROR "Please specify the bob packages that you want to search for as COMPONENTS")
endif()
set(CMAKE_CXX_FLAGS "-std=c++0x -pthread" CACHE STRING "Flags used by the compiler during release builds" FORCE)
foreach (package IN LISTS Bob_FIND_COMPONENTS)
find_bob_package(${package})
endforeach()
message(STATUS "Found Bob include directories '${Bob_INCLUDE_DIRS}'")
message(STATUS "Found Bob library directories '${Bob_LIBRARY_DIRS}'")
message(STATUS "Found Bob libraries '${Bob_LIBRARIES}'")
message(STATUS "Found Bob definitions '${Bob_DEFINITIONS}'")
.. vim: set fileencoding=utf-8 :
.. Manuel Gunther <siebenkopf@googlemail.com>
.. Thu 30 Jan 08:46:53 2014 CET
.. image:: http://img.shields.io/badge/docs-stable-yellow.png
:target: http://pythonhosted.org/bob.example.cmake/index.html
.. image:: http://img.shields.io/badge/docs-latest-orange.png
:target: https://www.idiap.ch/software/bob/docs/latest/bioidiap/bob.example.cmake/master/index.html
.. image:: http://travis-ci.org/bioidiap/bob.example.cmake.svg?branch=master
:target: https://travis-ci.org/bioidiap/bob.example.cmake?branch=master
.. image:: https://coveralls.io/repos/bioidiap/bob.example.cmake/badge.png?branch=master
:target: https://coveralls.io/r/bioidiap/bob.example.cmake?branch=master
.. image:: https://img.shields.io/badge/github-master-0000c0.png
:target: https://github.com/bioidiap/bob.example.cmake/tree/master
.. image:: http://img.shields.io/pypi/v/bob.example.cmake.png
:target: https://pypi.python.org/pypi/bob.example.cmake
.. image:: http://img.shields.io/pypi/dm/bob.example.cmake.png
:target: https://pypi.python.org/pypi/bob.example.cmake
===========================================
Example project using Bob's C++ interface
===========================================
This example project shows a way to incorporate Bob's C++ libraries into a C++ project.
For this, is uses the CMake_ interface, and a home-developed ``FindBob.cmake`` file.
It relies on the python interface to download and install Bob_.
More information about the Bob installation can be found on its `webpage <bob>`_.
Building this example
---------------------
As the exmaple requires some Bob_ packages to be installed, we first run one of the ways to install Bob_, i.e., using `buildout <https://github.com/idiap/bob/wiki/Installation#using-zcbuildout-for-production>`_.
For that, simply go to the main directory of this package and call::
$ python bootstrap-buildout.py
$ ./bin/buildout
This will checkout some of the packages to the ``src`` directory, and download some into the ``eggs`` directory.
If you have Bob installed globally, it will use the globally installed packages instead of downloading new eggs.
If you have Bob installed in a non-default directory, for example in an `virtual environment <https://github.com/idiap/bob/wiki/Installation#using-pip-for-experts>`_, you can use that python version to bootstrap.
Inside of this package I have prepared a small CMake_ project that includes some of the Bob_ packages.
It uses the ``FindBob.cmake`` to locate Bob's include directories and libraries.
To enable that, you can use the ``find_package(Bob COMPONENTS <package(s)> REQUIRED)`` command to find the list of bob ``package(s)``.
Later, you can use three CMake_ variables ``Bob_INCLUDE_DIRS``, ``Bob_LIBRARY_DIRS``, ``Bob_LIBRARIES`` and ``Bob_DEFINITIONS`` and add it to your project::
cmake_minimum_required(VERSION 2.8)
project(test)
# Tell CMake, where to find the "FindBob.cmake" file
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
# Find Bobs packages and its dependencies
find_package(Bob COMPONENTS bob.io.image REQUIRED)
# add information to your project
include_directories(${Bob_INCLUDE_DIRS})
link_directories(${Bob_LIBRARY_DIRS})
add_definitions(${Bob_DEFINITIONS})
link_libraries(${Bob_LIBRARIES} boost_system)
# link an executable
add_executable(my_test test.cpp)
For some reason (that I do not understand) we also need to add the ``boost_system`` library, although it shoud theoretically be linked to the Bob_ libraries already.
So, now we can go ahead and compile our package using CMake_::
$ mkdir build
$ cd build
$ cmake ..
$ make
and we should get an executable ``my_test`` inside the build directory.
Note that you can pass a variable to CMake to use a custom Bob_ installation::
$ cmake -DBOB_PREFIX_PATH=/path/to/your/bob/installation
or set the ``BOB_PREFIX_PATH`` environment variable accordingly.
To run the example, go back to the package base directory (otherwise it will not find the example image) and call::
$ ./build/my_test
This should create an HDF5 file called ``test.hdf5`` inside the current directory.
.. _cmake: http://cmake.org
.. _bob: http://www.idiap.ch/software/bob
##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
"""
import os
import shutil
import sys
import tempfile
from optparse import OptionParser
tmpeggs = tempfile.mkdtemp()
usage = '''\
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
Bootstraps a buildout-based project.
Simply run this script in a directory containing a buildout.cfg, using the
Python that you want bin/buildout to use.
Note that by using --find-links to point to local resources, you can keep
this script from going over the network.
'''
parser = OptionParser(usage=usage)
parser.add_option("-v", "--version", help="use a specific zc.buildout version")
parser.add_option("-t", "--accept-buildout-test-releases",
dest='accept_buildout_test_releases',
action="store_true", default=False,
help=("Normally, if you do not specify a --version, the "
"bootstrap script and buildout gets the newest "
"*final* versions of zc.buildout and its recipes and "
"extensions for you. If you use this flag, "
"bootstrap and buildout will get the newest releases "
"even if they are alphas or betas."))
parser.add_option("-c", "--config-file",
help=("Specify the path to the buildout configuration "
"file to be used."))
parser.add_option("-f", "--find-links",
help=("Specify a URL to search for buildout releases"))
parser.add_option("--allow-site-packages",
action="store_true", default=False,
help=("Let bootstrap.py use existing site packages"))
parser.add_option("--setuptools-version",
help="use a specific setuptools version")
options, args = parser.parse_args()
######################################################################
# load/install setuptools
try:
if options.allow_site_packages:
import setuptools
import pkg_resources
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
ez = {}
exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
if not options.allow_site_packages:
# ez_setup imports site, which adds site packages
# this will remove them from the path to ensure that incompatible versions
# of setuptools are not in the path
import site
# inside a virtualenv, there is no 'getsitepackages'.
# We can't remove these reliably
if hasattr(site, 'getsitepackages'):
for sitepackage_path in site.getsitepackages():
sys.path[:] = [x for x in sys.path if sitepackage_path not in x]
setup_args = dict(to_dir=tmpeggs, download_delay=0)
if options.setuptools_version is not None:
setup_args['version'] = options.setuptools_version
ez['use_setuptools'](**setup_args)
import setuptools
import pkg_resources
# This does not (always?) update the default working set. We will
# do it.
for path in sys.path:
if path not in pkg_resources.working_set.entries:
pkg_resources.working_set.add_entry(path)
######################################################################
# Install buildout
ws = pkg_resources.working_set
cmd = [sys.executable, '-c',
'from setuptools.command.easy_install import main; main()',
'-mZqNxd', tmpeggs]
find_links = os.environ.get(
'bootstrap-testing-find-links',
options.find_links or
('http://downloads.buildout.org/'
if options.accept_buildout_test_releases else None)
)
if find_links:
cmd.extend(['-f', find_links])
setuptools_path = ws.find(
pkg_resources.Requirement.parse('setuptools')).location
requirement = 'zc.buildout'
version = options.version
if version is None and not options.accept_buildout_test_releases:
# Figure out the most recent final version of zc.buildout.
import setuptools.package_index
_final_parts = '*final-', '*final'
def _final_version(parsed_version):
try:
return not parsed_version.is_prerelease
except AttributeError:
# Older setuptools
for part in parsed_version:
if (part[:1] == '*') and (part not in _final_parts):
return False
return True
index = setuptools.package_index.PackageIndex(
search_path=[setuptools_path])
if find_links:
index.add_find_links((find_links,))
req = pkg_resources.Requirement.parse(requirement)
if index.obtain(req) is not None:
best = []
bestv = None
for dist in index[req.project_name]:
distv = dist.parsed_version
if _final_version(distv):
if bestv is None or distv > bestv:
best = [dist]
bestv = distv
elif distv == bestv:
best.append(dist)
if best:
best.sort()
version = best[-1].version
if version:
requirement = '=='.join((requirement, version))
cmd.append(requirement)
import subprocess
if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0:
raise Exception(
"Failed to execute command:\n%s" % repr(cmd)[1:-1])
######################################################################
# Import and run buildout
ws.add_entry(tmpeggs)
ws.require(requirement)
import zc.buildout.buildout
if not [a for a in args if '=' not in a]:
args.append('bootstrap')
# if -c was provided, we push it back into args for buildout' main function
if options.config_file is not None:
args[0:0] = ['-c', options.config_file]
zc.buildout.buildout.main(args)
shutil.rmtree(tmpeggs)
; vim: set fileencoding=utf-8 :
; Manuel Guenther <siebenkopf@googlemail.com>
; Tue May 24 15:24:11 MDT 2016
[buildout]
parts = scripts
eggs = bob.io.image
extensions = bob.buildout
mr.developer
auto-checkout = *
develop = src/bob.extension
src/bob.io.base
src/bob.io.image
; options for bob.buildout
debug = true
verbose = true
newest = false
[sources]
bob.extension = git https://github.com/bioidiap/bob.extension.git
bob.io.base = git https://github.com/bioidiap/bob.io.base.git
bob.io.image = git https://github.com/bioidiap/bob.io.image.git
[scripts]
recipe = bob.buildout:scripts
dependent-scripts = true
#include <bob.extension/documentation.h>
#include <bob.io.base/HDF5File.h>
#include <bob.io.image/png.h>
#include <iostream>
int main(int argc, const char** argv){
blitz::Array<uint8_t, 3> image = bob::io::image::read_png<uint8_t,3>("test.png");
bob::io::base::HDF5File h("test.hdf5", 'w');
h.setArray("Test", image);
std::cout << "Successfully converted test.png into test.hdf5" << std::endl;
}
test.png

507 KB

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment