# Copyright 2022 The KerasCV Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== # Usage: python configure.py """Configures local environment to prepare for building KerasCV from source.""" import logging import os import pathlib import platform import tensorflow as tf from packaging.version import Version _TFA_BAZELRC = ".bazelrc" # Writes variables to bazelrc file def write(line): with open(_TFA_BAZELRC, "a") as f: f.write(line + "\n") def write_action_env(var_name, var): write('build --action_env {}="{}"'.format(var_name, var)) def is_macos(): return platform.system() == "Darwin" def is_windows(): return platform.system() == "Windows" def is_linux(): return platform.system() == "Linux" def is_raspi_arm(): return os.uname()[4] == "armv7l" or os.uname()[4] == "aarch64" def is_linux_ppc64le(): return is_linux() and platform.machine() == "ppc64le" def is_linux_x86_64(): return is_linux() and platform.machine() == "x86_64" def is_linux_arm(): return is_linux() and platform.machine() == "arm" def is_linux_aarch64(): return is_linux() and platform.machine() == "aarch64" def is_linux_s390x(): return is_linux() and platform.machine() == "s390x" def get_tf_header_dir(): import tensorflow as tf tf_header_dir = tf.sysconfig.get_compile_flags()[0][2:] if is_windows(): tf_header_dir = tf_header_dir.replace("\\", "/") return tf_header_dir def get_cpp_version(): cpp_version = "c++14" if Version(tf.__version__) >= Version("2.10"): cpp_version = "c++17" return cpp_version def get_tf_shared_lib_dir(): import tensorflow as tf # OS Specific parsing if is_windows(): tf_shared_lib_dir = tf.sysconfig.get_compile_flags()[0][2:-7] + "python" return tf_shared_lib_dir.replace("\\", "/") elif is_raspi_arm(): return tf.sysconfig.get_compile_flags()[0][2:-7] + "python" else: return tf.sysconfig.get_link_flags()[0][2:] # Converts the linkflag namespec to the full shared library name def get_shared_lib_name(): import tensorflow as tf namespec = tf.sysconfig.get_link_flags() if is_macos(): # MacOS return "lib" + namespec[1][2:] + ".dylib" elif is_windows(): # Windows return "_pywrap_tensorflow_internal.lib" elif is_raspi_arm(): # The below command for linux would return an empty list return "_pywrap_tensorflow_internal.so" else: # Linux return namespec[1][3:] def create_build_configuration(): print() print("Configuring KerasCV to be built from source...") if os.path.isfile(_TFA_BAZELRC): os.remove(_TFA_BAZELRC) logging.disable(logging.WARNING) write_action_env("TF_HEADER_DIR", get_tf_header_dir()) write_action_env("TF_SHARED_LIBRARY_DIR", get_tf_shared_lib_dir()) write_action_env("TF_SHARED_LIBRARY_NAME", get_shared_lib_name()) write_action_env("TF_CXX11_ABI_FLAG", tf.sysconfig.CXX11_ABI_FLAG) # This should be replaced with a call to tf.sysconfig if it's added write_action_env("TF_CPLUSPLUS_VER", get_cpp_version()) write("build --spawn_strategy=standalone") write("build --strategy=Genrule=standalone") write("build --experimental_repo_remote_exec") write("build -c opt") write( "build --cxxopt=" + '"-D_GLIBCXX_USE_CXX11_ABI="' + str(tf.sysconfig.CXX11_ABI_FLAG) ) if is_windows(): write("build --config=windows") write("build:windows --enable_runfiles") write("build:windows --copt=/experimental:preprocessor") write("build:windows --host_copt=/experimental:preprocessor") write("build:windows --copt=/arch=AVX") write("build:windows --cxxopt=/std:" + get_cpp_version()) write("build:windows --host_cxxopt=/std:" + get_cpp_version()) if is_macos() or is_linux(): if not is_linux_ppc64le() and not is_linux_arm() and not is_linux_aarch64(): write("build --copt=-mavx") write("build --cxxopt=-std=" + get_cpp_version()) write("build --host_cxxopt=-std=" + get_cpp_version()) print("> Building only CPU ops") print() print("Build configurations successfully written to", _TFA_BAZELRC, ":\n") print(pathlib.Path(_TFA_BAZELRC).read_text()) if __name__ == "__main__": create_build_configuration()