Skip to content
Snippets Groups Projects
Select Git revision
  • c98cde4a6711845c9929f1773c66794adeca20de
  • master default protected
  • main
  • test-refactor-server-json
  • blender-v4.1-release
  • blender-v4.0-release
  • blender-v3.6-release
  • blender-v3.3-release
  • blender-v2.93-release
  • blender-v3.5-release
  • blender-v3.1-release
  • blender-v3.0-release
  • blender-v3.4-release
  • blender-v3.2-release
  • studio-sprite-fright
  • blender-v2.92-release
  • blender-v2.91-release
  • greasepencil-addon
  • blender-v2.90-release
  • blender-v2.83-release
  • blender-v2.82-release
  • v3.6.9
  • v3.3.16
  • v4.1.0
  • v4.1.1
  • v3.6.8
  • v3.3.15
  • v3.6.7
  • v3.3.14
  • v4.0.2
  • v4.0.1
  • v4.0.0
  • v3.6.5
  • v3.3.12
  • v3.6.4
  • v3.6.3
  • v3.3.11
  • v3.6.2
  • v3.3.10
  • v3.6.1
  • v3.3.9
41 results

space_view3d_manipulator_Menu.py

Blame
  • cmake-flags 14.45 KiB
    #!/usr/bin/env python3
    # ##### BEGIN GPL LICENSE BLOCK #####
    #
    #  This program is free software; you can redistribute it and/or
    #  modify it under the terms of the GNU General Public License
    #  as published by the Free Software Foundation; either version 2
    #  of the License, or (at your option) any later version.
    #
    #  This program is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software Foundation,
    #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ##### END GPL LICENSE BLOCK #####
    
    """
    This tool is for configuring build flags.
    """
    
    WITH_GUI = True
    
    # ----------------------------------------------------------------------------
    # Data (flags)
    # eg: indervidual flags, compat info.
    
    
    # ----------------------------------------------------------------------------
    # Data (presets)
    # eg: profiling, mudflap, debugging.
    
    # setting: ((add, ...), (remove, ...)), ...
    PRESETS = {
        "sanitize_address": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=address",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=address",), ()),
            "CMAKE_EXE_LINKER_FLAGS": (("-lasan",), ()),
            },
        "sanitize_leak": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=leak",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=leak",), ()),
            },
        "sanitize_undefined": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=undefined",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=undefined",), ()),
            },
        "sanitize_thread": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=thread",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=thread",), ()),
            },
    
        # GCC5
        "sanitize_float_divide_by_zero": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=float-divide-by-zero",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=float-divide-by-zero",), ()),
            },
        "sanitize_float_cast_overflow": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=float-cast-overflow",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=float-cast-overflow",), ()),
            },
        "sanitize_int_overflow": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=signed-integer-overflow",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=signed-integer-overflow",), ()),
            },
        "sanitize_bool": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=bool",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=bool",), ()),
            },
        "sanitize_enun": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=enum",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=enum",), ()),
            },
        "sanitize_bounds": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=bounds",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=bounds",), ()),
            },
        "sanitize_bounds_strict": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=bounds-strict",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=bounds-strict",), ()),
            },
        "sanitize_vla_bounds": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=vla-bounds",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=vla-bounds",), ()),
            },
        "sanitize_alignment": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=alignment",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=alignment",), ()),
            },
        "sanitize_object_size": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=object-size",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=object-size",), ()),
            },
        "sanitize_nonull_attribute": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=nonnull-attribute",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=nonnull-attribute",), ()),
            },
        "sanitize_returns_nonull_attribute": {
            "CMAKE_CXX_FLAGS": (("-fsanitize=returns-nonnull-attribute",), ()),
            "CMAKE_C_FLAGS":   (("-fsanitize=returns-nonnull-attribute",), ()),
            },
    
        "warn_all": {
            "CMAKE_CXX_FLAGS": (("-Wall",), ()),
            "CMAKE_C_FLAGS":   (("-Wall",), ()),
            },
        "warn_extra": {
            "CMAKE_CXX_FLAGS": (("-Wextra",), ()),
            "CMAKE_C_FLAGS":   (("-Wextra",), ()),
            },
        "warn_unused_macros": {
            "CMAKE_CXX_FLAGS": (("-Wunused-macros",), ()),
            "CMAKE_C_FLAGS":   (("-Wunused-macros",), ()),
            },
        "warn_undefined_macros": {
            "CMAKE_CXX_FLAGS": (("-Wundef",), ()),
            "CMAKE_C_FLAGS":   (("-Wundef",), ()),
            },
        "warn_unused_local_typedefs": {
            "CMAKE_CXX_FLAGS": (("-Wunused-local-typedefs",), ()),
            "CMAKE_C_FLAGS":   (("-Wunused-local-typedefs",), ()),
            },
        "warn_pointer_sign": {
            "CMAKE_CXX_FLAGS": (("",), ()),
            "CMAKE_C_FLAGS":   (("-Wpointer-sign",), ()),
            },
        "warn_sizeof_pointer_memaccess": {
            "CMAKE_CXX_FLAGS": (("-Wsizeof-pointer-memaccess",), ()),
            "CMAKE_C_FLAGS":   (("-Wsizeof-pointer-memaccess",), ()),
            },
        "warn_no_null": {
            "CMAKE_CXX_FLAGS": (("-Wnonnull",), ()),
            "CMAKE_C_FLAGS":   (("-Wnonnull",), ()),
            },
        "warn_init_self": {
            "CMAKE_CXX_FLAGS": (("-Winit-self",), ()),
            "CMAKE_C_FLAGS":   (("-Winit-self",), ()),
            },
        "warn_format": {
            "CMAKE_CXX_FLAGS": (("-Wformat=2", "-Wno-format-nonliteral", "-Wno-format-y2k"), ()),
            "CMAKE_C_FLAGS":   (("-Wformat=2", "-Wno-format-nonliteral", "-Wno-format-y2k"), ()),
            },
        "warn_format": {
            "CMAKE_CXX_FLAGS": (("-Wwrite-strings",), ()),
            "CMAKE_C_FLAGS":   (("-Wwrite-strings",), ()),
            },
        "warn_logical_op": {
            "CMAKE_CXX_FLAGS": (("-Wlogical-op",), ()),
            "CMAKE_C_FLAGS":   (("-Wlogical-op",), ()),
            },
        "warn_error": {
            "CMAKE_CXX_FLAGS": (("-Werror",), ()),
            "CMAKE_C_FLAGS":   (("-Werror",), ()),
            },
        "warn_shadow": {
            "CMAKE_CXX_FLAGS": (("-Wshadow", "-Wno-error=shadow"), ()),
            "CMAKE_C_FLAGS":   (("-Wshadow", "-Wno-error=shadow"), ()),
            },
        "warn_missing_include_dirs": {
            "CMAKE_CXX_FLAGS": (("-Wmissing-include-dirs",), ()),
            "CMAKE_C_FLAGS":   (("-Wmissing-include-dirs",), ()),
            },
        "warn_double_promotion": {
            "CMAKE_CXX_FLAGS": (("-Wdouble-promotion",), ()),
            "CMAKE_C_FLAGS":   (("-Wdouble-promotion",), ()),
            },
        "warn_declaration_after_statement": {
            "CMAKE_C_FLAGS":   (("-Wdeclaration-after-statement",), ()),
            },
        "warn_zero_as_null_pointer_constant": {
            "CMAKE_CXX_FLAGS": (("-Wzero-as-null-pointer-constant",), ()),
            },
        "show_color": {
            "CMAKE_C_FLAGS": (("-fdiagnostics-color=always",), ()),
            "CMAKE_CXX_FLAGS": (("-fdiagnostics-color=always",), ()),
            },
    
        # Optimize
        "optimize_whole_program": {
            "CMAKE_CXX_FLAGS": (("-flto",), ()),
            "CMAKE_C_FLAGS":   (("-flto",), ()),
            "CMAKE_EXE_LINKER_FLAGS": (("-flto", "-fwhole-program",), ()),
            },
    }
    
    # ----------------------------------------------------------------------------
    # Utility Functions
    # eg: check buildsystem (make or ninja?)
    
    
    def cmake_flag_buildtype_suffix(flag, build_type):
        """
        Add the build type as a suffix for options that support it.
        this way for Debug builds we edit debug flags.
        eg:
          CMAKE_CXX_FLAGS -> CMAKE_CXX_FLAGS_DEBUG
        """
        if build_type == "":
            return flag
    
        # perhaps there are more,
        # but these are default that can have _DEBUG... etc added.
        if flag in {'CMAKE_CXX_FLAGS',
                    'CMAKE_C_FLAGS',
                    'CMAKE_EXE_LINKER_FLAGS',
                    'CMAKE_MODULE_LINKER_FLAGS',
                    'CMAKE_SHARED_LINKER_FLAGS'}:
    
            return "%s_%s" % (flag, build_type.upper())
        else:
            return flag
    
    
    # ----------------------------------------------------------------------------
    # CMakeCache.txt Parser (simple)
    #
    # These functions should run standalone
    # format in python is as follows...
    #
    # CMakeCache.txt is converted into a dict
    # the key is the cache ID
    # the value is a triple (type, value, description, internal)
    # where the discription is the comment above conforming to the CMake convention.
    #
    #
    def cmakecache_to_py(filepath, native=True):
        """
        header, cache
        """
    
        cmake_header = ""
        cmake_cache = {}
    
        with open(filepath, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            for i in range(len(lines)):
                if lines[i].startswith("#"):
                    cmake_header += lines[i]
                else:
                    break
    
            # incase its not set
            cmake_descr = ""
            cmake_internal = False
    
            for i in range(len(lines)):
                if lines[i].startswith("//"):
                    cmake_descr += lines[i][2:].rstrip() + "\n"
                elif lines[i].startswith("#"):
                    if "INTERNAL cache entries" in lines[i]:
                        cmake_internal = True
                elif lines[i][0].isalpha() or lines[i][0] in {"_", "-"}:
                    cmake_name, cmake_value = lines[i].split("=", 1)
                    if ":" in cmake_name:
                        cmake_name, cmake_type = cmake_name.split(":", 1)
                    else:
                        cmake_type = "STRING"
                    cmake_value = cmake_value.rstrip()  # remove trailing '\n'
                    cmake_descr = cmake_descr.rstrip()
    
                    if native:
                        if cmake_type in {"STRING", "PATH", "FILEPATH", "STATIC", "INTERNAL", "UNINITIALIZED"}:
                            pass
                        elif cmake_type == "BOOL":
                            cmake_value = cmake_value.upper() not in {"NO", "N", "", "OFF", "0", "FALSE"}
    
                    cmake_cache[cmake_name] = (cmake_type, cmake_value, cmake_descr, cmake_internal)
    
                    # incase its not set
                    cmake_descr = ""
    
        return cmake_header, cmake_cache
    
    
    def cmakecache_from_py(filepath, cmake_header, cmake_cache):
    
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write(cmake_header)
            f.write("\n")
    
            cmake_cache_list = ([], [])
    
            # sort into external/internal
            for cmake_name, (cmake_type, cmake_value, cmake_descr, cmake_internal) in cmake_cache.items():
                cmake_cache_list[cmake_internal].append((cmake_name, cmake_type, cmake_value, cmake_descr))
    
            for is_internal, ls in enumerate(cmake_cache_list):
                ls.sort()
                if is_internal:
                    f.write("########################\n"
                            "# INTERNAL cache entries\n"
                            "########################\n\n")
                else:
                    f.write("########################\n"
                            "# EXTERNAL cache entries\n"
                            "########################\n\n")
    
                for cmake_name, cmake_type, cmake_value, cmake_descr in ls:
                    if cmake_descr:
                        l = None
                        for l in cmake_descr.split("\n"):
                            f.write("//%s\n" % l)
                        del l
    
                    # convert the value
                    if cmake_value is True:
                        cmake_value = "TRUE"
                    elif cmake_value is False:
                        cmake_value = "FALSE"
    
                    f.write("%s:%s=%s\n" % (cmake_name, cmake_type, cmake_value))
                    if not is_internal:
                        f.write("\n")
    
    # cmake_header, cmake_cache = cmakecache_to_py("/src/cmake_debug/CMakeCache.txt~")
    # cmakecache_from_py("/src/cmake_debug/CMakeCache.txt", cmake_header, cmake_cache)
    # print(cmake_cache)
    
    
    # ----------------------------------------------------------------------------
    # Main Functions (can be run from command line)
    
    def config_set(config_id, state):
        print(config_id, state.get(), dir(state))
        cache = CMAKE_DATA["cmake_cache"]
        build_type = cache["CMAKE_BUILD_TYPE"][1]  # value
    
        cfg = PRESETS[config_id]
        for key, (add, rem) in cfg.items():
            key = cmake_flag_buildtype_suffix(key, build_type)
            (cmake_type, cmake_value, cmake_descr, cmake_internal) = cache[key]
            data = cmake_value.split()
            if not state.get():
                add, rem = rem, add
    
            for arg in rem:
                data[:] = [i for i in data if i != arg]
            data.extend(add)
    
            # print("A", data)
            cmake_value = " ".join(data)
            # print("B", cmake_value)
            cache[key] = (cmake_type, cmake_value, cmake_descr, cmake_internal)
            print("AFTER", cache[key])
    
    
    def config_check(config_id):
        cache = CMAKE_DATA["cmake_cache"]
        build_type = cache["CMAKE_BUILD_TYPE"][1]  # value
    
        cfg = PRESETS[config_id]
        for key, (add, rem) in cfg.items():
            key = cmake_flag_buildtype_suffix(key, build_type)
            (cmake_type, cmake_value, cmake_descr, cmake_internal) = cache[key]
            data = cmake_value.split()
            for arg in add:
                if arg not in data:
                    return False
        return True
    
    
    # ----------------------------------------------------------------------------
    # Command Line Interface
    
    # ----------------------------------------------------------------------------
    # User Interface
    if WITH_GUI:
        CMAKE_DATA = {}
        # CMAKE_CACHE = "/src/cmake_debugCMakeCache.txt"
        CMAKE_CACHE = "CMakeCache.txt"
    
        def cmake_read():
            print("%s: reading..." % CMAKE_CACHE)
            (CMAKE_DATA["cmake_header"],
             CMAKE_DATA["cmake_cache"],
             ) = cmakecache_to_py(CMAKE_CACHE)
    
        def cmake_write():
            print("%s: writing..." % CMAKE_CACHE)
            CMAKE_CACHE_TMP = CMAKE_CACHE + "~"
            cmakecache_from_py(CMAKE_CACHE_TMP,
                               CMAKE_DATA["cmake_header"],
                               CMAKE_DATA["cmake_cache"])
    
            import shutil
            shutil.move(CMAKE_CACHE_TMP, CMAKE_CACHE)
    
        # read before load.
        cmake_read()
    
        import tkinter
        master = tkinter.Tk()
    
        row = 0
        tkinter.Label(master, text="Flags:").grid(row=row, sticky=tkinter.W)
        row += 1
    
        def config_but(my_id):
            global row
            var = tkinter.IntVar()
            var.set(config_check(my_id))
            tkinter.Checkbutton(master,
                                text=my_id.replace("_", " ").capitalize(),
                                variable=var,
                                command=lambda: config_set(my_id, var)).grid(row=row, sticky=tkinter.W)
            row += 1
    
        for my_id in sorted(PRESETS.keys()):
            config_but(my_id)
    
        tkinter.Button(master, text='Write', command=cmake_write).grid(row=row, sticky=tkinter.W, pady=4)
        row += 1
        tkinter.Button(master, text='Quit', command=master.quit).grid(row=row, sticky=tkinter.W, pady=4)
        row += 1
        # tkinter.Button(master, text='Show', command=var_states).grid(row=4, sticky=tkinter.W, pady=4)
    
        tkinter.mainloop()
    
    # EOF