Skip to content

Commit

Permalink
Fix CMake build of pycaffe
Browse files Browse the repository at this point in the history
- generate right shared library name
- fix CMake linking with the new layer factory
- find numpy

Fix finding protobuf.
  • Loading branch information
BlGene committed Oct 8, 2014
1 parent 0ba046b commit b9c1eec
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 6 deletions.
103 changes: 103 additions & 0 deletions CMakeScripts/FindNumPy.cmake
@@ -0,0 +1,103 @@
# - Find the NumPy libraries
# This module finds if NumPy is installed, and sets the following variables
# indicating where it is.
#
# TODO: Update to provide the libraries and paths for linking npymath lib.
#
# NUMPY_FOUND - was NumPy found
# NUMPY_VERSION - the version of NumPy found as a string
# NUMPY_VERSION_MAJOR - the major version number of NumPy
# NUMPY_VERSION_MINOR - the minor version number of NumPy
# NUMPY_VERSION_PATCH - the patch version number of NumPy
# NUMPY_VERSION_DECIMAL - e.g. version 1.6.1 is 10601
# NUMPY_INCLUDE_DIRS - path to the NumPy include files

#============================================================================
# Copyright 2012 Continuum Analytics, Inc.
#
# MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
#============================================================================

# Finding NumPy involves calling the Python interpreter
if(NumPy_FIND_REQUIRED)
find_package(PythonInterp REQUIRED)
else()
find_package(PythonInterp)
endif()

if(NOT PYTHONINTERP_FOUND)
set(NUMPY_FOUND FALSE)
return()
endif()

execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
"import numpy as n; print(n.__version__); print(n.get_include());"
RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS
OUTPUT_VARIABLE _NUMPY_VALUES_OUTPUT
ERROR_VARIABLE _NUMPY_ERROR_VALUE
OUTPUT_STRIP_TRAILING_WHITESPACE)

if(NOT _NUMPY_SEARCH_SUCCESS MATCHES 0)
if(NumPy_FIND_REQUIRED)
message(FATAL_ERROR
"NumPy import failure:\n${_NUMPY_ERROR_VALUE}")
endif()
set(NUMPY_FOUND FALSE)
return()
endif()

# Convert the process output into a list
string(REGEX REPLACE ";" "\\\\;" _NUMPY_VALUES ${_NUMPY_VALUES_OUTPUT})
string(REGEX REPLACE "\n" ";" _NUMPY_VALUES ${_NUMPY_VALUES})
# Just in case there is unexpected output from the Python command.
list(GET _NUMPY_VALUES -2 NUMPY_VERSION)
list(GET _NUMPY_VALUES -1 NUMPY_INCLUDE_DIRS)

string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" _VER_CHECK "${NUMPY_VERSION}")
if("${_VER_CHECK}" STREQUAL "")
# The output from Python was unexpected. Raise an error always
# here, because we found NumPy, but it appears to be corrupted somehow.
message(FATAL_ERROR
"Requested version and include path from NumPy, got instead:\n${_NUMPY_VALUES_OUTPUT}\n")
return()
endif()

# Make sure all directory separators are '/'
string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIRS})

# Get the major and minor version numbers
string(REGEX REPLACE "\\." ";" _NUMPY_VERSION_LIST ${NUMPY_VERSION})
list(GET _NUMPY_VERSION_LIST 0 NUMPY_VERSION_MAJOR)
list(GET _NUMPY_VERSION_LIST 1 NUMPY_VERSION_MINOR)
list(GET _NUMPY_VERSION_LIST 2 NUMPY_VERSION_PATCH)
string(REGEX MATCH "[0-9]*" NUMPY_VERSION_PATCH ${NUMPY_VERSION_PATCH})
math(EXPR NUMPY_VERSION_DECIMAL
"(${NUMPY_VERSION_MAJOR} * 10000) + (${NUMPY_VERSION_MINOR} * 100) + ${NUMPY_VERSION_PATCH}")

find_package_message(NUMPY
"Found NumPy: version \"${NUMPY_VERSION}\" ${NUMPY_INCLUDE_DIRS}"
"${NUMPY_INCLUDE_DIRS}${NUMPY_VERSION}")

set(NUMPY_FOUND TRUE)


152 changes: 152 additions & 0 deletions CMakeScripts/FindProtobuf.cmake
@@ -0,0 +1,152 @@
# Locate and configure the Google Protocol Buffers library.
# Defines the following variables:
#
# PROTOBUF_FOUND - Found the Google Protocol Buffers library
# PROTOBUF_INCLUDE_DIRS - Include directories for Google Protocol Buffers
# PROTOBUF_LIBRARIES - The protobuf library
#
# The following cache variables are also defined:
# PROTOBUF_LIBRARY - The protobuf library
# PROTOBUF_PROTOC_LIBRARY - The protoc library
# PROTOBUF_INCLUDE_DIR - The include directory for protocol buffers
# PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler
#
# ====================================================================
# Example:
#
# find_package(Protobuf REQUIRED)
# include_directories(${PROTOBUF_INCLUDE_DIRS})
#
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
# PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto)
# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
# target_link_libraries(bar ${PROTOBUF_LIBRARY})
#
# NOTE: You may need to link against pthreads, depending
# on the platform.
# ====================================================================
#
# PROTOBUF_GENERATE_CPP (public function)
# SRCS = Variable to define with autogenerated
# source files
# HDRS = Variable to define with autogenerated
# header files
# ARGN = proto files
#
# ====================================================================


