cmake_minimum_required(VERSION 3.10.2) set(CMAKE_OSX_ARCHITECTURES x86_64) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) project(coremltools) if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(FATAL_ERROR " Source directory '${PROJECT_SOURCE_DIR}' is the same as binary directory '${PROJECT_BINARY_DIR}'; coremltools requires an out-of-source build. Note that your directory tree will require you to remove CMakeCache.txt before this will work, and CMake may have clobbered some source files (use git reset --hard). See: https://gitlab.kitware.com/cmake/community/wikis/FAQ#i-run-an-out-of-source-build-but-cmake-generates-in-source-anyway-why ") endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Globally ignore "no symbols" warnings during compilation SET(CMAKE_CXX_ARCHIVE_CREATE " Scr ") if(APPLE) SET(CMAKE_CXX_ARCHIVE_FINISH " -no_warning_for_no_symbols -c ") endif() find_program(HAS_CCACHE ccache) if(HAS_CCACHE) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) endif() add_subdirectory(deps) add_subdirectory(mlmodel) find_package(PythonInterp) find_package(PythonLibs) message("Found python at ${PYTHON_EXECUTABLE}") message("Found python version ${PYTHON_VERSION_STRING}") message("Found python includes ${PYTHON_INCLUDE_DIRS}") include_directories( . deps/protobuf/src deps/pybind11/include deps/nlohmann mlmodel/src ${PYTHON_INCLUDE_DIRS} ) if(APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc") endif() add_library(milstoragepython SHARED milstoragepython/MilStorage.cpp milstoragepython/MilStoragePython.cpp ) target_link_libraries(milstoragepython mlmodel ) add_library(modelpackage SHARED modelpackage/src/ModelPackage.cpp modelpackage/src/utils/JsonMap.cpp modelpackage/src/ModelPackagePython.cpp ) target_compile_definitions(modelpackage PRIVATE CPU_ONLY=1 ) target_link_libraries(modelpackage mlmodel libprotobuf ) if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) target_link_libraries(modelpackage stdc++fs ) endif() if (APPLE) # Allow Python to be found at runtime instead of compile/link time # This is apparently the default on Linux set_target_properties(milstoragepython PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") set_target_properties(modelpackage PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") endif() file(COPY ${CMAKE_SOURCE_DIR}/README.md DESTINATION ${CMAKE_BINARY_DIR}) file(COPY ${CMAKE_SOURCE_DIR}/coremltools/__init__.py DESTINATION ${CMAKE_BINARY_DIR}/coremltools) file(COPY ${CMAKE_SOURCE_DIR}/coremltools/version.py DESTINATION ${CMAKE_BINARY_DIR}/coremltools) set(copy_dirs _deps converters models proto) foreach(cdir IN ITEMS ${copy_dirs}) file(COPY ${CMAKE_SOURCE_DIR}/coremltools/${cdir} DESTINATION ${CMAKE_BINARY_DIR}/coremltools) endforeach() if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") set(_additional_milstoragepython_command COMMAND strip -x ${PROJECT_SOURCE_DIR}/coremltools/libmilstoragepython.so) set(_additional_modelpackage_command COMMAND strip -x ${PROJECT_SOURCE_DIR}/coremltools/libmodelpackage.so) endif() add_custom_command( TARGET modelpackage POST_BUILD COMMAND cp $ ${PROJECT_SOURCE_DIR}/coremltools/libmodelpackage.so ${_additional_modelpackage_command} ) if (NOT APPLE) target_link_libraries(modelpackage uuid) endif() add_custom_command( TARGET milstoragepython POST_BUILD COMMAND cp $ ${PROJECT_SOURCE_DIR}/coremltools/libmilstoragepython.so ${_additional_milstoragepython_command} ) find_library(CORE_VIDEO CoreVideo) find_library(CORE_ML CoreML) find_library(FOUNDATION Foundation) if (APPLE AND CORE_VIDEO AND CORE_ML AND FOUNDATION) execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print(numpy.get_include())" RESULT_VARIABLE NUMPY_INCLUDE_STATUS OUTPUT_VARIABLE NUMPY_INCLUDE ) if("${NUMPY_INCLUDE}" STREQUAL "" OR NOT NUMPY_INCLUDE_STATUS EQUAL 0) message(FATAL_ERROR "Could not find numpy include path. Exit code: ${NUMPY_INCLUDE_STATUS}") endif() message("Found numpy include path at ${NUMPY_INCLUDE}") include_directories( ${NUMPY_INCLUDE} ) add_library(coremlpython SHARED coremlpython/CoreMLPython.mm coremlpython/CoreMLPython.h coremlpython/CoreMLPythonArray.mm coremlpython/CoreMLPythonArray.h coremlpython/CoreMLPythonUtils.mm coremlpython/CoreMLPythonUtils.h ) target_link_libraries(coremlpython mlmodel ${CORE_VIDEO} ${CORE_ML} ${FOUNDATION} ) set(osx_export_file ${CMAKE_SOURCE_DIR}/coremlpython/exported_symbols_osx.ver) set_property(TARGET coremlpython APPEND PROPERTY LINK_DEPENDS "${osx_export_file}") set_property(TARGET coremlpython APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-exported_symbols_list,${osx_export_file} ") # Allow Python to be found at runtime instead of compile/link time # This is apparently the default on Linux set_property(TARGET coremlpython APPEND_STRING PROPERTY LINK_FLAGS "-undefined dynamic_lookup") set_property(TARGET coremlpython APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-dead_strip") if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") set(_additional_libcoremlpython_command COMMAND strip -x ${PROJECT_SOURCE_DIR}/coremltools/libcoremlpython.so ) endif() add_custom_command( TARGET coremlpython POST_BUILD COMMAND cp $ ${PROJECT_SOURCE_DIR}/coremltools/libcoremlpython.so ${_additional_libcoremlpython_command} ) else() message(STATUS "CoreML.framework and dependent frameworks not found. Skipping libcoremlpython build.") endif() set(PYTHON_TAG "cp${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") if(APPLE) execute_process(COMMAND uname -m OUTPUT_VARIABLE HARDWARE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) if(${HARDWARE_NAME} MATCHES "x86_64") set(MIN_MAC_OS "10_15") elseif(${HARDWARE_NAME} MATCHES "arm64") set(MIN_MAC_OS "11_0") else() message(FATAL_ERROR "Unsupported hardware type. On macOS, x86_64 and arm64 are supported.") endif() set(PLAT_NAME "macosx_${MIN_MAC_OS}_${HARDWARE_NAME}") elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") set(PLAT_NAME "manylinux1_x86_64") else() message(FATAL_ERROR "Unsupported build platform. Supported platforms are Linux and macOS.") endif() if(BUILD_TAG) set(BUILD_TAG_OPTION "--build-number=${BUILD_TAG}") message(STATUS "Using ${BUILD_TAG} as build tag for wheels.") else() set(BUILD_TAG_OPTION "") endif() # Add a target for each platform, and then a 'dist' that will build all of them. # Parallel invocations of setup.py is not safe, so we serialize them. set(plat_targets "") foreach(platform IN ITEMS ${PLAT_NAME}) add_custom_target(dist_${platform} COMMENT "Building dist for platform ${platform}..." COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/setup.py bdist_wheel --plat-name=${platform} --python-tag=${PYTHON_TAG} ${BUILD_TAG_OPTION} --dist-dir=${PROJECT_BINARY_DIR}/dist DEPENDS "milstoragepython;modelpackage;coremlpython;${plat_targets}" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) set(plat_targets "${plat_targets};dist_${platform}") endforeach() # Add a 'dist' target that will build wheels for all possible platforms. add_custom_target(dist DEPENDS ${plat_targets}) add_custom_target(pip_install_dev COMMAND pip install -e ${PROJECT_SOURCE_DIR} DEPENDS "coremlpython" ) add_custom_target(pytest COMMAND pytest -r fs ${PROJECT_SOURCE_DIR}/coremltools/test/ --timeout=600 DEPENDS pip_install_dev USES_TERMINAL ) add_custom_target(pytest_no_slow COMMAND pytest -r fs -m '"no slow"' ${PROJECT_SOURCE_DIR}/coremltools/test/ DEPENDS pip_install_dev USES_TERMINAL )