<commit_before>import os
import re
import sys
import platform

from qisys import ui
import qisys.command
import qisys.sh
import qibuild.cmake
import qibuild.build
import qibuild.gdb
import qibuild.dylibs
import qibuild.dlls
import qitoolchain.toolchain

class BuildProject(object):
    def __init__(self, build_worktree, worktree_project):
        self.build_worktree = build_worktree
        self.build_config = build_worktree.build_config
        self.path = worktree_project.path
        self.src = worktree_project.src
        self.name = None
        # depends is a set at this point because they are not sorted yet
        self.depends = set()
        self.rdepends = set()

    @property
    def qiproject_xml(self):
        """ Path to qiproject.xml """
        return os.path.join(self.path, "qiproject.xml")


    @property
    def build_directory(self):
        """ Return a suitable build directory, depending on the
        build setting of the worktree: the name of the toolchain,
        the build profiles, and the build type (debug/release)

        """
        parts = ["build"]
        toolchain = self.build_config.toolchain
        build_type = self.build_config.build_type
        visual_studio = self.build_config.using_visual_studio
        if toolchain:
            parts.append(toolchain.name)
        else:
            parts.append("sys-%s-%s" % (platform.system().lower(),
                                        platform.machine().lower()))
        profiles = self.build_config.profiles
        for profile in profiles:
            parts.append(profile)

        # When using cmake + visual studio, sharing the same build dir with
        # several build config is mandatory.
        # Otherwise, it's not a good idea, so we always specify it
        # when it's not "Debug" (the default)
        if not visual_studio:
            if build_type and build_type != "Debug":
                parts.append(build_type.lower())

        # FIXME: handle custom build dir
        return os.path.join(self.path, "-".join(parts))

    @property
    def cmake_cache(self):
        return os.path.join(self.build_directory, "CMakeCache.txt")

    @property
    def cmake_args(self):
        """ The list of CMake arguments to use when configuring the
        project.
        Delegates to build_config.cmake_args

        """
        return self.build_config.cmake_args

    @property
    def build_env(self):
        """ The environment to use when calling cmake or build commands

        """
        return self.build_config.build_env

    @property
    def sdk_directory(self):
        """ The sdk directory in the build directory """
        # TODO: handle unique sdk dir?
        return os.path.join(self.build_directory, "sdk")

    @property
    def cmake_generator(self):
        return self.build_config.cmake_generator

    @property
    def using_visual_studio(self):
        return self.build_config.using_visual_studio
    @property
    def using_make(self):
        return self.build_config.using_make

    def write_qi_path_conf(self, sdk_dirs):
        """ Write the <build>/sdk/share/qi/path.conf file. This file
        can be used for instance by qi::path::find() functions, to
        finf files from the dependencies' build directory

        """
        to_write = "# File autogenerated by qibuild configure based on\n"
        to_write += "# dependencies found in qiproject.xml\n"
        to_write += "\n"

        for sdk_dir in sdk_dirs:
            to_write += qisys.sh.to_posix_path(sdk_dir) + "\n"

        path_dconf = os.path.join(self.sdk_directory, "share", "qi")
        qisys.sh.mkdir(path_dconf, recursive=True)

        path_conf = os.path.join(path_dconf, "path.conf")
        with open(path_conf, "w") as fp:
            fp.write(to_write)

    def write_dependencies_cmake(self, sdk_dirs):
        """ Write the dependencies.cmake file. This will be read by
        qibuild-config.cmake to set CMAKE_FIND_ROOT_PATH and
        qibuild_DIR, so that just running `cmake ..` works

        """
        to_write = """
#############################################
#QIBUILD AUTOGENERATED FILE. DO NOT EDIT.
#############################################

# Add path to CMake framework path if necessary:
set(_qibuild_path "{cmake_qibuild_dir}")
list(FIND CMAKE_MODULE_PATH "${{_qibuild_path}}" _found)
if(_found STREQUAL "-1")
  # Prefer cmake files matching  current qibuild installation
  # over cmake files in the cross-toolchain
  list(INSERT CMAKE_MODULE_PATH 0 "${{_qibuild_path}}")


  # Uncomment this if you really need to use qibuild
  # cmake files from the cross-toolchain
  # list(APPEND CMAKE_MODULE_PATH "${{_qibuild_path}}")
endif()

# Dependencies:
{dep_to_add}

# Store CMAKE_MODULE_PATH and CMAKE_FIND_ROOT_PATH in cache:
set(CMAKE_MODULE_PATH ${{CMAKE_MODULE_PATH}} CACHE INTERNAL ""  FORCE)
set(CMAKE_FIND_ROOT_PATH ${{CMAKE_FIND_ROOT_PATH}} CACHE INTERNAL ""  FORCE)

{custom_cmake_code}
"""
        custom_cmake_code = ""
        if self.build_config.local_cmake:
            to_include = qisys.sh.to_posix_path(self.build_config.local_cmake)
            custom_cmake_code += 'include("%s")\n' % to_include

        cmake_qibuild_dir = qibuild.cmake.get_cmake_qibuild_dir()
        cmake_qibuild_dir = qisys.sh.to_posix_path(cmake_qibuild_dir)
        dep_to_add = ""
        for sdk_dir in sdk_dirs:

            dep_to_add += """
    list(FIND CMAKE_FIND_ROOT_PATH "{sdk_dir}" _found)
    if(_found STREQUAL "-1")
        list(INSERT CMAKE_FIND_ROOT_PATH 0 "{sdk_dir}")
    endif()
    """.format(sdk_dir=qisys.sh.to_posix_path(sdk_dir))

        to_write = to_write.format(
            cmake_qibuild_dir=cmake_qibuild_dir,
            dep_to_add=dep_to_add,
            custom_cmake_code=custom_cmake_code
        )

        qisys.sh.mkdir(self.build_directory, recursive=True)
        dep_cmake = os.path.join(self.build_directory, "dependencies.cmake")

        with open(dep_cmake, "w") as fp:
            fp.write(to_write)

    def configure(self, **kwargs):
        """ Delegate to :py:func:`qibuild.cmake.cmake` """
        # FIXME: done by write_dependencies_cmake
        qisys.sh.mkdir(self.build_directory, recursive=True)
        cmake_args = self.cmake_args
        # only required the first time, afterwards this setting is
        # written in the cache by dependencies.cmake
        cmake_qibuild_dir = qibuild.cmake.get_cmake_qibuild_dir()
        cmake_qibuild_dir = os.path.join(cmake_qibuild_dir, "qibuild")
        cmake_qibuild_dir = qisys.sh.to_posix_path(cmake_qibuild_dir)
        cmake_args.append("-Dqibuild_DIR=%s" % cmake_qibuild_dir)

        qibuild.cmake.cmake(self.path, self.build_directory,
                            cmake_args, env=self.build_env, **kwargs)


    def build(self, num_jobs=1, rebuild=False, target=None,
              verbose_make=False, coverity=False, env=None):
        """ Build the project """
        timer = ui.timer("make %s" % self.name)
        timer.start()
        build_type = self.build_config.build_type

        cmd = []
        if coverity:<commit_msg>qibuild: do not rewrite dependencies.cmake if identical<commit_after>import os
