diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..8d7bceb2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,64 @@ +if (PYTHON_LIBRARIES) + include_directories(${PYTHON_INCLUDE_PATH}) + + # Determine extra libraries we need to link against to build Python + # extension modules. + if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "dl") + if(CMAKE_COMPILER_IS_GNUCXX) + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt") + endif(CMAKE_COMPILER_IS_GNUCXX) + elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSD") + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread") + elseif(CMAKE_SYSTEM_NAME STREQUAL "DragonFly") + # DragonFly is a variant of FreeBSD + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread") + elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF") + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl") + if(CMAKE_COMPILER_IS_GNUCXX) + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt") + endif(CMAKE_COMPILER_IS_GNUCXX) + elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") + # No options necessary for QNX + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # No options necessary for Mac OS X + elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX") + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "rt") + elseif(UNIX) + # Assume -pthread and -ldl on all other variants + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "pthread" "dl") + if(CMAKE_COMPILER_IS_GNUCXX) + set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} "util") + endif(CMAKE_COMPILER_IS_GNUCXX) + endif(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + + # Macro for building Boost.Python extension modules + macro(boost_python_extension MODULE_NAME) + parse_arguments(BPL_EXT + "" + "" + ${ARGN}) + + # Create the library target itself + add_library(${MODULE_NAME} MODULE ${BPL_EXT_DEFAULT_ARGS} ) + + # Miscellaneous target properties + set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") + + # Link against Boost.Python library + target_link_libraries(${MODULE_NAME} boost_python-shared) + + # Link against Python libraries + target_link_libraries(${MODULE_NAME} ${PYTHON_LIBRARIES}) + endmacro(boost_python_extension) + + boost_library_project( + Python + SRCDIRS src + TESTDIRS test + HEADERS python.hpp python + MODULARIZED + DESCRIPTION "A framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler." + AUTHORS "David Abrahams " + ) +endif (PYTHON_LIBRARIES) diff --git a/module.cmake b/module.cmake new file mode 100644 index 00000000..5bfa0c79 --- /dev/null +++ b/module.cmake @@ -0,0 +1,3 @@ +boost_module(python DEPENDS graph numeric) + +# numeric is there because of boost/cast.hpp from libs/python/src/errors.cpp:11 \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..bfafa16a --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,64 @@ +if (PYTHON_DEBUG_LIBRARIES AND BUILD_BOOST_PYTHON) + # We have detected that there might be Python debug libraries + # available, but check for ourselves whether this is true by trying + # to compile/link a program against them. + set(CMAKE_REQUIRED_DEFINITIONS "-DBOOST_DEBUG_PYTHON -DPy_DEBUG") + get_directory_property(CMAKE_REQUIRED_INCLUDES INCLUDE_DIRECTORIES) + set(CMAKE_REQUIRED_LIBRARIES ${PYTHON_DEBUG_LIBRARIES}) + set(CHECK_PYDEBUG_SOURCE + "#include ") + check_cxx_source_compiles( + "#include + void check(PyObject *obj) { Py_INCREF(obj); } int main() { }" + PYDEBUG_CAN_BUILD) + + # Setup an option to enable/disable building variants with Python + # debugging. If we were able to link against the debug libraries, + # default to ON; otherwise, default to OFF. + option(BUILD_PYTHON_DEBUG + "Build an additional Boost.Python library with Python debugging enabled" + ${PYDEBUG_CAN_BUILD}) +endif (PYTHON_DEBUG_LIBRARIES AND BUILD_BOOST_PYTHON) + +# Always build the non-debug variants of the boost_python library +set(BUILD_PYTHON_NODEBUG ON) + +boost_add_library(boost_python + numeric.cpp + list.cpp + long.cpp + dict.cpp + tuple.cpp + str.cpp + slice.cpp + converter/from_python.cpp + converter/registry.cpp + converter/type_id.cpp + object/enum.cpp + object/class.cpp + object/function.cpp + object/inheritance.cpp + object/life_support.cpp + object/pickle_support.cpp + errors.cpp + module.cpp + converter/builtin_converters.cpp + converter/arg_to_python_base.cpp + object/iterator.cpp + object/stl_iterator.cpp + object_protocol.cpp + object_operators.cpp + wrapper.cpp + import.cpp + exec.cpp + object/function_doc_signature.cpp + + STATIC_COMPILE_FLAGS "-DBOOST_PYTHON_SOURCE -DBOOST_PYTHON_STATIC_LIB" + SHARED_COMPILE_FLAGS "-DBOOST_PYTHON_SOURCE" + PYTHON_NODEBUG_LINK_LIBS "${PYTHON_LIBRARIES}" + + # Support for Python debugging + EXTRA_VARIANTS PYTHON_NODEBUG:PYTHON_DEBUG + PYTHON_DEBUG_COMPILE_FLAGS "-DBOOST_DEBUG_PYTHON -DPy_DEBUG" + PYTHON_DEBUG_LINK_LIBS "${PYTHON_DEBUG_LIBRARIES}" + ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..0bc615dc --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,194 @@ +macro(bpl_test TESTNAME) + parse_arguments(BPL_TEST + "ARGS" + "" + ${ARGN}) + + # Determine the Python and C++ source files for this test + if (BPL_TEST_DEFAULT_ARGS) + # First argument is the Python source we will run, the rest are + # either extra Python sources we're dependent on or C++ files from + # which we will build extension modules. + car(BPL_TEST_PYSOURCE ${BPL_TEST_DEFAULT_ARGS}) + cdr(BPL_TEST_DEFAULT_ARGS ${BPL_TEST_DEFAULT_ARGS}) + + get_filename_component(BPL_TEST_PYBASE ${BPL_TEST_PYSOURCE} NAME_WE) + foreach(SRC ${BPL_TEST_DEFAULT_ARGS}) + get_filename_component(BPL_SRC_EXT ${SRC} EXT) + if (BPL_SRC_EXT STREQUAL ".cpp") + # Build a Python extension module from this source file + get_filename_component(BPL_SRC_NAME ${SRC} NAME_WE) + if(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}") + boost_python_extension(${BPL_SRC_NAME}_ext ${SRC}) + else(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}") + boost_python_extension(${BPL_SRC_NAME} ${SRC}) + endif(BPL_TEST_PYBASE STREQUAL "${BPL_SRC_NAME}") + endif (BPL_SRC_EXT STREQUAL ".cpp") + endforeach(SRC ${BPL_TEST_DEFAULT_ARGS}) + else (BPL_TEST_DEFAULT_ARGS) + set(BPL_TEST_PYSOURCE "${TESTNAME}.py") + + # Build a Python extension module from this source file + boost_python_extension(${TESTNAME}_ext "${TESTNAME}.cpp") + endif(BPL_TEST_DEFAULT_ARGS) + + # We'll need the full patch to run the Python test + set(BPL_TEST_PYSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${BPL_TEST_PYSOURCE}) + + # Run the test itself + file(TO_NATIVE_PATH "${LIBRARY_OUTPUT_PATH}" PYTHONPATH) + if(WIN32 AND NOT UNIX) + string(REPLACE "\\" "\\\\" PYTHONPATH "${PYTHONPATH}") + endif(WIN32 AND NOT UNIX) + add_test("${PROJECT_NAME}::${TESTNAME}" + ${PYTHON_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/pyrun.py" + "${PYTHONPATH}" + ${BPL_TEST_PYSOURCE} ${BPL_TEST_ARGS}) +endmacro(bpl_test) + +macro(py_run TESTNAME) + boost_test_run(${TESTNAME} + ${TESTNAME}.cpp + DEPENDS boost_python STATIC + LINK_LIBS ${PYTHON_LIBRARIES}) +endmacro(py_run) + +boost_test_run(exec + DEPENDS boost_python STATIC + ARGS "${CMAKE_CURRENT_SOURCE_DIR}/exec.py" + LINK_LIBS ${PYTHON_LIBRARIES}) +boost_test_run(exec-dynamic + exec.cpp + ARGS "${CMAKE_CURRENT_SOURCE_DIR}/exec.py" + DEPENDS boost_python SHARED + LINK_LIBS ${PYTHON_LIBRARIES}) + +bpl_test(crossmod_exception + crossmod_exception.py crossmod_exception_a.cpp crossmod_exception_b.cpp) + +bpl_test(injected) +bpl_test(properties) +bpl_test(return_arg) +bpl_test(staticmethod) +bpl_test(shared_ptr) +bpl_test(andreas_beyer) +bpl_test(polymorphism) +bpl_test(polymorphism2) + +bpl_test(wrapper_held_type) +bpl_test(polymorphism2_auto_ptr) + +bpl_test(auto_ptr) + +bpl_test(minimal) +bpl_test(args) +bpl_test(raw_ctor) +bpl_test(numpy numpy.py printer.py numeric_tests.py numarray_tests.py numpy.cpp) +bpl_test(enum) +bpl_test(exception_translator) +bpl_test(pearu1 test_cltree.py cltree.cpp) +bpl_test(try newtest.py m1.cpp m2.cpp) +bpl_test(const_argument) +bpl_test(keywords keywords_test.py keywords.cpp) + +boost_python_extension(builtin_converters_ext test_builtin_converters.cpp) +bpl_test(builtin_converters test_builtin_converters.py builtin_converters_ext) + +bpl_test(test_pointer_adoption) +bpl_test(operators) +bpl_test(callbacks) +bpl_test(defaults) + +bpl_test(object) +bpl_test(list) +bpl_test(long) +bpl_test(dict) +bpl_test(tuple) +bpl_test(str) +bpl_test(slice) + +bpl_test(virtual_functions) +bpl_test(back_reference) +bpl_test(implicit) +bpl_test(data_members) + +bpl_test(ben_scott1) + +bpl_test(bienstman1) +bpl_test(bienstman2) +bpl_test(bienstman3) + +bpl_test(multi_arg_constructor) +# TODO: A bug in the Win32 intel compilers causes compilation of one +# of our tests to take forever when debug symbols are +# enabled. This rule turns them off when added to the requirements +# section +# intel-win:off + +bpl_test(iterator iterator.py iterator.cpp input_iterator.cpp) + +bpl_test(stl_iterator stl_iterator.py stl_iterator.cpp) + +bpl_test(extract) + +bpl_test (crossmod_opaque + crossmod_opaque.py crossmod_opaque_a.cpp crossmod_opaque_b.cpp) + +bpl_test(opaque) +bpl_test(voidptr) + +bpl_test(pickle1) +bpl_test(pickle2) +bpl_test(pickle3) +bpl_test(pickle4) + +bpl_test(nested) + +bpl_test(docstring) + +bpl_test(vector_indexing_suite) + +bpl_test(pointer_vector) +# TODO: Turn off this test on HP CXX, as the test hangs when executing. +# Whenever the cause for the failure of the polymorphism test is found +# and fixed, this should be retested. +# hp_cxx:no + +boost_python_extension(map_indexing_suite_ext + map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp) + +bpl_test(map_indexing_suite + map_indexing_suite.py map_indexing_suite_ext) + + +# --- unit tests of library components --- + +boost_test_compile(indirect_traits_test) +boost_test_run(destroy_test) +py_run(pointer_type_id_test) +py_run(bases) +boost_test_run(if_else) +py_run(pointee) +boost_test_run(result) + +boost_test_compile(string_literal) +boost_test_compile(borrowed) +boost_test_compile(object_manager) +boost_test_compile(copy_ctor_mutates_rhs) + +py_run(upcast) + +boost_test_compile(select_holder) + +boost_test_run(select_from_python_test + select_from_python_test.cpp ../src/converter/type_id.cpp + COMPILE_FLAGS "-DBOOST_PYTHON_STATIC_LIB" + LINK_LIBS ${PYTHON_LIBRARIES}) + +boost_test_compile(select_arg_to_python_test) + +boost_test_compile_fail(raw_pyobject_fail1) +boost_test_compile_fail(raw_pyobject_fail2) +boost_test_compile_fail(as_to_python_function) +boost_test_compile_fail(object_fail1)