1# Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15# CMake rules for generating the TensorFlow Python bindings. 16# 17# Known limitations: 18# * Generates output in a hard-coded path ${CMAKE_CURRENT_BINARY_DIR}/tf_python. 19# * No support for dynamic library loading. 20# * Limited support for tf.contrib. 21# 22# The _pywrap_tensorflow_internal target builds everything. 23 24######################################################## 25# Resolve installed dependencies 26######################################################## 27 28# 1. Resolve the installed version of Python (for Python.h and python). 29# TODO(mrry): Parameterize the build script to enable Python 3 building. 30if(NOT PYTHON_INCLUDE_DIR) 31 set(PYTHON_NOT_FOUND false) 32 exec_program("${PYTHON_EXECUTABLE}" 33 ARGS "-c \"import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())\"" 34 OUTPUT_VARIABLE PYTHON_INCLUDE_DIR 35 RETURN_VALUE PYTHON_NOT_FOUND) 36 if(${PYTHON_NOT_FOUND}) 37 message(FATAL_ERROR 38 "Cannot get Python include directory. Is distutils installed?") 39 endif(${PYTHON_NOT_FOUND}) 40endif(NOT PYTHON_INCLUDE_DIR) 41FIND_PACKAGE(PythonLibs) 42 43# 2. Resolve the installed version of NumPy (for numpy/arrayobject.h). 44if(NOT NUMPY_INCLUDE_DIR) 45 set(NUMPY_NOT_FOUND false) 46 exec_program("${PYTHON_EXECUTABLE}" 47 ARGS "-c \"import numpy; print(numpy.get_include())\"" 48 OUTPUT_VARIABLE NUMPY_INCLUDE_DIR 49 RETURN_VALUE NUMPY_NOT_FOUND) 50 if(${NUMPY_NOT_FOUND}) 51 message(FATAL_ERROR 52 "Cannot get NumPy include directory: Is NumPy installed?") 53 endif(${NUMPY_NOT_FOUND}) 54endif(NOT NUMPY_INCLUDE_DIR) 55 56 57######################################################## 58# Build the Python directory structure. 59######################################################## 60 61# TODO(mrry): Configure this to build in a directory other than tf_python/ 62 63# Generates the Python protobuf wrappers. 64# ROOT_DIR must be absolute; subsequent arguments are interpreted as 65# paths of .proto files, and must be relative to ROOT_DIR. 66function(RELATIVE_PROTOBUF_GENERATE_PYTHON ROOT_DIR SRCS) 67 if(NOT ARGN) 68 message(SEND_ERROR "Error: RELATIVE_PROTOBUF_GENERATE_PYTHON() called without any proto files") 69 return() 70 endif() 71 72 set(${SRCS}) 73 foreach(FIL ${ARGN}) 74 set(ABS_FIL ${ROOT_DIR}/${FIL}) 75 get_filename_component(FIL_WE ${FIL} NAME_WE) 76 get_filename_component(FIL_DIR ${ABS_FIL} PATH) 77 file(RELATIVE_PATH REL_DIR ${ROOT_DIR} ${FIL_DIR}) 78 79 list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/tf_python/${REL_DIR}/${FIL_WE}_pb2.py") 80 add_custom_command( 81 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/tf_python/${REL_DIR}/${FIL_WE}_pb2.py" 82 COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} 83 ARGS --python_out ${CMAKE_CURRENT_BINARY_DIR}/tf_python/ -I ${ROOT_DIR} -I ${PROTOBUF_INCLUDE_DIRS} ${ABS_FIL} 84 DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE} protobuf 85 COMMENT "Running Python protocol buffer compiler on ${FIL}" 86 VERBATIM ) 87 endforeach() 88 set(${SRCS} ${${SRCS}} PARENT_SCOPE) 89endfunction() 90 91function(RELATIVE_PROTOBUF_GENERATE_CPP SRCS HDRS ROOT_DIR) 92 if(NOT ARGN) 93 message(SEND_ERROR "Error: RELATIVE_PROTOBUF_GENERATE_CPP() called without any proto files") 94 return() 95 endif() 96 97 set(${SRCS}) 98 set(${HDRS}) 99 foreach(FIL ${ARGN}) 100 set(ABS_FIL ${ROOT_DIR}/${FIL}) 101 get_filename_component(FIL_WE ${FIL} NAME_WE) 102 get_filename_component(FIL_DIR ${ABS_FIL} PATH) 103 file(RELATIVE_PATH REL_DIR ${ROOT_DIR} ${FIL_DIR}) 104 105 list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.pb.cc") 106 list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.pb.h") 107 108 add_custom_command( 109 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.pb.cc" 110 "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.pb.h" 111 COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} 112 ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${ROOT_DIR} ${ABS_FIL} -I ${PROTOBUF_INCLUDE_DIRS} 113 DEPENDS ${ABS_FIL} protobuf 114 COMMENT "Running C++ protocol buffer compiler on ${FIL}" 115 VERBATIM ) 116 endforeach() 117 118 set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) 119 set(${SRCS} ${${SRCS}} PARENT_SCOPE) 120 set(${HDRS} ${${HDRS}} PARENT_SCOPE) 121endfunction() 122 123FILE(READ python_protos.txt python_protos) 124# Convert file contents into a CMake list (where each element in the list is one line of the file) 125STRING(REGEX REPLACE ";" "\\\\;" python_protos "${python_protos}") 126STRING(REGEX REPLACE "\n" ";" python_protos "${python_protos}") 127 128foreach(python_proto ${python_protos}) 129 if(NOT python_proto MATCHES "^\#") 130 STRING(REGEX REPLACE " *\#.*" "" python_proto "${python_proto}") 131 if(NOT EXISTS "${tensorflow_source_dir}/${python_proto}") 132 message(SEND_ERROR "Python proto directory not found: ${python_proto}") 133 endif() 134 file(GLOB_RECURSE tf_python_protos_src RELATIVE ${tensorflow_source_dir} 135 "${tensorflow_source_dir}/${python_proto}/*.proto" 136 ) 137 list(APPEND tf_python_protos_srcs ${tf_python_protos_src}) 138 endif() 139endforeach(python_proto) 140 141RELATIVE_PROTOBUF_GENERATE_PYTHON( 142 ${tensorflow_source_dir} PYTHON_PROTO_GENFILES ${tf_python_protos_srcs} 143) 144 145FILE(READ python_protos_cc.txt python_protos_cc) 146# Convert file contents into a CMake list (where each element in the list is one line of the file) 147STRING(REGEX REPLACE ";" "\\\\;" python_protos_cc "${python_protos_cc}") 148STRING(REGEX REPLACE "\n" ";" python_protos_cc "${python_protos_cc}") 149 150foreach(python_proto_cc ${python_protos_cc}) 151 if(NOT python_proto_cc MATCHES "^\#") 152 STRING(REGEX REPLACE " *\#.*" "" python_proto_cc "${python_proto_cc}") 153 if(NOT EXISTS "${tensorflow_source_dir}/${python_proto_cc}") 154 message(SEND_ERROR "Python proto CC directory not found: ${python_proto_cc}") 155 endif() 156 file(GLOB_RECURSE tf_python_protos_cc_src RELATIVE ${tensorflow_source_dir} 157 "${tensorflow_source_dir}/${python_proto_cc}/*.proto" 158 ) 159 list(APPEND tf_python_protos_cc_srcs ${tf_python_protos_cc_src}) 160 endif() 161endforeach(python_proto_cc) 162 163RELATIVE_PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS 164 ${tensorflow_source_dir} ${tf_python_protos_cc_srcs} 165) 166 167add_library(tf_python_protos_cc ${PROTO_SRCS} ${PROTO_HDRS}) 168add_dependencies(tf_python_protos_cc tf_protos_cc) 169 170# tf_python_touchup_modules adds empty __init__.py files to all 171# directories containing Python code, so that Python will recognize 172# them as modules. 173add_custom_target(tf_python_touchup_modules) 174 175# tf_python_copy_scripts_to_destination copies all Python files 176# (including static source and generated protobuf wrappers, but *not* 177# generated TensorFlow op wrappers) into tf_python/. 178add_custom_target(tf_python_copy_scripts_to_destination DEPENDS tf_python_touchup_modules) 179 180 181# tf_python_srcs contains all static .py files 182function(add_python_module MODULE_NAME) 183 set(options DONTCOPY) 184 cmake_parse_arguments(ADD_PYTHON_MODULE "${options}" "" "" ${ARGN}) 185 add_custom_command(TARGET tf_python_touchup_modules PRE_BUILD 186 COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/tf_python/${MODULE_NAME}") 187 add_custom_command(TARGET tf_python_touchup_modules PRE_BUILD 188 COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/tf_python/${MODULE_NAME}/__init__.py") 189 file(GLOB module_python_srcs RELATIVE ${tensorflow_source_dir} 190 "${tensorflow_source_dir}/${MODULE_NAME}/*.py" 191 ) 192 if(NOT ${ADD_PYTHON_MODULE_DONTCOPY}) 193 foreach(script ${module_python_srcs}) 194 get_filename_component(REL_DIR ${script} DIRECTORY) 195 # NOTE(mrry): This rule may exclude modules that should be part of 196 # the distributed PIP package 197 # (e.g. tensorflow/contrib/testing/python/framework/util_test.py), 198 # so we currently add explicit commands to include those files 199 # later on in this script. 200 if (NOT "${script}" MATCHES "_test\.py$") 201 add_custom_command(TARGET tf_python_copy_scripts_to_destination PRE_BUILD 202 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/${script} ${CMAKE_CURRENT_BINARY_DIR}/tf_python/${script}) 203 endif() 204 endforeach() 205 endif() 206endfunction() 207 208FILE(READ python_modules.txt python_modules) 209# Convert file contents into a CMake list (where each element in the list is one line of the file) 210STRING(REGEX REPLACE ";" "\\\\;" python_modules "${python_modules}") 211STRING(REGEX REPLACE "\n" ";" python_modules "${python_modules}") 212 213foreach(python_module ${python_modules}) 214 if(NOT python_module MATCHES "^\#") 215 STRING(REGEX REPLACE " *\#.*" "" python_module "${python_module}") 216 if(NOT EXISTS "${tensorflow_source_dir}/${python_module}") 217 message(SEND_ERROR "Python module not found: ${python_module}") 218 endif() 219 add_python_module(${python_module}) 220 endif() 221endforeach(python_module) 222 223add_custom_command(TARGET tf_python_touchup_modules PRE_BUILD 224 COMMAND ${CMAKE_COMMAND} -E make_directory 225 "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/lite") 226add_custom_command(TARGET tf_python_touchup_modules PRE_BUILD 227 COMMAND ${CMAKE_COMMAND} -E make_directory 228 "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/lite/python") 229add_custom_command(TARGET tf_python_touchup_modules PRE_BUILD 230 COMMAND ${CMAKE_COMMAND} -E touch 231 "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/lite/python/__init__.py") 232add_custom_command( 233 TARGET tf_python_copy_scripts_to_destination PRE_BUILD 234 COMMAND ${CMAKE_COMMAND} -E touch 235 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/lite/python/lite.py) 236 237# Generate the tensorflow.python.platform.build_info module. 238set(BUILD_INFO_PY "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/platform/build_info.py") 239add_custom_command(TARGET tf_python_copy_scripts_to_destination PRE_BUILD 240 COMMAND ${PYTHON_EXECUTABLE} ${tensorflow_source_dir}/tensorflow/tools/build_info/gen_build_info.py --raw_generate ${BUILD_INFO_PY} ${tensorflow_BUILD_INFO_FLAGS}) 241 242 243######################################################## 244# tf_python_op_gen_main library 245######################################################## 246set(tf_python_op_gen_main_srcs 247 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen.cc" 248 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen.h" 249 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen_internal.cc" 250 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen_internal.h" 251 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen_main.cc" 252) 253 254add_library(tf_python_op_gen_main OBJECT ${tf_python_op_gen_main_srcs}) 255 256add_dependencies(tf_python_op_gen_main tf_core_framework) 257 258# create directory for ops generated files 259set(python_ops_target_dir ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/ops) 260 261set(tf_python_ops_generated_files) 262 263set(tf_python_op_lib_names 264 ${tf_op_lib_names} 265 "user_ops" 266) 267 268function(GENERATE_PYTHON_OP_LIB tf_python_op_lib_name) 269 set(options SHAPE_FUNCTIONS_NOT_REQUIRED) 270 set(oneValueArgs DESTINATION) 271 set(multiValueArgs ADDITIONAL_LIBRARIES) 272 cmake_parse_arguments(GENERATE_PYTHON_OP_LIB 273 "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 274 if(NOT DEFINED GENERATE_PYTHON_OP_LIB_DESTINATION) 275 # Default destination is tf_python/tensorflow/python/ops/gen_<...>.py. 276 set(GENERATE_PYTHON_OP_LIB_DESTINATION 277 "${python_ops_target_dir}/gen_${tf_python_op_lib_name}.py") 278 endif() 279 if(GENERATE_PYTHON_OP_LIB_SHAPE_FUNCTIONS_NOT_REQUIRED) 280 set(require_shape_fn 0) 281 else() 282 set(require_shape_fn 1) 283 endif() 284 285 get_filename_component(GENERATE_PYTHON_OP_LIB_MKDIRPATH ${GENERATE_PYTHON_OP_LIB_DESTINATION} PATH) 286 file(MAKE_DIRECTORY ${GENERATE_PYTHON_OP_LIB_MKDIRPATH}) 287 288 # Create a C++ executable that links in the appropriate op 289 # registrations and generates Python wrapper code based on the 290 # registered ops. 291 add_executable(${tf_python_op_lib_name}_gen_python 292 $<TARGET_OBJECTS:tf_python_op_gen_main> 293 $<TARGET_OBJECTS:tf_${tf_python_op_lib_name}> 294 $<TARGET_OBJECTS:tf_core_lib> 295 $<TARGET_OBJECTS:tf_core_framework> 296 ${GENERATE_PYTHON_OP_LIB_ADDITIONAL_LIBRARIES} 297 ) 298 target_link_libraries(${tf_python_op_lib_name}_gen_python PRIVATE 299 tf_protos_cc 300 tf_python_protos_cc 301 ${tensorflow_EXTERNAL_LIBRARIES} 302 ) 303 304 # Use the generated C++ executable to create a Python file 305 # containing the wrappers. 306 add_custom_command( 307 OUTPUT ${GENERATE_PYTHON_OP_LIB_DESTINATION} 308 COMMAND ${tf_python_op_lib_name}_gen_python ${tensorflow_source_dir}/tensorflow/core/api_def/base_api,${tensorflow_source_dir}/tensorflow/core/api_def/python_api ${require_shape_fn} > ${GENERATE_PYTHON_OP_LIB_DESTINATION} 309 DEPENDS ${tf_python_op_lib_name}_gen_python 310 ) 311 312 set(tf_python_ops_generated_files ${tf_python_ops_generated_files} 313 ${GENERATE_PYTHON_OP_LIB_DESTINATION} PARENT_SCOPE) 314endfunction() 315 316GENERATE_PYTHON_OP_LIB("array_ops") 317GENERATE_PYTHON_OP_LIB("audio_ops") 318GENERATE_PYTHON_OP_LIB("batch_ops") 319GENERATE_PYTHON_OP_LIB("bitwise_ops") 320GENERATE_PYTHON_OP_LIB("boosted_trees_ops") 321GENERATE_PYTHON_OP_LIB("candidate_sampling_ops") 322GENERATE_PYTHON_OP_LIB("checkpoint_ops") 323GENERATE_PYTHON_OP_LIB("collective_ops") 324GENERATE_PYTHON_OP_LIB("control_flow_ops" 325 ADDITIONAL_LIBRARIES $<TARGET_OBJECTS:tf_no_op>) 326GENERATE_PYTHON_OP_LIB("ctc_ops") 327GENERATE_PYTHON_OP_LIB("cudnn_rnn_ops") 328GENERATE_PYTHON_OP_LIB("data_flow_ops") 329GENERATE_PYTHON_OP_LIB("dataset_ops") 330GENERATE_PYTHON_OP_LIB("decode_proto_ops" 331 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/proto/python/ops/gen_decode_proto_op.py) 332GENERATE_PYTHON_OP_LIB("encode_proto_ops" 333 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/proto/python/ops/gen_encode_proto_op.py) 334GENERATE_PYTHON_OP_LIB("function_ops") 335GENERATE_PYTHON_OP_LIB("functional_ops") 336GENERATE_PYTHON_OP_LIB("image_ops") 337GENERATE_PYTHON_OP_LIB("io_ops") 338GENERATE_PYTHON_OP_LIB("linalg_ops") 339GENERATE_PYTHON_OP_LIB("list_ops") 340GENERATE_PYTHON_OP_LIB("logging_ops") 341GENERATE_PYTHON_OP_LIB("lookup_ops") 342GENERATE_PYTHON_OP_LIB("manip_ops") 343GENERATE_PYTHON_OP_LIB("math_ops") 344GENERATE_PYTHON_OP_LIB("nn_ops") 345GENERATE_PYTHON_OP_LIB("no_op") 346GENERATE_PYTHON_OP_LIB("parsing_ops") 347GENERATE_PYTHON_OP_LIB("random_ops") 348GENERATE_PYTHON_OP_LIB("remote_fused_graph_ops" 349 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/remote_fused_graph/pylib/python/ops/gen_remote_fused_graph_ops.py) 350GENERATE_PYTHON_OP_LIB("resource_variable_ops") 351GENERATE_PYTHON_OP_LIB("rpc_ops" 352 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/rpc/python/ops/gen_rpc_op.py) 353GENERATE_PYTHON_OP_LIB("scoped_allocator_ops") 354GENERATE_PYTHON_OP_LIB("script_ops") 355GENERATE_PYTHON_OP_LIB("sdca_ops") 356GENERATE_PYTHON_OP_LIB("sendrecv_ops") 357GENERATE_PYTHON_OP_LIB("set_ops") 358GENERATE_PYTHON_OP_LIB("sparse_ops") 359GENERATE_PYTHON_OP_LIB("spectral_ops") 360GENERATE_PYTHON_OP_LIB("state_ops") 361GENERATE_PYTHON_OP_LIB("stateless_random_ops") 362GENERATE_PYTHON_OP_LIB("string_ops") 363GENERATE_PYTHON_OP_LIB("summary_ops") 364GENERATE_PYTHON_OP_LIB("user_ops") 365GENERATE_PYTHON_OP_LIB("training_ops" 366 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/training/gen_training_ops.py) 367GENERATE_PYTHON_OP_LIB("word2vec_ops") 368 369GENERATE_PYTHON_OP_LIB("contrib_boosted_trees_model_ops" 370 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/boosted_trees/python/ops/gen_model_ops.py) 371GENERATE_PYTHON_OP_LIB("contrib_boosted_trees_split_handler_ops" 372 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/boosted_trees/python/ops/gen_split_handler_ops.py) 373GENERATE_PYTHON_OP_LIB("contrib_boosted_trees_training_ops" 374 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/boosted_trees/python/ops/gen_training_ops.py) 375GENERATE_PYTHON_OP_LIB("contrib_boosted_trees_prediction_ops" 376 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/boosted_trees/python/ops/gen_prediction_ops.py) 377GENERATE_PYTHON_OP_LIB("contrib_boosted_trees_quantiles_ops" 378 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/boosted_trees/python/ops/gen_quantile_ops.py) 379GENERATE_PYTHON_OP_LIB("contrib_boosted_trees_stats_accumulator_ops" 380 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/boosted_trees/python/ops/gen_stats_accumulator_ops.py) 381GENERATE_PYTHON_OP_LIB("contrib_coder_ops" 382 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/coder/python/ops/gen_coder_ops.py) 383GENERATE_PYTHON_OP_LIB("contrib_factorization_clustering_ops" 384 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/factorization/python/ops/gen_clustering_ops.py) 385GENERATE_PYTHON_OP_LIB("contrib_factorization_factorization_ops" 386 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/factorization/python/ops/gen_factorization_ops.py) 387GENERATE_PYTHON_OP_LIB("contrib_framework_variable_ops" 388 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/framework/python/ops/gen_variable_ops.py) 389GENERATE_PYTHON_OP_LIB("contrib_input_pipeline_ops" 390 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/input_pipeline/ops/gen_input_pipeline_ops.py) 391GENERATE_PYTHON_OP_LIB("contrib_image_ops" 392 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/image/ops/gen_image_ops.py) 393GENERATE_PYTHON_OP_LIB("contrib_image_distort_image_ops" 394 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/image/ops/gen_distort_image_ops.py) 395GENERATE_PYTHON_OP_LIB("contrib_image_sirds_ops" 396 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/image/ops/gen_single_image_random_dot_stereograms_ops.py) 397GENERATE_PYTHON_OP_LIB("contrib_layers_sparse_feature_cross_ops" 398 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/layers/ops/gen_sparse_feature_cross_op.py) 399GENERATE_PYTHON_OP_LIB("contrib_memory_stats_ops" 400 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/memory_stats/ops/gen_memory_stats_ops.py) 401GENERATE_PYTHON_OP_LIB("contrib_periodic_resample_ops" 402 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/periodic_resample/python/ops/gen_periodic_resample_op.py) 403GENERATE_PYTHON_OP_LIB("contrib_nearest_neighbor_ops" 404 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/nearest_neighbor/ops/gen_nearest_neighbor_ops.py) 405GENERATE_PYTHON_OP_LIB("contrib_resampler_ops" 406 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/resampler/ops/gen_resampler_ops.py) 407GENERATE_PYTHON_OP_LIB("contrib_rnn_gru_ops" 408 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/rnn/ops/gen_gru_ops.py) 409GENERATE_PYTHON_OP_LIB("contrib_rnn_lstm_ops" 410 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/rnn/ops/gen_lstm_ops.py) 411GENERATE_PYTHON_OP_LIB("contrib_seq2seq_beam_search_ops" 412 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/seq2seq/ops/gen_beam_search_ops.py) 413GENERATE_PYTHON_OP_LIB("contrib_tensor_forest_ops" 414 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/tensor_forest/python/ops/gen_tensor_forest_ops.py) 415GENERATE_PYTHON_OP_LIB("contrib_tensor_forest_hybrid_ops" 416 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/tensor_forest/hybrid/ops/gen_training_ops.py) 417GENERATE_PYTHON_OP_LIB("contrib_tensor_forest_model_ops" 418 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/tensor_forest/python/ops/gen_model_ops.py) 419GENERATE_PYTHON_OP_LIB("contrib_tensor_forest_stats_ops" 420 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/tensor_forest/python/ops/gen_stats_ops.py) 421GENERATE_PYTHON_OP_LIB("contrib_text_skip_gram_ops" 422 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/text/python/ops/gen_skip_gram_ops.py) 423GENERATE_PYTHON_OP_LIB("contrib_bigquery_reader_ops" 424 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/cloud/python/ops/gen_bigquery_reader_ops.py) 425GENERATE_PYTHON_OP_LIB("contrib_gcs_config_ops" 426 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/cloud/python/ops/gen_gcs_config_ops.py) 427GENERATE_PYTHON_OP_LIB("debug_ops" 428 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/debug/ops/gen_debug_ops.py) 429 430add_custom_target(tf_python_ops SOURCES ${tf_python_ops_generated_files} ${PYTHON_PROTO_GENFILES}) 431add_dependencies(tf_python_ops tf_python_op_gen_main) 432 433 434############################################################ 435# Build the SWIG-wrapped library for the TensorFlow runtime. 436############################################################ 437 438find_package(SWIG REQUIRED) 439# Generate the C++ and Python source code for the SWIG wrapper. 440# NOTE(mrry): We always regenerate the SWIG wrapper, which means that we must 441# always re-link the Python extension, but we don't have to track the 442# individual headers on which the SWIG wrapper depends. 443add_custom_command( 444 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/pywrap_tensorflow_internal.py" 445 "${CMAKE_CURRENT_BINARY_DIR}/pywrap_tensorflow_internal.cc" 446 DEPENDS tf_python_touchup_modules __force_rebuild 447 COMMAND ${SWIG_EXECUTABLE} 448 ARGS -python -c++ 449 -I${tensorflow_source_dir} 450 -I${CMAKE_CURRENT_BINARY_DIR} 451 -module pywrap_tensorflow_internal 452 -outdir ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python 453 -o ${CMAKE_CURRENT_BINARY_DIR}/pywrap_tensorflow_internal.cc 454 -globals '' 455 ${tensorflow_source_dir}/tensorflow/python/tensorflow.i 456 COMMENT "Running SWIG to generate Python wrappers" 457 VERBATIM ) 458 459add_library(tf_c_python_api OBJECT 460 "${tensorflow_source_dir}/tensorflow/c/python_api.cc" 461 "${tensorflow_source_dir}/tensorflow/c/python_api.h" 462) 463add_dependencies( 464 tf_c_python_api 465 tf_c 466 tf_core_lib 467 tf_core_framework 468 tf_protos_cc 469 tf_python_protos_cc) 470 471set (pywrap_tensorflow_internal_src 472 "${tensorflow_source_dir}/tensorflow/core/profiler/internal/print_model_analysis.h" 473 "${tensorflow_source_dir}/tensorflow/core/profiler/internal/print_model_analysis.cc" 474 "${tensorflow_source_dir}/tensorflow/python/eager/pywrap_tfe.h" 475 "${tensorflow_source_dir}/tensorflow/python/eager/pywrap_tensor.cc" 476 "${tensorflow_source_dir}/tensorflow/python/eager/pywrap_tfe_src.cc" 477 "${tensorflow_source_dir}/tensorflow/python/client/tf_session_helper.h" 478 "${tensorflow_source_dir}/tensorflow/python/client/tf_session_helper.cc" 479 "${tensorflow_source_dir}/tensorflow/python/framework/cpp_shape_inference.h" 480 "${tensorflow_source_dir}/tensorflow/python/framework/cpp_shape_inference.cc" 481 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen.h" 482 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen.cc" 483 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen_internal.h" 484 "${tensorflow_source_dir}/tensorflow/python/framework/python_op_gen_internal.cc" 485 "${tensorflow_source_dir}/tensorflow/python/lib/core/bfloat16.h" 486 "${tensorflow_source_dir}/tensorflow/python/lib/core/bfloat16.cc" 487 "${tensorflow_source_dir}/tensorflow/python/lib/core/numpy.h" 488 "${tensorflow_source_dir}/tensorflow/python/lib/core/numpy.cc" 489 "${tensorflow_source_dir}/tensorflow/python/lib/core/ndarray_tensor.h" 490 "${tensorflow_source_dir}/tensorflow/python/lib/core/ndarray_tensor.cc" 491 "${tensorflow_source_dir}/tensorflow/python/lib/core/ndarray_tensor_bridge.h" 492 "${tensorflow_source_dir}/tensorflow/python/lib/core/ndarray_tensor_bridge.cc" 493 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_func.h" 494 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_func.cc" 495 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_exception_registry.h" 496 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_exception_registry.cc" 497 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_seq_tensor.h" 498 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_seq_tensor.cc" 499 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_util.h" 500 "${tensorflow_source_dir}/tensorflow/python/lib/core/py_util.cc" 501 "${tensorflow_source_dir}/tensorflow/python/lib/core/safe_ptr.h" 502 "${tensorflow_source_dir}/tensorflow/python/lib/core/safe_ptr.cc" 503 "${tensorflow_source_dir}/tensorflow/python/lib/io/py_record_reader.h" 504 "${tensorflow_source_dir}/tensorflow/python/lib/io/py_record_reader.cc" 505 "${tensorflow_source_dir}/tensorflow/python/lib/io/py_record_writer.h" 506 "${tensorflow_source_dir}/tensorflow/python/lib/io/py_record_writer.cc" 507 "${tensorflow_source_dir}/tensorflow/python/util/kernel_registry.h" 508 "${tensorflow_source_dir}/tensorflow/python/util/kernel_registry.cc" 509 "${tensorflow_source_dir}/tensorflow/python/util/util.h" 510 "${tensorflow_source_dir}/tensorflow/python/util/util.cc" 511 "${tensorflow_source_dir}/tensorflow/cc/framework/ops.cc" 512 "${tensorflow_source_dir}/tensorflow/cc/framework/scope.cc" 513 "${CMAKE_CURRENT_BINARY_DIR}/pywrap_tensorflow_internal.cc" 514) 515 516if(WIN32) 517 # Windows: build a static library with the same objects as tensorflow.dll. 518 # This can be used to build for a standalone exe and also helps us to 519 # find all symbols that need to be exported from the dll which is needed 520 # to provide the tensorflow c/c++ api in tensorflow.dll. 521 # From the static library we create the def file with all symbols that need to 522 # be exported from tensorflow.dll. Because there is a limit of 64K sybmols 523 # that can be exported, we filter the symbols with a python script to the namespaces 524 # we need. 525 # 526 add_library(pywrap_tensorflow_internal_static STATIC 527 ${pywrap_tensorflow_internal_src} 528 $<TARGET_OBJECTS:tf_c> 529 $<TARGET_OBJECTS:tf_c_eager> 530 $<TARGET_OBJECTS:tf_c_python_api> 531 $<TARGET_OBJECTS:tf_core_lib> 532 $<TARGET_OBJECTS:tf_core_cpu> 533 $<TARGET_OBJECTS:tf_core_framework> 534 $<TARGET_OBJECTS:tf_core_profiler> 535 $<TARGET_OBJECTS:tf_core_eager_runtime> 536 $<TARGET_OBJECTS:tf_cc> 537 $<TARGET_OBJECTS:tf_cc_ops> 538 $<TARGET_OBJECTS:tf_cc_while_loop> 539 $<TARGET_OBJECTS:tf_core_ops> 540 $<TARGET_OBJECTS:tf_core_direct_session> 541 $<TARGET_OBJECTS:tf_grappler> 542 $<TARGET_OBJECTS:tf_tools_transform_graph_lib> 543 $<$<BOOL:${tensorflow_ENABLE_GRPC_SUPPORT}>:$<TARGET_OBJECTS:tf_core_distributed_runtime>> 544 $<TARGET_OBJECTS:tf_core_kernels> 545 $<$<BOOL:${tensorflow_ENABLE_GPU}>:$<TARGET_OBJECTS:tf_core_kernels_cpu_only>> 546 $<$<BOOL:${tensorflow_ENABLE_GPU}>:$<TARGET_OBJECTS:tf_stream_executor>> 547 ) 548 549 target_include_directories(pywrap_tensorflow_internal_static PUBLIC 550 ${PYTHON_INCLUDE_DIR} 551 ${NUMPY_INCLUDE_DIR} 552 ) 553 #target_link_libraries(pywrap_tensorflow_internal_static 554 # tf_protos_cc 555 # tf_python_protos_cc 556 #) 557 add_dependencies(pywrap_tensorflow_internal_static tf_protos_cc tf_python_protos_cc) 558 set(pywrap_tensorflow_internal_static_dependencies 559 $<TARGET_FILE:pywrap_tensorflow_internal_static> 560 $<TARGET_FILE:tf_protos_cc> 561 $<TARGET_FILE:tf_python_protos_cc> 562 ${nsync_STATIC_LIBRARIES} 563 ) 564 565 if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") 566 set(pywrap_tensorflow_deffile "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/pywrap_tensorflow.def") 567 else() 568 set(pywrap_tensorflow_deffile "${CMAKE_CURRENT_BINARY_DIR}/pywrap_tensorflow.def") 569 endif() 570 set_source_files_properties(${pywrap_tensorflow_deffile} PROPERTIES GENERATED TRUE) 571 math(EXPR tensorflow_target_bitness "${CMAKE_SIZEOF_VOID_P}*8") 572 add_custom_command(TARGET pywrap_tensorflow_internal_static POST_BUILD 573 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tools/create_def_file.py 574 --input "${pywrap_tensorflow_internal_static_dependencies}" 575 --output "${pywrap_tensorflow_deffile}" 576 --target _pywrap_tensorflow_internal.pyd 577 --bitness "${tensorflow_target_bitness}" 578 BYPRODUCTS ${pywrap_tensorflow_deffile} # Required for Ninja 579 ) 580endif(WIN32) 581 582# pywrap_tensorflow_internal is a shared library containing all of the 583# TensorFlow runtime and the standard ops and kernels. These are installed into 584# tf_python/tensorflow/python/. 585add_library(pywrap_tensorflow_internal SHARED 586 ${pywrap_tensorflow_internal_src} 587 $<TARGET_OBJECTS:tf_c> 588 $<TARGET_OBJECTS:tf_c_eager> 589 $<TARGET_OBJECTS:tf_c_python_api> 590 $<TARGET_OBJECTS:tf_core_lib> 591 $<TARGET_OBJECTS:tf_core_cpu> 592 $<TARGET_OBJECTS:tf_core_framework> 593 $<TARGET_OBJECTS:tf_core_profiler> 594 $<TARGET_OBJECTS:tf_core_eager_runtime> 595 $<TARGET_OBJECTS:tf_cc> 596 $<TARGET_OBJECTS:tf_cc_ops> 597 $<TARGET_OBJECTS:tf_cc_while_loop> 598 $<TARGET_OBJECTS:tf_core_ops> 599 $<TARGET_OBJECTS:tf_core_direct_session> 600 $<TARGET_OBJECTS:tf_grappler> 601 $<TARGET_OBJECTS:tf_tools_transform_graph_lib> 602 $<$<BOOL:${tensorflow_ENABLE_GRPC_SUPPORT}>:$<TARGET_OBJECTS:tf_core_distributed_runtime>> 603 $<TARGET_OBJECTS:tf_core_kernels> 604 $<$<BOOL:${tensorflow_ENABLE_GPU}>:$<$<BOOL:${BOOL_WIN32}>:$<TARGET_OBJECTS:tf_core_kernels_cpu_only>>> 605 $<$<BOOL:${tensorflow_ENABLE_GPU}>:$<TARGET_OBJECTS:tf_stream_executor>> 606 ${pywrap_tensorflow_deffile} 607) 608 609# There is a bug in GCC 5 resulting in undefined reference to a __cpu_model function when 610# linking to the tensorflow library. Adding the following libraries fixes it. 611if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0) 612 target_link_libraries(pywrap_tensorflow_internal PRIVATE gcc_s gcc) 613endif() 614 615if(WIN32) 616 add_dependencies(pywrap_tensorflow_internal pywrap_tensorflow_internal_static) 617endif(WIN32) 618 619target_include_directories(pywrap_tensorflow_internal PUBLIC 620 ${PYTHON_INCLUDE_DIR} 621 ${NUMPY_INCLUDE_DIR} 622) 623 624if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0) 625 # There is a bug in GCC 5 resulting in undefined reference to a __cpu_model function when 626 # linking to the tensorflow library. Adding the following libraries fixes it. 627 # See issue on github: https://github.com/tensorflow/tensorflow/issues/9593 628 target_link_libraries(pywrap_tensorflow_internal PRIVATE 629 ${tf_core_gpu_kernels_lib} 630 ${tensorflow_EXTERNAL_LIBRARIES} 631 tf_protos_cc 632 tf_python_protos_cc 633 ${PYTHON_LIBRARIES} 634 gcc_s 635 gcc 636) 637else() 638 target_link_libraries(pywrap_tensorflow_internal PRIVATE 639 ${tf_core_gpu_kernels_lib} 640 ${tensorflow_EXTERNAL_LIBRARIES} 641 tf_protos_cc 642 tf_python_protos_cc 643 ${PYTHON_LIBRARIES} 644) 645endif() 646 647if(WIN32) 648 649 # include contrib/periodic_resample as .so 650 # 651 set(tf_periodic_resample_srcs 652 "${tensorflow_source_dir}/tensorflow/contrib/periodic_resample/kernels/periodic_resample_op.cc" 653 "${tensorflow_source_dir}/tensorflow/contrib/periodic_resample/kernels/periodic_resample_op.h" 654 "${tensorflow_source_dir}/tensorflow/contrib/periodic_resample/ops/array_ops.cc" 655 ) 656 657 AddUserOps(TARGET _periodic_resample_op 658 SOURCES "${tf_periodic_resample_srcs}" 659 DEPENDS pywrap_tensorflow_internal tf_python_ops 660 DISTCOPY ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/periodic_resample/python/ops/) 661 662 # include contrib/nearest_neighbor as .so 663 # 664 set(tf_nearest_neighbor_srcs 665 "${tensorflow_source_dir}/tensorflow/contrib/nearest_neighbor/kernels/heap.h" 666 "${tensorflow_source_dir}/tensorflow/contrib/nearest_neighbor/kernels/hyperplane_lsh_probes.h" 667 "${tensorflow_source_dir}/tensorflow/contrib/nearest_neighbor/kernels/hyperplane_lsh_probes.cc" 668 "${tensorflow_source_dir}/tensorflow/contrib/nearest_neighbor/ops/nearest_neighbor_ops.cc" 669 ) 670 671 AddUserOps(TARGET _nearest_neighbor_ops 672 SOURCES "${tf_nearest_neighbor_srcs}" 673 DEPENDS pywrap_tensorflow_internal tf_python_ops 674 DISTCOPY ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/nearest_neighbor/python/ops/) 675endif(WIN32) 676 677if(WIN32) 678 # include contrib/rnn as .so 679 # 680 set(tf_gru_srcs 681 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/blas_gemm.cc" 682 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/blas_gemm.h" 683 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/gru_ops.cc" 684 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/gru_ops.h" 685 "${tensorflow_source_dir}/tensorflow/contrib/rnn/ops/gru_ops.cc" 686 ) 687 set(tf_gru_gpu_srcs 688 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/gru_ops_gpu.cu.cc" 689 ) 690 691 set(tf_lstm_srcs 692 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/blas_gemm.cc" 693 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/blas_gemm.h" 694 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/lstm_ops.cc" 695 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/lstm_ops.h" 696 "${tensorflow_source_dir}/tensorflow/contrib/rnn/ops/lstm_ops.cc" 697 ) 698 set(tf_lstm_gpu_srcs 699 "${tensorflow_source_dir}/tensorflow/contrib/rnn/kernels/lstm_ops_gpu.cu.cc" 700 ) 701 702 AddUserOps(TARGET _gru_ops 703 SOURCES "${tf_gru_srcs}" 704 GPUSOURCES ${tf_gru_gpu_srcs} 705 DEPENDS pywrap_tensorflow_internal tf_python_ops 706 DISTCOPY ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/rnn/python/ops/) 707 708 AddUserOps(TARGET _lstm_ops 709 SOURCES "${tf_lstm_srcs}" 710 GPUSOURCES ${tf_lstm_gpu_srcs} 711 DEPENDS pywrap_tensorflow_internal tf_python_ops 712 DISTCOPY ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/rnn/python/ops/) 713endif(WIN32) 714 715# include contrib/seq2seq as .so 716# 717set(tf_beam_search_srcs 718 "${tensorflow_source_dir}/tensorflow/contrib/seq2seq/kernels/beam_search_ops.cc" 719 "${tensorflow_source_dir}/tensorflow/contrib/seq2seq/kernels/beam_search_ops.h" 720 "${tensorflow_source_dir}/tensorflow/contrib/seq2seq/ops/beam_search_ops.cc" 721) 722 723set(tf_beam_search_gpu_srcs 724 "${tensorflow_source_dir}/tensorflow/contrib/seq2seq/kernels/beam_search_ops_gpu.cu.cc" 725) 726 727AddUserOps(TARGET _beam_search_ops 728 SOURCES "${tf_beam_search_srcs}" 729 GPUSOURCES ${tf_beam_search_gpu_srcs} 730 DEPENDS pywrap_tensorflow_internal tf_python_ops 731 DISTCOPY ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/seq2seq/python/ops/) 732 733if(WIN32) 734 if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") 735 add_custom_command(TARGET pywrap_tensorflow_internal POST_BUILD 736 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/$(Configuration)/pywrap_tensorflow_internal.dll 737 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/_pywrap_tensorflow_internal.pyd 738 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/$(Configuration)/pywrap_tensorflow_internal.lib 739 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/) 740 else() 741 add_custom_command(TARGET pywrap_tensorflow_internal POST_BUILD 742 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/pywrap_tensorflow_internal.dll 743 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/_pywrap_tensorflow_internal.pyd 744 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/pywrap_tensorflow_internal.lib 745 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/) 746 endif() 747else() 748 add_custom_command(TARGET pywrap_tensorflow_internal POST_BUILD 749 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/libpywrap_tensorflow_internal${CMAKE_SHARED_LIBRARY_SUFFIX} 750 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/_pywrap_tensorflow_internal.so) 751endif() 752 753 754######################################################## 755# Generate API __init__.py files. 756######################################################## 757 758# Parse tensorflow/python/tools/api/generator/BUILD to get list of generated files. 759FILE(READ ${tensorflow_source_dir}/tensorflow/python/tools/api/generator/api_init_files.bzl api_generator_BUILD_text) 760STRING(REGEX MATCH "# BEGIN GENERATED FILES.*# END GENERATED FILES" api_init_files_text ${api_generator_BUILD_text}) 761string(REPLACE "# BEGIN GENERATED FILES" "" api_init_files_text ${api_init_files_text}) 762string(REPLACE "# END GENERATED FILES" "" api_init_files_text ${api_init_files_text}) 763string(REPLACE "," ";" api_init_files_list ${api_init_files_text}) 764 765set(api_init_files "") 766foreach(api_init_file ${api_init_files_list}) 767 string(STRIP "${api_init_file}" api_init_file) 768 if(api_init_file) 769 string(REPLACE "\"" "" api_init_file "${api_init_file}") # Remove quotes 770 list(APPEND api_init_files "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/${api_init_file}") 771 endif() 772endforeach(api_init_file) 773set(api_init_list_file "${tensorflow_source_dir}/api_init_files_list.txt") 774file(WRITE "${api_init_list_file}" "${api_init_files}") 775 776# Run create_python_api.py to generate __init__.py files. 777 778### TODO 779# In order to download and compile MKL/MKL-DNN automatically in cmake script, mkl-built libraries should be added to system path 780# to be loaded by python executor. However `add_custom_command` has an issue with `COMMAND ${CMAKE_COMMAND} -E env PATH=`, where 781# arguments of multiple paths (such as D:/;D:/mkl) will be parsed in to seperate string without semicolon and that command fail to 782# recongnize paths. As CUDA isn't built with MKL, the MKL built directory is the only path to this command to work around that issue. 783# To not override the CUDA and system path in other circumstances, `if-else` branch used here to handle this problem, 784# and should be removed if the path issue can be resolved. 785# UPDATE: Below block appears to handle multiple items in PATH correctly, but risks command line limits if PATH is large. 786# If you have issues, try `set(PY_RUNTIME_ENV "PATH=${mkl_BIN_DIRS}")` instead. 787### 788 789set(PY_RUNTIME_ENV "") 790if(tensorflow_ENABLE_MKL_SUPPORT) 791 # add mkl dist dlls to system path for python 792 file(TO_CMAKE_PATH "$ENV{PATH}" PY_RUNTIME_ENV) 793 set(PY_RUNTIME_ENV ${mkl_BIN_DIRS} ${PY_RUNTIME_ENV}) 794 file(TO_NATIVE_PATH "${PY_RUNTIME_ENV}" PY_RUNTIME_ENV) 795 set(PY_RUNTIME_ENV "PATH=${PY_RUNTIME_ENV}") 796endif(tensorflow_ENABLE_MKL_SUPPORT) 797 798add_custom_command( 799 OUTPUT ${api_init_files} 800 DEPENDS tf_python_ops tf_python_copy_scripts_to_destination pywrap_tensorflow_internal tf_python_touchup_modules tf_extension_ops 801 802 # tensorflow/__init__.py depends on files generated in this step. So, remove it while 803 # this step is running since the files aren't there yet. 804 COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/__init__.py 805 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/__init__.py 806 807 # Run create_python_api.py to generate API init files. 808 COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/tf_python "${PY_RUNTIME_ENV}" ${PYTHON_EXECUTABLE} 809 "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/tools/api/generator/create_python_api.py" 810 "--root_init_template=${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/api_template.__init__.py" 811 "--apidir=${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow" 812 "--package=tensorflow.python" 813 "--apiname=tensorflow" 814 "${api_init_list_file}" 815 816 COMMENT "Generating __init__.py files for Python API." 817 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tf_python" 818 VERBATIM 819) 820 821add_custom_target(tf_python_api SOURCES ${api_init_files}) 822add_dependencies(tf_python_api tf_python_ops) 823 824# TODO(mikecase): This can be removed once tf.estimator is moved 825# out of TensorFlow. 826######################################################## 827# Generate API __init__.py files for tf.estimator. 828######################################################## 829 830# Parse tensorflow/python/tools/api/generator/BUILD to get list of generated files. 831FILE(READ ${tensorflow_source_dir}/tensorflow/python/tools/api/generator/api_init_files.bzl api_generator_BUILD_text) 832STRING(REGEX MATCH "# BEGIN GENERATED FILES.*# END GENERATED FILES" api_init_files_text ${api_generator_BUILD_text}) 833string(REPLACE "# BEGIN GENERATED FILES" "" api_init_files_text ${api_init_files_text}) 834string(REPLACE "# END GENERATED FILES" "" api_init_files_text ${api_init_files_text}) 835string(REPLACE "," ";" api_init_files_list ${api_init_files_text}) 836 837set(api_init_files "") 838foreach(api_init_file ${api_init_files_list}) 839 string(STRIP "${api_init_file}" api_init_file) 840 if(api_init_file) 841 string(REPLACE "\"" "" api_init_file "${api_init_file}") # Remove quotes 842 list(APPEND api_init_files "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/estimator/api/${api_init_file}") 843 endif() 844endforeach(api_init_file) 845set(estimator_api_init_list_file "${tensorflow_source_dir}/estimator_api_init_files_list.txt") 846file(WRITE "${estimator_api_init_list_file}" "${api_init_files}") 847 848# Run create_python_api.py to generate __init__.py files. 849add_custom_command( 850 OUTPUT ${api_init_files} 851 DEPENDS tf_python_ops tf_python_copy_scripts_to_destination pywrap_tensorflow_internal tf_python_touchup_modules tf_extension_ops 852 853 # Run create_python_api.py to generate API init files. 854 COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/tf_python "${PY_RUNTIME_ENV}" ${PYTHON_EXECUTABLE} 855 "${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/tools/api/generator/create_python_api.py" 856 "--apidir=${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/python/estimator/api" 857 "--package=tensorflow.python.estimator" 858 "--apiname=estimator" 859 "--output_package=tensorflow.python.estimator.api" 860 "${estimator_api_init_list_file}" 861 862 COMMENT "Generating __init__.py files for Python API." 863 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tf_python" 864) 865 866add_custom_target(estimator_python_api SOURCES ${api_init_files}) 867add_dependencies(estimator_python_api tf_python_ops) 868############################################################ 869# Build a PIP package containing the TensorFlow runtime. 870############################################################ 871add_custom_target(tf_python_build_pip_package) 872add_dependencies(tf_python_build_pip_package 873 pywrap_tensorflow_internal 874 tf_python_copy_scripts_to_destination 875 tf_python_touchup_modules 876 tf_python_ops 877 tf_python_api 878 estimator_python_api 879 tf_extension_ops) 880 881# Fix-up Python files that were not included by the add_python_module() macros. 882add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 883 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/tools/pip_package/setup.py 884 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/) 885# This file is unfortunately excluded by the regex that excludes *_test.py 886# files, but it is imported into tf.contrib, so we add it explicitly. 887add_custom_command(TARGET tf_python_copy_scripts_to_destination PRE_BUILD 888 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/contrib/testing/python/framework/util_test.py 889 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/testing/python/framework/) 890add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 891 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/tools/pip_package/README 892 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/) 893add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 894 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/tools/pip_package/MANIFEST.in 895 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/) 896 897# Copy datasets for tf.contrib.learn. 898add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 899 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/contrib/learn/python/learn/datasets/data/boston_house_prices.csv 900 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/learn/python/learn/datasets/data/) 901add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 902 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/contrib/learn/python/learn/datasets/data/iris.csv 903 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/learn/python/learn/datasets/data/) 904add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 905 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/contrib/learn/python/learn/datasets/data/text_test.csv 906 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/learn/python/learn/datasets/data/) 907add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 908 COMMAND ${CMAKE_COMMAND} -E copy ${tensorflow_source_dir}/tensorflow/contrib/learn/python/learn/datasets/data/text_train.csv 909 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/contrib/learn/python/learn/datasets/data/) 910 911# Create include header directory 912add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 913 COMMAND ${CMAKE_COMMAND} -E make_directory 914 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/) 915 916# tensorflow headers 917add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 918 COMMAND ${CMAKE_COMMAND} -E make_directory 919 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/tensorflow) 920add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 921 COMMAND ${CMAKE_COMMAND} -E make_directory 922 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/tensorflow/core) 923add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 924 COMMAND ${CMAKE_COMMAND} -E make_directory 925 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/tensorflow/stream_executor) 926add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 927 COMMAND ${CMAKE_COMMAND} -E copy_directory ${tensorflow_source_dir}/tensorflow/core 928 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/tensorflow/core) 929add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 930 COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/tensorflow/core 931 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/tensorflow/core) 932add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 933 COMMAND ${CMAKE_COMMAND} -E copy_directory ${tensorflow_source_dir}/tensorflow/stream_executor 934 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/tensorflow/stream_executor) 935 936# google protobuf headers 937add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 938 COMMAND ${CMAKE_COMMAND} -E make_directory 939 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/google) 940add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 941 COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/protobuf/src/protobuf/src/google 942 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/google) 943 944# Eigen directory 945add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 946 COMMAND ${CMAKE_COMMAND} -E make_directory 947 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/Eigen) 948add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 949 COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/eigen/src/eigen/Eigen 950 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/Eigen) 951 952# external directory 953add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 954 COMMAND ${CMAKE_COMMAND} -E make_directory 955 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/external) 956add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 957 COMMAND ${CMAKE_COMMAND} -E make_directory 958 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/external/eigen_archive) 959add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 960 COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/external/eigen_archive 961 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/external/eigen_archive) 962 963# third_party eigen directory 964add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 965 COMMAND ${CMAKE_COMMAND} -E make_directory 966 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/third_party) 967add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 968 COMMAND ${CMAKE_COMMAND} -E make_directory 969 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/third_party/eigen3) 970add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 971 COMMAND ${CMAKE_COMMAND} -E copy_directory ${tensorflow_source_dir}/third_party/eigen3 972 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/third_party/eigen3) 973 974# unsupported Eigen directory 975add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 976 COMMAND ${CMAKE_COMMAND} -E make_directory 977 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/unsupported) 978add_custom_command(TARGET tf_python_build_pip_package PRE_BUILD 979 COMMAND ${CMAKE_COMMAND} -E make_directory 980 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/unsupported/Eigen) 981add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 982 COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/eigen/src/eigen/unsupported/Eigen 983 ${CMAKE_CURRENT_BINARY_DIR}/tf_python/tensorflow/include/unsupported/Eigen) 984 985if(${tensorflow_TF_NIGHTLY}) 986 if(${tensorflow_ENABLE_GPU}) 987 add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 988 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/tf_python/setup.py bdist_wheel --project_name tf_nightly_gpu 989 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tf_python) 990 else() 991 add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 992 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/tf_python/setup.py bdist_wheel --project_name tf_nightly 993 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tf_python) 994 endif(${tensorflow_ENABLE_GPU}) 995else() 996 if(${tensorflow_ENABLE_GPU}) 997 add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 998 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/tf_python/setup.py bdist_wheel --project_name tensorflow_gpu 999 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tf_python) 1000 else() 1001 add_custom_command(TARGET tf_python_build_pip_package POST_BUILD 1002 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/tf_python/setup.py bdist_wheel 1003 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tf_python) 1004 endif(${tensorflow_ENABLE_GPU}) 1005endif(${tensorflow_TF_NIGHTLY}) 1006