FindBoostPython.cmake 5.05 KB
Newer Older
1
2
3
# - Try to find the a valid boost+python combination
# Once done this will define
#
4
5
6
#  BoostPython_FOUND - system has a valid boost+python combination
#  BoostPython_INCLUDE_DIRS - the include directory for boost+python
#  BoostPython_LIBRARIES - the needed libs for boost+python
7

8
# SPDX-FileCopyrightText: 2006 Pino Toscano <toscano.pino@tiscali.it>
9
# SPDX-License-Identifier: BSD-3-Clause
10

11
if(BoostPython_INCLUDE_DIRS AND BoostPython_LIBRARIES)
12
    # Already in cache, be silent
13
14
	set(BoostPython_FIND_QUIETLY TRUE)
endif(BoostPython_INCLUDE_DIRS AND BoostPython_LIBRARIES)
15
16

include(CheckIncludeFileCXX)
17
18
include(CMakePushCheckState)
include(FindPackageHandleStandardArgs)
19

20
21
22
23
24
25
26
27
28
29
30
# Set varname to true if we found good combination of Boost and Python.
# NOTE: varname should be different each time, or test won't run.
# Also, varname is printed as test name, so it should not be too cryptic.
macro(BoostPython_TRY_COMPILE varname)
  check_cxx_source_compiles("
#include <boost/python.hpp>
const char* greet() { return \"Hello world!\"; }
BOOST_PYTHON_MODULE(hello) { boost::python::def(\"greet\", greet); }
int main() { return 0; }
" ${varname} )
endmacro(BoostPython_TRY_COMPILE)
31

32
find_package(Boost QUIET COMPONENTS python3)
33
34
35
36
37
38
39
if(NOT Boost_PYTHON3_FOUND)
  find_package(Boost QUIET COMPONENTS python)
  if(Boost_PYTHON_FOUND)
    set(Boost_PYTHON3_LIBRARY ${Boost_PYTHON_LIBRARY})
    set(Boost_PYTHON3_FOUND TRUE)
  endif(Boost_PYTHON_FOUND)
endif(NOT Boost_PYTHON3_FOUND)
40

41
42
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES  ${CMAKE_REQUIRED_INCLUDES}  ${Boost_INCLUDE_DIRS})
43
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${Boost_PYTHON3_LIBRARY})
44
45
46

check_include_file_cxx(boost/shared_ptr.hpp HAVE_BOOST_SHARED_PTR_HPP)

47
48
49
50
51
# This variable is not checked/used when user provide both
# BoostPython_INCLUDE_DIRS and BoostPython_LIBRARIES, by design.
# If user wants to speed up configure stage, he's allowed to do this.
# If user wants to shoot himself in the foot, he is allowed to do this, too.
set(BoostPython_COMPILES)
52

53
54
# If shared_ptr.hpp or Python library is not available, then there is
# no point to do anything.
55
if(HAVE_BOOST_SHARED_PTR_HPP AND Boost_PYTHON3_FOUND)
56
57
  if(NOT BoostPython_INCLUDE_DIRS OR NOT BoostPython_LIBRARIES)
    # First try: check if CMake Python is suitable.
58
59
    set(Python_ADDITIONAL_VERSIONS "3.9;3.8;3.7;3.6;3.5")
    find_package(PythonLibs 3 QUIET)
60
61
62
63
64
65
66
67
68
69
70
    if(PYTHONLIBS_FOUND)
      cmake_push_check_state()
      set(CMAKE_REQUIRED_INCLUDES  ${CMAKE_REQUIRED_INCLUDES}  ${PYTHON_INCLUDE_DIRS})
      set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${PYTHON_LIBRARIES})
      BoostPython_TRY_COMPILE(BoostPython_FromCMake)
      cmake_pop_check_state()

      if(BoostPython_FromCMake)
        set(BoostPython_COMPILES Yes)
        set(BoostPython_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
            CACHE INTERNAL "Includes search path for Boost+Python")
71
        set(BoostPython_LIBRARIES    ${PYTHON_LIBRARIES}    ${Boost_PYTHON3_LIBRARY}
72
73
74
75
76
77
78
79
80
            CACHE INTERNAL "Linker flags for Boost+Python")
      endif(BoostPython_FromCMake)
    endif(PYTHONLIBS_FOUND)
  endif(NOT BoostPython_INCLUDE_DIRS OR NOT BoostPython_LIBRARIES)

  if(NOT BoostPython_INCLUDE_DIRS OR NOT BoostPython_LIBRARIES)
    # Second try: try pkg-config way
    find_package(PkgConfig)
    if(PKG_CONFIG_FOUND)
81
82
83
      # Prefer the -embed version from Python 3.8, as it is the way to
      # actually link against the Python library.
      set(PYTHON_VERSIONS "python3-embed;python-3.9-embed;python-3.8-embed;python3;python-3.7;python-3.6;python-3.5")
84
85
86
87
88
89
90
91
92
93
94
95
96
97
      foreach(_pyver ${PYTHON_VERSIONS})
        if(NOT BoostPython_INCLUDES OR NOT BoostPython_LIBS)
          pkg_check_modules(${_pyver} QUIET ${_pyver})
          if(${_pyver}_FOUND)
            cmake_push_check_state()
            set(CMAKE_REQUIRED_INCLUDES  ${CMAKE_REQUIRED_INCLUDES}  ${${_pyver}_INCLUDE_DIRS})
            set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${${_pyver}_LDFLAGS})
            BoostPython_TRY_COMPILE(BoostPython_${_pyver})
            cmake_pop_check_state()

            if(BoostPython_${_pyver})
              set(BoostPython_COMPILES Yes)
              set(BoostPython_INCLUDE_DIRS ${${_pyver}_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
                  CACHE INTERNAL "Includes search path for Boost+Python")
98
              set(BoostPython_LIBRARIES    ${${_pyver}_LDFLAGS}      ${Boost_PYTHON3_LIBRARY}
99
100
101
102
103
104
105
106
                  CACHE INTERNAL "Linker flags for Boost+Python")
            endif(BoostPython_${_pyver})

          endif(${_pyver}_FOUND)
        endif(NOT BoostPython_INCLUDES OR NOT BoostPython_LIBS)
      endforeach(_pyver ${PYTHON_VERSIONS})
    endif(PKG_CONFIG_FOUND)
  endif(NOT BoostPython_INCLUDE_DIRS OR NOT BoostPython_LIBRARIES )
107
endif(HAVE_BOOST_SHARED_PTR_HPP AND Boost_PYTHON3_FOUND)
108
109

cmake_pop_check_state()
110

111
112
113
114
find_package_handle_standard_args(BoostPython
                                  FOUND_VAR BoostPython_FOUND
                                  REQUIRED_VARS BoostPython_LIBRARIES BoostPython_INCLUDE_DIRS
                                 )
115

116
mark_as_advanced(BoostPython_INCLUDE_DIRS BoostPython_LIBRARIES)