diff --git a/.github/workflows/static_analysis.yaml b/.github/workflows/static_analysis.yaml index b5840c5ab4..a811f1a0a9 100644 --- a/.github/workflows/static_analysis.yaml +++ b/.github/workflows/static_analysis.yaml @@ -194,3 +194,15 @@ jobs: echo "Error - The minimal CMake version required for LibRS is ${EXPECTED_CMAKE_MAJOR_VER}.${EXPECTED_CMAKE_MINOR_VER} but on this build the minimal CMake version that works is $CURRENT_CMAKE_MAJOR_VER.$CURRENT_CMAKE_MINOR_VER" exit 1 fi + + build_flags_docs: + name: "Generate build-flags.html" + timeout-minutes: 10 + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3 + + - name: Build docs + run: | + python3 scripts/lrs_options-to-html.py diff --git a/CMake/lrs_options.cmake b/CMake/lrs_options.cmake index 02ca70796b..94b25621ac 100644 --- a/CMake/lrs_options.cmake +++ b/CMake/lrs_options.cmake @@ -1,3 +1,9 @@ +## This file is also being used to generate our build flags document at https://intelrealsense.github.io/librealsense/build-flags-docs/build-flags.html +## Formatting notes for this file: +## Options are listed as: | [comment] | +## regular comments should be ABOVE their relevent option +## use double # for comments that should not show in the options doc + option(ENABLE_CCACHE "Build with ccache." ON) option(BUILD_WITH_CUDA "Enable CUDA" OFF) option(BUILD_GLSL_EXTENSIONS "Build GLSL extensions API" ON) diff --git a/doc/build-flags.css b/doc/build-flags.css new file mode 100644 index 0000000000..57e78b2593 --- /dev/null +++ b/doc/build-flags.css @@ -0,0 +1,91 @@ +/* This file is used in lrs_options-to-html, creating the html build-flags.html file we use to keep + the flags updated */ +body { + font-family: 'Roboto', Arial, sans-serif; + background-color: #f5f5f5; + margin: 0; + padding: 0; +} + +.container { + width: 80%; + margin: 0 auto; + padding: 30px; +} + +h1 { + text-align: center; + margin-bottom: 20px; +} + +h2 { + text-align: center; + margin-bottom: 30px; +} + +table { + width: 100%; + border-collapse: collapse; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); + border-radius: 8px; + overflow: visible; +} + +th, td { + padding: 16px; + text-align: left; + border: 1px solid #ddd; +} + +th { + background-color: #5873e0; + color: white; +} + +tr:hover { + background-color: #f0f0f0; +} + +code { + padding: 2px 4px; + border-radius: 4px; + font-family: 'Roboto Mono', monospace; +} +/* --- Tooltip --- */ +.tooltip { + position: relative; + display: block; +} + +.tooltip .tooltip-text { + visibility: hidden; + /*width: 120px;*/ + background-color: #555; + color: #fff; + text-align: center; + padding: 5%; + border-radius: 6px; + position: absolute; + z-index: 1; + bottom: 125%; + left: 50%; + margin-left: -60px; + opacity: 0; + transition: opacity 0.3s; +} + +.tooltip .tooltip-text::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: #555 transparent transparent transparent; +} + +.tooltip:hover .tooltip-text { + visibility: visible; + opacity: 1; +} diff --git a/doc/build-flags.ico b/doc/build-flags.ico new file mode 100644 index 0000000000..ff97f560e5 Binary files /dev/null and b/doc/build-flags.ico differ diff --git a/scripts/lrs_options-to-html.py b/scripts/lrs_options-to-html.py new file mode 100644 index 0000000000..03ff168f59 --- /dev/null +++ b/scripts/lrs_options-to-html.py @@ -0,0 +1,146 @@ +import sys + + +def add_style(option, val): + # colorize ON and OFF keywords + val = val.replace('ON', 'ON') + val = val.replace('OFF', 'OFF') + + # if more complicated conditions are being used, this can be disabled - + # if we see an option more than once at add_row, just set its value to be 'Environment dependant' + # this should handle if/elseif/else structures of cmake + if in_cond: + # text will say Environment dependant, and if hovered will show the condition + val = f'Environment dependant{val}
' + elif in_elseif: + # append condition to tooltip + val = table_rows[option][2].replace("
", f',
{val}
') + + elif in_else: + # append otherwise to tooltip + val = table_rows[option][2].replace("
", f',
{val} otherwise') + + return val + + +def add_row(option, description, value): + if option in table_rows: + # update value if option exists + table_rows[option][2] = value + else: + # add to table new option + table_rows[option] = [option, description, value] + + +with open('CMake/lrs_options.cmake', 'r') as file: + lines = file.readlines() + +table_rows = {} +in_cond = False +in_elseif = False +in_else = False +current_condition = None +current_comment = "" + +for i, line in enumerate(lines): + if line.strip().startswith(('option(', 'set(')): + line = ' '.join(line.split()) # remove consecutive spaces + parts = line.strip().split(' ') + if line.strip().startswith('option('): + option = parts[0].strip('option(') + value = parts[-1].strip(")") # the last word in line is the value (ON/OFF by default) + + # concatenate rest of the line - expected to be just the description in quotes + description = ' '.join(parts[1:-1]).strip('"') + else: + option = parts[0].strip('set(') + value = parts[1] + value = f'{value}' + # parts[2] is expected to be 'CACHE' + vartype = parts[3] # INT, STRING ... + + # concatenate rest of the line - expected to be just the description in quotes + description = ' '.join(parts[4:-1]).strip('"') + f" (type {vartype})" + + if current_comment: + description += " " + current_comment + "" + current_comment = "" + + if in_cond or in_elseif: + value = f'{value} if {current_condition}' + + value = add_style(option, value) + add_row(option, description, value) + elif line.startswith('if'): + parts = line.strip().split('(', 1) + condition = parts[1][:-1] # remove last ")" - part of the 'if' + current_condition = condition + in_cond = True + elif line.startswith('elseif'): + parts = line.strip().split('(', 1) + condition = parts[1][:-1] # remove last ")" - part of the 'if' + current_condition = condition + in_cond = False + in_elseif = True + elif line.startswith('else'): + in_cond = False + in_elseif = False + in_else = True + elif line.startswith('endif'): + current_condition = None + in_cond = False + in_else = False + elif line.startswith('##'): + continue # ignore internal comments + elif line.startswith('#'): + current_comment += line.strip('# \n') + elif line.strip(): + # if we reach a line that doesn't match the pattern, throw an error as it's not handled (shouldn't happen) + raise Exception(f"{i, line} not handled") + + +def format_dict_values(): + return ''.join( + f'\n ' + f'\n\t\n\t {option}'f'\n\t' + f'\n\t\n\t {description}\n\t' + f'\n\t\n\t {value}\n\t' + f'\n ' + for option, description, value in table_rows.values()) + +def get_sdk_version(): + if len(sys.argv) > 1: + # the script can get the version number as a parameter + version = sys.argv[1] + return f'Version {version}' + else: + # if no parameter provided - no version number will be included + return "" + + +html = f''' + + + Build Customization Flags + + + + +
+

Intel RealSenseā„¢ SDK Build Customization Flags

+

{get_sdk_version()}

+ + + + + + {format_dict_values()} +
OptionDescriptionDefault
+
+ + +''' + +with open('doc/build-flags.html', 'w') as file: + file.write(html) + print("build-flags.html generated")