#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009 Philip Lowman <philip@yhbt.com>
# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)

function(PROTOBUF_GENERATE_PYTHON SRCS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
return()
endif(NOT ARGN)

set(${SRCS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)


list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")

add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --python_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}
${ABS_FIL}
DEPENDS ${ABS_FIL}
COMMENT "Running Python protocol buffer compiler on ${FIL}"
VERBATIM )
endforeach()


set_source_files_properties(${${SRCS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
endfunction()


function(PROTOBUF_GENERATE_CPP SRCS HDRS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif(NOT ARGN)

set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)

list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")

add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}
${ABS_FIL}
DEPENDS ${ABS_FIL}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM )
endforeach()

set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()


find_path(PROTOBUF_INCLUDE_DIR google/protobuf/service.h)

# Google's provided vcproj files generate libraries with a "lib"
# prefix on Windows
if(WIN32)
set(PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
endif()

find_library(PROTOBUF_LIBRARY NAMES protobuf
DOC "The Google Protocol Buffers Library"
)
find_library(PROTOBUF_PROTOC_LIBRARY NAMES protoc
DOC "The Google Protocol Buffers Compiler Library"
)
find_program(PROTOBUF_PROTOC_EXECUTABLE NAMES protoc
DOC "The Google Protocol Buffers Compiler"
)

mark_as_advanced(PROTOBUF_INCLUDE_DIR
PROTOBUF_LIBRARY
PROTOBUF_PROTOC_LIBRARY
PROTOBUF_PROTOC_EXECUTABLE)

# Restore original find library prefixes
if(WIN32)
set(CMAKE_FIND_LIBRARY_PREFIXES "${PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES}")
endif()

include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROTOBUF DEFAULT_MSG
PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR)

if(PROTOBUF_FOUND)
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
endif()
48 changes: 43 additions & 5 deletions python/CMakeLists.txt
@@ -1,20 +1,58 @@
project( Python )

# Python
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
find_package(PythonLibs 2.7 REQUIRED)

# Numpy
find_package(NumPy REQUIRED)

# Boost.Python
find_package(Boost 1.46 COMPONENTS python REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})



#In case you have both python2 and python3 installed the quickest way to
#compile pycaffe with cmake is to replace the following hardcoded paths.
#Althernativley the Find* scripts could be rewritten to support choice of
#of python version.
#if(${PYTHONLIBS_VERSION_STRING} MATCHES "^[3-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
#
# set( PYTHON_INCLUDE_DIRS "/usr/include/python2.7")
# set( PYTHON_LIBRARIES "/usr/lib64/libpython2.7.so")
# set( NUMPY_INCLUDE_DIRS "/usr/lib64/python2.7/site-packages/numpy/core/include/")
# set( PYTHON_LIBRARIES "/usr/lib64/python2.7/site-packages/numpy/lib/")
# set(Boost_LIBRARIES "/usr/lib64/libboost_python-2.7-mt.so")
#
# message( "Warning: cmake found python3 by default, switching to hardcoded paths")
#
# message( "PYTHON_INCLUDE_DIRS =/usr/include/python2.7")
# message( "PYTHON_LIBRARIES =/usr/lib64/libpython2.7.so")
# message( "NUMPY_INCLUDE_DIRS =/usr/lib64/python2.7/site-packages/numpy/core/include/")
# message( "PYTHON_LIBRARIES =/usr/lib64/python2.7/site-packages/numpy/lib/")
# message( "Boost_LIBRARIES =/usr/lib64/libboost_python-2.7-mt.so")
#endif()


include_directories(${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS})

file(GLOB_RECURSE Python_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

add_library(pycaffe SHARED ${Python_SOURCES})
target_link_libraries(pycaffe caffe ${PYTHON_LIBRARIES} ${Boost_LIBRARIES})

### Install #################################################################################
add_dependencies(pycaffe protoPy)

target_link_libraries(pycaffe ${CAFFE_STATIC_LINK} ${PYTHON_LIBRARIES} ${Boost_LIBRARIES})

set_target_properties(pycaffe PROPERTIES PREFIX "")
set_target_properties(pycaffe PROPERTIES OUTPUT_NAME "_caffe")

### Install #############################################################

install(DIRECTORY caffe DESTINATION python)
install(FILES requirements.txt DESTINATION python)

#This installs a library named "libpycaffe.so"
install(TARGETS pycaffe DESTINATION python/caffe)


11 changes: 10 additions & 1 deletion src/caffe/proto/CMakeLists.txt
Expand Up @@ -14,11 +14,15 @@ endif()
include_directories(${PROTOBUF_INCLUDE_DIR})
file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
PROTOBUF_GENERATE_PYTHON(ProtoSourcesPy ${ProtoFiles})

add_custom_target(protoPy DEPENDS ${ProtoSourcesPy})

add_library(proto
${ProtoSources}
${ProtoHeaders}
)
)


target_link_libraries(proto ${PROTOBUF_LIBRARIES})

Expand All @@ -35,3 +39,8 @@ foreach(header ${ProtoHeaders})
)

endforeach(header)

file(WRITE __init__.py)
install(PROGRAMS __init__.py DESTINATION python/caffe/proto)
install(PROGRAMS ${ProtoSourcesPy} DESTINATION python/caffe/proto)

0 comments on commit b9c1eec

Please sign in to comment.