############################################################################### # # Description : CMake build script for libSBML Python bindings # Original author(s): Frank Bergmann # Organization : California Institute of Technology # # This file is part of libSBML. Please visit http://sbml.org for more # information about SBML, and the latest version of libSBML. # # Copyright (C) 2013-2016 jointly by the following organizations: # 1. California Institute of Technology, Pasadena, CA, USA # 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK # 3. University of Heidelberg, Heidelberg, Germany # # Copyright (C) 2009-2013 jointly by the following organizations: # 1. California Institute of Technology, Pasadena, CA, USA # 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK # # Copyright (C) 2006-2008 by the California Institute of Technology, # Pasadena, CA, USA # # Copyright (C) 2002-2005 jointly by the following organizations: # 1. California Institute of Technology, Pasadena, CA, USA # 2. Japan Science and Technology Agency, Japan # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation. A copy of the license agreement is provided # in the file named "LICENSE.txt" included with this software distribution # and also available online as http://sbml.org/software/libsbml/license.html # ############################################################################### find_package(SWIG REQUIRED) include(${SWIG_USE_FILE}) find_package(PythonInterp) # specify that the same python library should be found # as the one the selected interpreter uses set (Python_ADDITIONAL_VERSIONS ${PYTHON_VERSION_STRING}) find_package(PythonLibs) #################################################################### # # determine local dependencies, so as to re-swig if one of them changed # file(GLOB SWIG_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/*.i ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.cmake ${CMAKE_CURRENT_SOURCE_DIR}/../swig/*.i ${CMAKE_CURRENT_SOURCE_DIR}/../swig/*.h ) #################################################################### # # generate files that include all packages: # # - local-packages.i file(GLOB DOWNCAST_EXTENSION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/local-*.i") list(REMOVE_ITEM DOWNCAST_EXTENSION "local-packages.i") # - local-packages.i update_ifile( "local-packages.i" ${CMAKE_CURRENT_BINARY_DIR} "${DOWNCAST_EXTENSION}" ) # - local-downcast.cpp file(GLOB DOWNCAST_EXTENSION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/local-downcast-packages-*.cpp") update_cfile( "local-downcast.cpp" ${CMAKE_CURRENT_BINARY_DIR} "${DOWNCAST_EXTENSION}" ) # - local-downcast-extension.cpp file(GLOB DOWNCAST_EXTENSION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/local-downcast-extension-*.cpp") update_cfile( "local-downcast-extension.cpp" ${CMAKE_CURRENT_BINARY_DIR} "${DOWNCAST_EXTENSION}" ) # - local-downcast-namespaces.cpp file(GLOB DOWNCAST_EXTENSION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/local-downcast-namespaces-*.cpp") update_cfile( "local-downcast-namespaces.cpp" ${CMAKE_CURRENT_BINARY_DIR} "${DOWNCAST_EXTENSION}" ) # - local-downcast-plugins.cpp file(GLOB DOWNCAST_EXTENSION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/local-downcast-plugins-*.cpp") update_cfile( "local-downcast-plugins.cpp" ${CMAKE_CURRENT_BINARY_DIR} "${DOWNCAST_EXTENSION}" ) # - local-downcast-converters.cpp file(GLOB DOWNCAST_EXTENSION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/local-downcast-converters-*.cpp") update_cfile( "local-downcast-converters.cpp" ${CMAKE_CURRENT_BINARY_DIR} "${DOWNCAST_EXTENSION}" ) # # Remove SWIG wrappers if requested # if (LIBSBML_REMOVE_WRAPPERS) foreach(file ${CMAKE_CURRENT_BINARY_DIR}/libsbml_wrap.cpp ${CMAKE_CURRENT_BINARY_DIR}/pydoc-normal.i ${CMAKE_CURRENT_BINARY_DIR}/pydoc-doxygen.i ) if (EXISTS ${file}) FILE(REMOVE ${file}) endif() endforeach() endif(LIBSBML_REMOVE_WRAPPERS) # the Python bindings will only build if some files are generated, # for those files to be generated the following python scripts are # needed file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../swig/libsbmlutils.py "${CMAKE_CURRENT_SOURCE_DIR}/../../../docs/src/utilities/generate-class-name-list.py" "${CMAKE_CURRENT_SOURCE_DIR}/../../../docs/src/utilities/generate-converters-list.py" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) #################################################################### # # Swig bindings # # add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libsbml_wrap.cpp ${CMAKE_CURRENT_BINARY_DIR}/libsbml.py ${CMAKE_CURRENT_BINARY_DIR}/class-list.txt ${CMAKE_CURRENT_BINARY_DIR}/libsbml-converters.txt COMMAND "${PYTHON_EXECUTABLE}" ARGS "${CMAKE_CURRENT_SOURCE_DIR}/../swig/swigdoc.py" --language python --top "${LIBSBML_ROOT_SOURCE_DIR}" --master "${CMAKE_CURRENT_SOURCE_DIR}/../swig/libsbml.i" --output "${CMAKE_CURRENT_BINARY_DIR}/pydoc-doxygen.i" ${SWIG_SWIGDOCDEFINES} COMMAND "${PYTHON_EXECUTABLE}" ARGS "${CMAKE_CURRENT_BINARY_DIR}/generate-class-name-list.py" "${LIBSBML_ROOT_SOURCE_DIR}/src" > "${CMAKE_CURRENT_BINARY_DIR}/class-list.txt" COMMAND "${PYTHON_EXECUTABLE}" ARGS "${CMAKE_CURRENT_BINARY_DIR}/generate-converters-list.py" "${CMAKE_CURRENT_BINARY_DIR}/class-list.txt" > "${CMAKE_CURRENT_BINARY_DIR}/libsbml-converters.txt" COMMAND "${PYTHON_EXECUTABLE}" ARGS "${CMAKE_CURRENT_SOURCE_DIR}/doc-converter/rewrite_pydoc.py" -f "${CMAKE_CURRENT_BINARY_DIR}/pydoc-doxygen.i" -o "${CMAKE_CURRENT_BINARY_DIR}/pydoc-normal.i" -i ${CMAKE_CURRENT_SOURCE_DIR}/../../../docs/src/common-text -g ${CMAKE_CURRENT_SOURCE_DIR}/../../../docs/src/common-graphics COMMAND "${CMAKE_COMMAND}" ARGS -E rename pydoc-doxygen.i pydoc.i COMMAND "${SWIG_EXECUTABLE}" ARGS -I${CMAKE_CURRENT_SOURCE_DIR}/../swig/ -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR} -I${LIBSBML_ROOT_BINARY_DIR}/src -I${LIBSBML_ROOT_SOURCE_DIR}/src -I${LIBSBML_ROOT_SOURCE_DIR}/include -DGENERATING_DOCS -c++ -python ${SWIG_EXTRA_ARGS} -o ${CMAKE_CURRENT_BINARY_DIR}/libsbml_wrap.cpp ${CMAKE_CURRENT_SOURCE_DIR}/libsbml.i COMMAND "${CMAKE_COMMAND}" ARGS -E rename pydoc.i pydoc-doxygen.i COMMAND "${CMAKE_COMMAND}" ARGS -E rename libsbml.py libsbml-doxygen.py COMMAND "${CMAKE_COMMAND}" ARGS -E rename pydoc-normal.i pydoc.i COMMAND "${SWIG_EXECUTABLE}" ARGS -I${CMAKE_CURRENT_SOURCE_DIR}/../swig/ -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR} -I${LIBSBML_ROOT_BINARY_DIR}/src -I${LIBSBML_ROOT_SOURCE_DIR}/src -I${LIBSBML_ROOT_SOURCE_DIR}/include -c++ -python ${SWIG_EXTRA_ARGS} -o ${CMAKE_CURRENT_BINARY_DIR}/libsbml_wrap.cpp ${CMAKE_CURRENT_SOURCE_DIR}/libsbml.i COMMAND "${CMAKE_COMMAND}" ARGS -E rename pydoc.i pydoc-normal.i COMMAND "${CMAKE_COMMAND}" ARGS -DCUR_BIN_DIRECTORY=\"${CMAKE_CURRENT_BINARY_DIR}\" -DVERSION=\"${LIBSBML_DOTTED_VERSION}\" -P "${CMAKE_CURRENT_SOURCE_DIR}/add_version.cmake" MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/libsbml.i DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/doc-converter/rewrite_pydoc.py ${CMAKE_CURRENT_SOURCE_DIR}/../swig/swigdoc.py ${SWIG_DEPENDENCIES} ${LIBSBML_HEADER_FILES} COMMENT "Swig Python source") add_custom_target(binding_python_swig ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/libsbml_wrap.cpp ) #################################################################### # # Build native library # include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../swig) include_directories(${LIBSBML_ROOT_SOURCE_DIR}/include) include_directories(${PYTHON_INCLUDE_DIRS}) include_directories(BEFORE ${LIBSBML_ROOT_BINARY_DIR}/src) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) if (EXTRA_INCLUDE_DIRS) include_directories(${EXTRA_INCLUDE_DIRS}) endif(EXTRA_INCLUDE_DIRS) if (MSVC) # the build fails when compiled with packages as the object file is too # big adding the big flag makes it work! add_definitions(/bigobj) endif(MSVC) add_library(binding_python_lib SHARED libsbml_wrap.cpp) add_dependencies( binding_python_lib binding_python_swig) set_target_properties (binding_python_lib PROPERTIES OUTPUT_NAME "_libsbml") if (UNIX) set_target_properties (binding_python_lib PROPERTIES PREFIX "") set_target_properties (binding_python_lib PROPERTIES SUFFIX ".so") else() if (CYGWIN) set_target_properties (binding_python_lib PROPERTIES PREFIX "") set_target_properties (binding_python_lib PROPERTIES SUFFIX ".dll") else() set_target_properties (binding_python_lib PROPERTIES SUFFIX ".pyd") endif() endif() if(APPLE) option (PYTHON_USE_DYNAMIC_LOOKUP "Do not actually link against the python library, instead use the undefined lookup mechanism." OFF) mark_as_advanced(PYTHON_USE_DYNAMIC_LOOKUP) endif(APPLE) if (APPLE AND PYTHON_USE_DYNAMIC_LOOKUP) set_target_properties (binding_python_lib PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") target_link_libraries(binding_python_lib ${LIBSBML_LIBRARY}-static) else() target_link_libraries(binding_python_lib ${LIBSBML_LIBRARY}-static ${PYTHON_LIBRARIES}) endif() # # Determine the python installation directory # set(PYTHON_PACKAGE_INSTALL_DIR) if (UNIX OR CYGWIN) execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys;import platform; sys.stdout.write(platform.python_version()[:3])" OUTPUT_VARIABLE PYTHON_VERSION) set(PYTHON_PACKAGE_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION}/site-packages) else() set(PYTHON_PACKAGE_INSTALL_DIR ${MISC_PREFIX}bindings/python) endif() #################################################################### # # install using the configured install prefix # option (PYTHON_INSTALL_IN_PREFIX "Install python binaries using the specified install prefix." ON) if (PYTHON_INSTALL_IN_PREFIX) install(TARGETS binding_python_lib DESTINATION ${PYTHON_PACKAGE_INSTALL_DIR}/libsbml ) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libsbml.pth" "libsbml\n") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libsbml.pth DESTINATION ${PYTHON_PACKAGE_INSTALL_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libsbml.py DESTINATION ${PYTHON_PACKAGE_INSTALL_DIR}/libsbml ) endif(PYTHON_INSTALL_IN_PREFIX) #################################################################### # # install using setup.py # option (PYTHON_INSTALL_WITH_SETUP "Use setup.py to install the compiled python binaries (be sure to install with the appropriate privileges)." OFF) if (PYTHON_INSTALL_WITH_SETUP) # adjust the setup.py script configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/setup.py) # execute the python interpreter INSTALL(TARGETS binding_python_lib DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/libsbml) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libsbml.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/libsbml RENAME __init__.py ) INSTALL(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir ${CMAKE_CURRENT_BINARY_DIR} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py install)") endif(PYTHON_INSTALL_WITH_SETUP) #################################################################### # # generate source package # option(WITH_CREATE_PYTHON_SOURCE "Generate Python Source Package." OFF) if (WITH_CREATE_PYTHON_SOURCE AND EXISTS "${LIBSBML_ROOT_SOURCE_DIR}/dev/utilities/python_package/") SET(PYTHON_SOURCE_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/out) file(TO_NATIVE_PATH ${PYTHON_SOURCE_OUT_DIR} NATIVE_OUT) add_custom_command( OUTPUT ${PYTHON_SOURCE_OUT_DIR}/setup.py COMMAND "${CMAKE_COMMAND}" ARGS -E make_directory ${PYTHON_SOURCE_OUT_DIR} COMMAND "${CMAKE_COMMAND}" ARGS -DOUT_DIR=\"${NATIVE_OUT}\" -DSRC_DIR=\"${LIBSBML_ROOT_SOURCE_DIR}/src\" -DBIN_DIR=\"${LIBSBML_ROOT_BINARY_DIR}\" -P "${LIBSBML_ROOT_SOURCE_DIR}/dev/utilities/python_package/create_package.cmake" DEPENDS ${LIBSBML_ROOT_SOURCE_DIR}/VERSION.txt WORKING_DIRECTORY "${LIBSBML_ROOT_SOURCE_DIR}/dev/utilities/python_package/" COMMENT "Configure Python source package" ) add_custom_target(binding_python_source_config ALL DEPENDS ${PYTHON_SOURCE_OUT_DIR}/setup.py) add_dependencies(binding_python_source_config binding_python_swig binding_python_lib) add_custom_command( OUTPUT ${PYTHON_SOURCE_OUT_DIR}/MANIFEST COMMAND "${PYTHON_EXECUTABLE}" ARGS setup.py sdist DEPENDS ${PYTHON_SOURCE_OUT_DIR}/setup.py ${LIBSBML_ROOT_SOURCE_DIR}/dev/utilities/python_package/create_package.cmake WORKING_DIRECTORY "${PYTHON_SOURCE_OUT_DIR}" COMMENT "Create Python source package" ) add_custom_target(binding_python_source_package ALL DEPENDS ${PYTHON_SOURCE_OUT_DIR}/MANIFEST) add_dependencies(binding_python_source_package binding_python_source_config) add_dependencies( binding_python_source_package binding_python_swig) endif(WITH_CREATE_PYTHON_SOURCE AND EXISTS "${LIBSBML_ROOT_SOURCE_DIR}/dev/utilities/python_package/") #################################################################### # # testing # if(WITH_CHECK) # copy test files to build dir file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # run python tests add_test(NAME test_python_binding COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/test.py -p $ -b ${CMAKE_CURRENT_SOURCE_DIR}/test) endif()