import re
import sys
import platform

from qisys import ui
import qisys.command
import qisys.sh
import qibuild.cmake
import qibuild.build
import qibuild.gdb
import qibuild.dylibs
import qibuild.dlls
import qitoolchain.toolchain

class BuildProject(object):
    def __init__(self, build_worktree, worktree_project):
        self.build_worktree = build_worktree
        self.build_config = build_worktree.build_config
        self.path = worktree_project.path
        self.src = worktree_project.src
        self.name = None
        # depends is a set at this point because they are not sorted yet
        self.depends = set()
        self.rdepends = set()

    @property
    def qiproject_xml(self):
        """ Path to qiproject.xml """
        return os.path.join(self.path, "qiproject.xml")


    @property
    def build_directory(self):
        """ Return a suitable build directory, depending on the
        build setting of the worktree: the name of the toolchain,
        the build profiles, and the build type (debug/release)

        """
        parts = ["build"]
        toolchain = self.build_config.toolchain
        build_type = self.build_config.build_type
        visual_studio = self.build_config.using_visual_studio
        if toolchain:
            parts.append(toolchain.name)
        else:
            parts.append("sys-%s-%s" % (platform.system().lower(),
                                        platform.machine().lower()))
        profiles = self.build_config.profiles
        for profile in profiles:
            parts.append(profile)

        # When using cmake + visual studio, sharing the same build dir with
        # several build config is mandatory.
        # Otherwise, it's not a good idea, so we always specify it
        # when it's not "Debug" (the default)
        if not visual_studio:
            if build_type and build_type != "Debug":
                parts.append(build_type.lower())

        # FIXME: handle custom build dir
        return os.path.join(self.path, "-".join(parts))

    @property
    def cmake_cache(self):
        return os.path.join(self.build_directory, "CMakeCache.txt")

    @property
    def cmake_args(self):
        """ The list of CMake arguments to use when configuring the
        project.
        Delegates to build_config.cmake_args

        """
        return self.build_config.cmake_args

    @property
    def build_env(self):
        """ The environment to use when calling cmake or build commands

        """
        return self.build_config.build_env

    @property
    def sdk_directory(self):
        """ The sdk directory in the build directory """
        # TODO: handle unique sdk dir?
        return os.path.join(self.build_directory, "sdk")

    @property
    def cmake_generator(self):
        return self.build_config.cmake_generator

    @property
    def using_visual_studio(self):
        return self.build_config.using_visual_studio
    @property
    def using_make(self):
        return self.build_config.using_make

    def write_qi_path_conf(self, sdk_dirs):
        """ Write the <build>/sdk/share/qi/path.conf file. This file
        can be used for instance by qi::path::find() functions, to
        finf files from the dependencies' build directory

        """
        to_write = "# File autogenerated by qibuild configure based on\n"
        to_write += "# dependencies found in qiproject.xml\n"
        to_write += "\n"

        for sdk_dir in sdk_dirs:
            to_write += qisys.sh.to_posix_path(sdk_dir) + "\n"

        path_dconf = os.path.join(self.sdk_directory, "share", "qi")
        qisys.sh.mkdir(path_dconf, recursive=True)

        path_conf = os.path.join(path_dconf, "path.conf")
        with open(path_conf, "w") as fp:
            fp.write(to_write)

    def write_dependencies_cmake(self, sdk_dirs):
        """ Write the dependencies.cmake file. This will be read by
        qibuild-config.cmake to set CMAKE_FIND_ROOT_PATH and
        qibuild_DIR, so that just running `cmake ..` works

        """
        to_write = """
#############################################
#QIBUILD AUTOGENERATED FILE. DO NOT EDIT.
#############################################

# Add path to CMake framework path if necessary:
set(_qibuild_path "{cmake_qibuild_dir}")
list(FIND CMAKE_MODULE_PATH "${{_qibuild_path}}" _found)
if(_found STREQUAL "-1")
  # Prefer cmake files matching  current qibuild installation
  # over cmake files in the cross-toolchain
  list(INSERT CMAKE_MODULE_PATH 0 "${{_qibuild_path}}")


  # Uncomment this if you really need to use qibuild
  # cmake files from the cross-toolchain
  # list(APPEND CMAKE_MODULE_PATH "${{_qibuild_path}}")
endif()

# Dependencies:
{dep_to_add}

# Store CMAKE_MODULE_PATH and CMAKE_FIND_ROOT_PATH in cache:
set(CMAKE_MODULE_PATH ${{CMAKE_MODULE_PATH}} CACHE INTERNAL ""  FORCE)
set(CMAKE_FIND_ROOT_PATH ${{CMAKE_FIND_ROOT_PATH}} CACHE INTERNAL ""  FORCE)

{custom_cmake_code}
"""
        custom_cmake_code = ""
        if self.build_config.local_cmake:
            to_include = qisys.sh.to_posix_path(self.build_config.local_cmake)
            custom_cmake_code += 'include("%s")\n' % to_include

        cmake_qibuild_dir = qibuild.cmake.get_cmake_qibuild_dir()
        cmake_qibuild_dir = qisys.sh.to_posix_path(cmake_qibuild_dir)
        dep_to_add = ""
        for sdk_dir in sdk_dirs:

            dep_to_add += """
    list(FIND CMAKE_FIND_ROOT_PATH "{sdk_dir}" _found)
    if(_found STREQUAL "-1")
        list(INSERT CMAKE_FIND_ROOT_PATH 0 "{sdk_dir}")
    endif()
    """.format(sdk_dir=qisys.sh.to_posix_path(sdk_dir))

        to_write = to_write.format(
            cmake_qibuild_dir=cmake_qibuild_dir,
            dep_to_add=dep_to_add,
            custom_cmake_code=custom_cmake_code
        )

        qisys.sh.mkdir(self.build_directory, recursive=True)
        dep_cmake = os.path.join(self.build_directory, "dependencies.cmake")
        qisys.sh.write_file_if_different(to_write, dep_cmake)

    def configure(self, **kwargs):
        """ Delegate to :py:func:`qibuild.cmake.cmake` """
        # FIXME: done by write_dependencies_cmake
        qisys.sh.mkdir(self.build_directory, recursive=True)
        cmake_args = self.cmake_args
        # only required the first time, afterwards this setting is
        # written in the cache by dependencies.cmake
        cmake_qibuild_dir = qibuild.cmake.get_cmake_qibuild_dir()
        cmake_qibuild_dir = os.path.join(cmake_qibuild_dir, "qibuild")
        cmake_qibuild_dir = qisys.sh.to_posix_path(cmake_qibuild_dir)
        cmake_args.append("-Dqibuild_DIR=%s" % cmake_qibuild_dir)

        qibuild.cmake.cmake(self.path, self.build_directory,
                            cmake_args, env=self.build_env, **kwargs)


    def build(self, num_jobs=1, rebuild=False, target=None,
              verbose_make=False, coverity=False, env=None):
        """ Build the project """
        timer = ui.timer("make %s" % self.name)
        timer.start()
        build_type = self.build_config.build_type

        cmd = []
        if coverity:
{'fraction_non_alphanumeric': 0.10612130156722187, 'fraction_numerical': 0.0007027900766041184, 'mean_word_length': 2.7585842577918647, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '631371', 'n_tokens_mistral': 4641, 'n_tokens_neox': 4479, 'n_words': 1039}