diff --git a/docs/reference-manual/native-image/BuildOptions.md b/docs/reference-manual/native-image/BuildOptions.md index 4ee1a4ac9773..8c96c284c546 100644 --- a/docs/reference-manual/native-image/BuildOptions.md +++ b/docs/reference-manual/native-image/BuildOptions.md @@ -37,78 +37,510 @@ Use reachability metadata instead. These deprecated URL protocol options are omitted from the generated table; see [URL Protocols in Native Image](URLProtocols.md). -| Command | Type | Description | Default | Usage | -|---------|------|-------------|---------|-------| -| `--add-exports` | String | value /=(,)* updates to export to , regardless of module declaration. can be ALL-UNNAMED to export to all unnamed modules. | None | `--add-exports=add-exports` | -| `--add-opens` | String | value /=(,)* updates to open to , regardless of module declaration. | None | `--add-opens=add-opens` | -| `--add-reads` | String | value =(,)* updates to read , regardless of module declaration. can be ALL-UNNAMED to read all unnamed modules. | None | `--add-reads=add-reads` | -| `--color` | String | color build output ('always', 'never', or 'auto') | None | `--color=color` | -| `--emit` | String | emit additional data as a result of the build. Use 'build-report' to emit a detailed Build Report, for example: '--emit build-report' or '--emit build-report=/tmp/report.html' | None | `--emit=emit` | -| `--enable-all-security-services` | String | add all security service classes to the generated image. | None | `--enable-all-security-services=enable-all-security-services` | -| `--enable-monitoring` | String | enable monitoring features that allow the VM to be inspected at run time. Comma-separated list can contain 'heapdump', 'jfr', 'jvmstat', 'jmxserver' (experimental), 'jmxclient' (experimental), 'threaddump', 'nmt' (experimental), 'jcmd' (experimental), or 'all' (deprecated behavior: defaults to 'all' if no argument is provided). For example: '--enable-monitoring=heapdump,jfr'. | | `--enable-monitoring=enable-monitoring` | -| `--enable-native-access` | String | a comma-separated list of modules that are permitted to perform restricted native operations. The module name can also be ALL-UNNAMED. | None | `--enable-native-access=enable-native-access` | -| `--enable-sbom` | String | assemble a Software Bill of Materials (SBOM) for the executable or shared library based on the results from the static analysis. Comma-separated list can contain 'embed' to store the SBOM in data sections of the binary, 'export' to save the SBOM in the output directory, 'classpath' to include the SBOM as a Java resource on the classpath at 'META-INF/native-image/sbom.json', 'hashes' to include component hashes, 'strict' to abort the build if any type (such as a class, interface, or annotation) cannot be matched to an SBOM component or if a component hash could not be created, 'cyclonedx' (the only format currently supported), and 'class-level' to include class-level metadata. Defaults to embedding an SBOM: '--enable-sbom=embed'. To disable the SBOM feature, use '--enable-sbom=false' on the command line. | embed | `--enable-sbom=--enable-sbom` | -| `--exact-reachability-metadata` | String | enables exact and user-friendly handling of reflection, resources, JNI, and serialization. | | `--exact-reachability-metadata=exact-reachability-metadata` | -| `--exact-reachability-metadata-path` | String | trigger exact handling of reflection, resources, JNI, and serialization from all types in the given class-path or module-path entries. | None | `--exact-reachability-metadata-path=exact-reachability-metadata-path` | -| `--features` | String | a comma-separated list of fully qualified Feature implementation classes | None | `--features=features` | -| `--future-defaults` | String | enable options that are planned to become defaults in future releases. Comma-separated list can contain 'all', 'none', 'run-time-initialize-jdk', 'class-for-name-respects-class-loader', 'run-time-initialize-file-system-providers', 'run-time-initialize-security-providers', 'run-time-initialize-resource-bundles', 'explicit-feature-singleton-registration'. The preferred usage is '--future-defaults=all'. | | `--future-defaults=future-defaults` | -| `--initialize-at-build-time` | String | a comma-separated list of packages and classes (and implicitly all of their superclasses) that are initialized during image generation. An empty string designates all packages. | | `--initialize-at-build-time=initialize-at-build-time` | -| `--initialize-at-run-time` | String | a comma-separated list of packages and classes (and implicitly all of their subclasses) that must be initialized at runtime and not during image building. An empty string is currently not supported. | | `--initialize-at-run-time=initialize-at-run-time` | -| `--libc` | String | selects the libc implementation to use. Available implementations: glibc, musl, bionic | None | `--libc=libc` | -| `--link-at-build-time` | String | require types to be fully defined at image build-time. If used without args, all classes in scope of the option are required to be fully defined. | | `--link-at-build-time=link-at-build-time` | -| `--link-at-build-time-paths` | String | require all types in given class or module-path entries to be fully defined at image build-time. | None | `--link-at-build-time-paths=link-at-build-time-paths` | -| `--list-cpu-features` | String | show CPU features specific to the target platform and exit. | None | `--list-cpu-features=list-cpu-features` | -| `--list-modules` | String | list observable modules and exit. | None | `--list-modules=list-modules` | -| `--native-compiler-options` | String | provide custom C compiler option used for query code compilation. | None | `--native-compiler-options=native-compiler-options` | -| `--native-compiler-path` | String | provide custom path to C compiler used for query code compilation and linking. | None | `--native-compiler-path=native-compiler-path` | -| `--native-image-info` | String | show native-toolchain information and image-build settings | None | `--native-image-info=native-image-info` | -| `--parallelism` | String | the maximum number of threads the build process is allowed to use. | None | `--parallelism=parallelism` | -| `--pgo` | String | a comma-separated list of files from which to read the data collected for profile-guided optimization of AOT compiled code (reads from default.iprof if nothing is specified). Each file must contain a single PGOProfiles object, serialized in JSON format, optionally compressed by gzip. | default.iprof | `--pgo=pgo` | -| `--pgo-instrument` | String | instrument AOT compiled code to collect data for profile-guided optimization into default.iprof file | None | `--pgo-instrument=pgo-instrument` | -| `--pgo-sampling` | String | perform profiling by sampling the AOT compiled code to collect data for profile-guided optimization. | None | `--pgo-sampling=pgo-sampling` | -| `--shared` | String | build shared library | None | `--shared=shared` | -| `--silent` | String | silence build output | None | `--silent=silent` | -| `--static` | String | build statically linked executable (requires static libc and zlib) | None | `--static=static` | -| `--static-nolibc` | String | build statically linked executable with libc dynamically linked | None | `--static-nolibc=static-nolibc` | -| `--target` | String | selects native-image compilation target (in - format). Defaults to host's OS-architecture pair. | None | `--target=target` | -| `--trace-object-instantiation` | String | comma-separated list of fully-qualified class names that object instantiation is traced for. | None | `--trace-object-instantiation=trace-object-instantiation` | -| `-O` | String | control code optimizations: b - optimize for fastest build time, s - optimize for size, 0 - no optimizations, 1 - basic optimizations, 2 - advanced optimizations, 3 - all optimizations for best performance. | None | `-O=-O` | -| `-Werror` | String | treat warnings as errors and terminate build. | all | `-Werror=-Werror` | -| `-da` | String | also -da[:[packagename]...\\|:classname] or -disableassertions[:[packagename]...\\|:classname]. Disable assertions with specified granularity at run time. | | `-da=-da` | -| `-dsa` | String | also -disablesystemassertions. Disables assertions in all system classes at run time. | None | `-dsa=-dsa` | -| `-ea` | String | also -ea[:[packagename]...\\|:classname] or -enableassertions[:[packagename]...\\|:classname]. Enable assertions with specified granularity at run time. | | `-ea=-ea` | -| `-esa` | String | also -enablesystemassertions. Enables assertions in all system classes at run time. | None | `-esa=-esa` | -| `-g` | String | generate debugging information | 2 | `-g=-g` | -| `-march` | String | generate instructions for a specific machine type. Defaults to 'x86-64-v3' on AMD64 and 'armv8.1-a' on AArch64. Use -march=compatibility for best compatibility, or -march=native for best performance if the native executable is deployed on the same machine or on a machine with the same CPU features. To list all available machine types, use -march=list. | None | `-march=-march` | -| `-o` | String | name of the output file to be generated | None | `-o=-o` | -| `--gc` | Enum | select native-image garbage collector implementation. Allowed values: 'epsilon', 'serial', 'G1'. | serial | `--gc=` | -| `--add-modules` | String | root modules to resolve in addition to the initial module. can also be ALL-DEFAULT, ALL-SYSTEM, ALL-MODULE-PATH. | | `--add-modules [,...]` | -| `--bundle-apply` | String | build an image from the given bundle file using the original arguments and files. If --bundle-create is passed after --bundle-apply, a new bundle is written with the applied plus additional arguments. | | `--bundle-apply=some-bundle.nib[,dry-run][,container[=][,dockerfile=]]` | -| `--bundle-create` | String | in addition to image building, create a Native Image bundle file (*.nib file) that allows rebuilding of that image again at a later point. If a bundle-file gets passed, the bundle will be created with the given name; otherwise, the bundle-file name is derived from the image name. Bundle options can be extended with ',dry-run' and ',container'; 'dockerfile=' uses a user-provided Dockerfile. | | `--bundle-create[=new-bundle.nib][,dry-run][,container[=][,dockerfile=]]` | -| `--class-path` | Path | A : separated list of directories, JAR archives, and ZIP archives to search for class files. | | `--class-path ` | -| `--configurations-path` | Path | A : separated list of directories to be treated as option-configuration directories. | | `--configurations-path ` | -| `--debug-attach` | String | attach to debugger during image building (default port is 8000) | | `--debug-attach[=]` | -| `--diagnostics-mode` | Boolean | Enables logging of image-build information to a diagnostics folder. | | `--diagnostics-mode` | -| `--dry-run` | Boolean | output the command line that would be used for building | | `--dry-run` | -| `--enable-preview` | Boolean | allow classes to depend on preview features of this release | | `--enable-preview` | -| `--exclude-config` | String | exclude configuration for a space-separated pair of classpath/modulepath pattern and resource pattern. For example: '--exclude-config foo.jar META-INF\\/native-image\\/.*.properties' ignores all .properties files in 'META-INF/native-image' in all JARs named 'foo.jar'. | | `--exclude-config` | -| `--expert-options` | Boolean | lists image build options for experts | | `--expert-options` | -| `--expert-options-all` | Boolean | lists all image build options for experts (use at your own risk). Options marked with [Extra help available] contain help that can be shown with --expert-options-detail. | | `--expert-options-all` | -| `--expert-options-detail` | String | displays all available help for a comma-separated list of option names. Pass * to show extra help for all options that contain it. | | `--expert-options-detail` | -| `--help` | Boolean | print this help message | | `--help` | -| `--help-extra` | Boolean | print help on non-standard options | | `--help-extra` | -| `--module-path` | Path | A : separated list of directories, each directory is a directory of modules. | | `--module-path ...` | -| `--print-options` | String | print comprehensive options table. Available formats: 'table' (default), 'markdown' or 'md', and 'json'. This eliminates duplication with manual documentation tables. | | `--print-options[=]` | -| `--verbose` | Boolean | enable verbose output | | `--verbose` | -| `--version` | Boolean | print product version and exit | | `--version` | -| `-D` | String | set a system property for image build time only | | `-D=` | -| `-E` | String | allow native-image to access the given environment variable during image build. If is omitted, the value is taken from the environment native-image was invoked from. | | `-E[=]` | -| `-J` | String | pass directly to the JVM running the image generator | | `-J` | -| `-V` | String | provide values for placeholders in native-image.properties files | | `-V=` | -| `-classpath` | Path | class search path of directories and zip/jar files | | `-classpath ` | -| `-cp` | Path | class search path of directories and zip/jar files | | `-cp ` | -| `-p` | Path | module path | | `-p ` | -| `@argument` | String | one or more argument files containing options | | `@argument files` | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandTypeDescriptionDefaultUsage
--add-exportsStringvalue <module>/<package>=<target-module>(,<target-module>)* updates <module> to export <package> to <target-module>, regardless of module declaration. <target-module> can be ALL-UNNAMED to export to all unnamed modules.None--add-exports=add-exports
--add-opensStringvalue <module>/<package>=<target-module>(,<target-module>)* updates <module> to open <package> to <target-module>, regardless of module declaration.None--add-opens=add-opens
--add-readsStringvalue <module>=<target-module>(,<target-module>)* updates <module> to read <target-module>, regardless of module declaration. <target-module> can be ALL-UNNAMED to read all unnamed modules.None--add-reads=add-reads
--colorStringcolor build output ('always', 'never', or 'auto')None--color=color
--emitStringemit additional data as a result of the build. Use 'build-report' to emit a detailed Build Report, for example: '--emit build-report' or '--emit build-report=/tmp/report.html'None--emit=emit
--enable-all-security-servicesStringadd all security service classes to the generated image.None--enable-all-security-services=enable-all-security-services
--enable-monitoringStringenable monitoring features that allow the VM to be inspected at run time. Comma-separated list can contain 'heapdump', 'jfr', 'jvmstat', 'jmxserver' (experimental), 'jmxclient' (experimental), 'threaddump', 'nmt' (experimental), 'jcmd' (experimental), or 'all' (deprecated behavior: defaults to 'all' if no argument is provided). For example: '--enable-monitoring=heapdump,jfr'.<deprecated-default>--enable-monitoring=enable-monitoring
--enable-native-accessStringa comma-separated list of modules that are permitted to perform restricted native operations. The module name can also be ALL-UNNAMED.None--enable-native-access=enable-native-access
--enable-sbomStringassemble a Software Bill of Materials (SBOM) for the executable or shared library based on the results from the static analysis. Comma-separated list can contain 'embed' to store the SBOM in data sections of the binary, 'export' to save the SBOM in the output directory, 'classpath' to include the SBOM as a Java resource on the classpath at 'META-INF/native-image/sbom.json', 'hashes' to include component hashes, 'strict' to abort the build if any type (such as a class, interface, or annotation) cannot be matched to an SBOM component or if a component hash could not be created, 'cyclonedx' (the only format currently supported), and 'class-level' to include class-level metadata. Defaults to embedding an SBOM: '--enable-sbom=embed'. To disable the SBOM feature, use '--enable-sbom=false' on the command line.embed--enable-sbom=--enable-sbom
--exact-reachability-metadataStringenables exact and user-friendly handling of reflection, resources, JNI, and serialization.--exact-reachability-metadata=exact-reachability-metadata
--exact-reachability-metadata-pathStringtrigger exact handling of reflection, resources, JNI, and serialization from all types in the given class-path or module-path entries.None--exact-reachability-metadata-path=exact-reachability-metadata-path
--featuresStringa comma-separated list of fully qualified Feature implementation classesNone--features=features
--future-defaultsStringenable options that are planned to become defaults in future releases. Comma-separated list can contain 'all', 'none', 'run-time-initialize-jdk', 'class-for-name-respects-class-loader', 'run-time-initialize-file-system-providers', 'run-time-initialize-security-providers', 'run-time-initialize-resource-bundles', 'explicit-feature-singleton-registration'. The preferred usage is '--future-defaults=all'.<default-value>--future-defaults=future-defaults
--initialize-at-build-timeStringa comma-separated list of packages and classes (and implicitly all of their superclasses) that are initialized during image generation. An empty string designates all packages.--initialize-at-build-time=initialize-at-build-time
--initialize-at-run-timeStringa comma-separated list of packages and classes (and implicitly all of their subclasses) that must be initialized at runtime and not during image building. An empty string is currently not supported.--initialize-at-run-time=initialize-at-run-time
--libcStringselects the libc implementation to use. Available implementations: glibc, musl, bionicNone--libc=libc
--link-at-build-timeStringrequire types to be fully defined at image build-time. If used without args, all classes in scope of the option are required to be fully defined.--link-at-build-time=link-at-build-time
--link-at-build-time-pathsStringrequire all types in given class or module-path entries to be fully defined at image build-time.None--link-at-build-time-paths=link-at-build-time-paths
--list-cpu-featuresStringshow CPU features specific to the target platform and exit.None--list-cpu-features=list-cpu-features
--list-modulesStringlist observable modules and exit.None--list-modules=list-modules
--native-compiler-optionsStringprovide custom C compiler option used for query code compilation.None--native-compiler-options=native-compiler-options
--native-compiler-pathStringprovide custom path to C compiler used for query code compilation and linking.None--native-compiler-path=native-compiler-path
--native-image-infoStringshow native-toolchain information and image-build settingsNone--native-image-info=native-image-info
--parallelismStringthe maximum number of threads the build process is allowed to use.None--parallelism=parallelism
--pgoStringa comma-separated list of files from which to read the data collected for profile-guided optimization of AOT compiled code (reads from default.iprof if nothing is specified). Each file must contain a single PGOProfiles object, serialized in JSON format, optionally compressed by gzip.default.iprof--pgo=pgo
--pgo-instrumentStringinstrument AOT compiled code to collect data for profile-guided optimization into default.iprof fileNone--pgo-instrument=pgo-instrument
--pgo-samplingStringperform profiling by sampling the AOT compiled code to collect data for profile-guided optimization.None--pgo-sampling=pgo-sampling
--sharedStringbuild shared libraryNone--shared=shared
--silentStringsilence build outputNone--silent=silent
--staticStringbuild statically linked executable (requires static libc and zlib)None--static=static
--static-nolibcStringbuild statically linked executable with libc dynamically linkedNone--static-nolibc=static-nolibc
--targetStringselects native-image compilation target (in <OS>-<architecture> format). Defaults to host's OS-architecture pair.None--target=target
--trace-object-instantiationStringcomma-separated list of fully-qualified class names that object instantiation is traced for.None--trace-object-instantiation=trace-object-instantiation
-OStringcontrol code optimizations: b - optimize for fastest build time, s - optimize for size, 0 - no optimizations, 1 - basic optimizations, 2 - advanced optimizations, 3 - all optimizations for best performance.None-O=-O
-WerrorStringtreat warnings as errors and terminate build.all-Werror=-Werror
-daStringalso -da[:[packagename]...|:classname] or -disableassertions[:[packagename]...|:classname]. Disable assertions with specified granularity at run time.-da=-da
-dsaStringalso -disablesystemassertions. Disables assertions in all system classes at run time.None-dsa=-dsa
-eaStringalso -ea[:[packagename]...|:classname] or -enableassertions[:[packagename]...|:classname]. Enable assertions with specified granularity at run time.-ea=-ea
-esaStringalso -enablesystemassertions. Enables assertions in all system classes at run time.None-esa=-esa
-gStringgenerate debugging information2-g=-g
-marchStringgenerate instructions for a specific machine type. Defaults to 'x86-64-v3' on AMD64 and 'armv8.1-a' on AArch64. Use -march=compatibility for best compatibility, or -march=native for best performance if the native executable is deployed on the same machine or on a machine with the same CPU features. To list all available machine types, use -march=list.None-march=-march
-oStringname of the output file to be generatedNone-o=-o
--gcEnumselect native-image garbage collector implementation. Allowed values: 'epsilon', 'serial', 'G1'.serial--gc=<value>
--add-modulesStringroot modules to resolve in addition to the initial module. <module name> can also be ALL-DEFAULT, ALL-SYSTEM, ALL-MODULE-PATH.--add-modules <module name>[,<module name>...]
--bundle-applyStringbuild an image from the given bundle file using the original arguments and files. If --bundle-create is passed after --bundle-apply, a new bundle is written with the applied plus additional arguments.--bundle-apply=some-bundle.nib[,dry-run][,container[=<container-tool>][,dockerfile=<Dockerfile>]]
--bundle-createStringin addition to image building, create a Native Image bundle file (*.nib file) that allows rebuilding of that image again at a later point. If a bundle-file gets passed, the bundle will be created with the given name; otherwise, the bundle-file name is derived from the image name. Bundle options can be extended with ',dry-run' and ',container'; 'dockerfile=<Dockerfile>' uses a user-provided Dockerfile.--bundle-create[=new-bundle.nib][,dry-run][,container[=<container-tool>][,dockerfile=<Dockerfile>]]
--class-pathPathA : separated list of directories, JAR archives, and ZIP archives to search for class files.--class-path <class search path of directories and zip/jar files>
--configurations-pathPathA : separated list of directories to be treated as option-configuration directories.--configurations-path <search path of option-configuration directories>
--debug-attachStringattach to debugger during image building (default port is 8000)--debug-attach[=<port or host:port (* can be used as host meaning bind to all interfaces)>]
--diagnostics-modeBooleanEnables logging of image-build information to a diagnostics folder.--diagnostics-mode
--dry-runBooleanoutput the command line that would be used for building--dry-run
--enable-previewBooleanallow classes to depend on preview features of this release--enable-preview
--exclude-configStringexclude configuration for a space-separated pair of classpath/modulepath pattern and resource pattern. For example: '--exclude-config foo.jar META-INF\\/native-image\\/.*.properties' ignores all .properties files in 'META-INF/native-image' in all JARs named 'foo.jar'.--exclude-config
--expert-optionsBooleanlists image build options for experts--expert-options
--expert-options-allBooleanlists all image build options for experts (use at your own risk). Options marked with [Extra help available] contain help that can be shown with --expert-options-detail.--expert-options-all
--expert-options-detailStringdisplays all available help for a comma-separated list of option names. Pass * to show extra help for all options that contain it.--expert-options-detail
--helpBooleanprint this help message--help
--help-extraBooleanprint help on non-standard options--help-extra
--module-pathPathA : separated list of directories, each directory is a directory of modules.--module-path <module path>...
--print-optionsStringprint comprehensive options table. Available formats: 'table' (default), 'markdown' or 'md', and 'json'. This eliminates duplication with manual documentation tables.--print-options[=<format>]
--verboseBooleanenable verbose output--verbose
--versionBooleanprint product version and exit--version
-DStringset a system property for image build time only-D<name>=<value>
-EStringallow native-image to access the given environment variable during image build. If <env-var-value> is omitted, the value is taken from the environment native-image was invoked from.-E<env-var-key>[=<env-var-value>]
-JStringpass <flag> directly to the JVM running the image generator-J<flag>
-VStringprovide values for placeholders in native-image.properties files-V<key>=<value>
-classpathPathclass search path of directories and zip/jar files-classpath <class search path of directories and zip/jar files>
-cpPathclass search path of directories and zip/jar files-cp <class search path of directories and zip/jar files>
-pPathmodule path-p <module path>
@argumentStringone or more argument files containing options@argument files
## List of Useful Options diff --git a/substratevm/mx.substratevm/mx_substratevm_docs.py b/substratevm/mx.substratevm/mx_substratevm_docs.py index ee571e0d36a6..ce5d5a6c444c 100644 --- a/substratevm/mx.substratevm/mx_substratevm_docs.py +++ b/substratevm/mx.substratevm/mx_substratevm_docs.py @@ -52,10 +52,10 @@ def _ensure_native_image_executable(): return native_image_cmd -def _generate_markdown_options_table(): +def _generate_html_options_table(): native_image_cmd = _ensure_native_image_executable() output = mx.OutputCapture() - mx.run([native_image_cmd, '--print-options=markdown'], out=output) + mx.run([native_image_cmd, '--print-options=html'], out=output) return output.data.strip() @@ -118,7 +118,7 @@ def verify_build_options_table(): # Generate current options table mx.log("Generating current options table for verification...") - generated_content = _generate_markdown_options_table() + generated_content = _generate_html_options_table() # Read existing BuildOptions.md and extract just the table section with open(build_options_file, 'r', encoding='utf-8') as f: @@ -147,7 +147,7 @@ def verify_build_options_table(): # Extract content between markers existing_table = content[begin_idx + len(begin_marker):end_idx].strip() - generated_table = _extract_table_from_markdown(generated_content) + generated_table = generated_content existing_normalized = _normalize_table(existing_table) generated_normalized = _normalize_table(generated_table) @@ -219,7 +219,7 @@ def update_build_options_table(): # Generate current options table mx.log("Generating updated options table...") - generated_content = _generate_markdown_options_table() + generated_content = _generate_html_options_table() # Read existing BuildOptions.md with open(build_options_file, 'r', encoding='utf-8') as f: @@ -235,33 +235,34 @@ def update_build_options_table(): if begin_idx == -1 or end_idx == -1: # Fallback: try to find existing table and suggest adding markers table_start = content.find('| Command | Type | Description |') - if table_start == -1: + if table_start != -1: + mx.log("Found existing table but no auto-generation markers.") + mx.log("Consider adding comment markers around the table:") + mx.log(f" {begin_marker}") + mx.log(" [existing table content]") + mx.log(f" {end_marker}") + + # For now, use the old method + table_end = content.find('\n## ', table_start) + if table_end == -1: + table_end = len(content) + + # Extract table from generated content (skip markdown header) + new_table = generated_content + new_content = content[:table_start] + new_table + content[table_end:] + else: mx.abort("Could not find table or auto-generation markers in BuildOptions.md") - - mx.log("Found existing table but no auto-generation markers.") - mx.log("Consider adding comment markers around the table:") - mx.log(f" {begin_marker}") - mx.log(" [existing table content]") - mx.log(f" {end_marker}") - - # For now, use the old method - table_end = content.find('\n## ', table_start) - if table_end == -1: - table_end = len(content) - - # Extract table from generated content (skip markdown header) - new_table = _extract_table_from_markdown(generated_content) - new_content = content[:table_start] + new_table + content[table_end:] + return False else: # Use marker-based replacement (preferred method) mx.log("Found auto-generation markers - using clean replacement") # Extract table content from generated markdown - table_content = _extract_table_from_markdown(generated_content) + table_content = generated_content # Replace content between markers new_content = (content[:begin_idx + len(begin_marker)] + - '\n' + table_content + '\n' + + '\n\n' + table_content + '\n' + content[end_idx:]) # Write updated content diff --git a/substratevm/src/com.oracle.svm.driver.test/src/com/oracle/svm/driver/ComprehensiveOptionsTest.java b/substratevm/src/com.oracle.svm.driver.test/src/com/oracle/svm/driver/ComprehensiveOptionsTest.java new file mode 100644 index 000000000000..293c346f6f36 --- /dev/null +++ b/substratevm/src/com.oracle.svm.driver.test/src/com/oracle/svm/driver/ComprehensiveOptionsTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.svm.driver; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class ComprehensiveOptionsTest { + @Test + public void escapesPipesAsMarkdownTableCellContent() { + assertEquals("-da[:[packagename]...\\|:classname]", + ComprehensiveOptions.escapeMarkdown("-da[:[packagename]...|:classname]")); + } +} diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/ComprehensiveOptions.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/ComprehensiveOptions.java index 237ebb52f985..a9a358069e90 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/ComprehensiveOptions.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/ComprehensiveOptions.java @@ -133,6 +133,15 @@ void printOptions(Consumer println, SortedMap println, SortedMap apiOptions, Map groupInfos) { + List markdownLines = new ArrayList<>(); + MARKDOWN.printOptions(markdownLines::add, apiOptions, groupInfos); + printHtmlTable(println, markdownLines); + } + }, JSON("json") { @Override void printOptions(Consumer println, SortedMap apiOptions, Map groupInfos) { @@ -315,9 +324,63 @@ static OutputFormat fromString(String format) { } throw NativeImage.showError("Invalid format: '" + format + "'. Valid formats are: " + Arrays.stream(values()) + .filter(f -> f != HTML) .flatMap(f -> Arrays.stream(f.aliases)) .collect(Collectors.joining(", "))); } + + private static void printHtmlTable(Consumer println, List markdownLines) { + int tableStart = markdownLines.indexOf("| Command | Type | Description | Default | Usage |"); + if (tableStart == -1) { + throw VMError.shouldNotReachHere("Could not find the Markdown options table"); + } + + println.accept(""); + println.accept(" "); + printHtmlRow(println, "th", markdownLines.get(tableStart)); + println.accept(" "); + println.accept(" "); + for (int i = tableStart + 2; i < markdownLines.size(); i++) { + String line = markdownLines.get(i); + if (line.isEmpty()) { + break; + } + printHtmlRow(println, "td", line); + } + println.accept(" "); + println.accept("
"); + } + + private static void printHtmlRow(Consumer println, String tag, String markdownRow) { + println.accept(" "); + for (String cell : splitMarkdownRow(markdownRow)) { + String value = cell.strip().replace("\\|", "|"); + String codeDelimiter = Character.toString((char) 96); + if (value.startsWith(codeDelimiter) && value.endsWith(codeDelimiter)) { + value = "" + value.substring(1, value.length() - 1) + ""; + } + println.accept(" <" + tag + ">" + value + ""); + } + println.accept(" "); + } + + private static List splitMarkdownRow(String markdownRow) { + List cells = new ArrayList<>(); + StringBuilder cell = new StringBuilder(); + boolean escaped = false; + for (int i = 1; i < markdownRow.length() - 1; i++) { + char character = markdownRow.charAt(i); + if (character == '|' && !escaped) { + cells.add(cell.toString()); + cell.setLength(0); + } else { + cell.append(character); + } + escaped = character == '\\' && !escaped; + } + cells.add(cell.toString()); + return cells; + } } record DriverOptionInfo(String type, String helpText, String defaultValue, String usage, boolean deprecated) { @@ -557,11 +620,14 @@ private static String generateUsageExample(String optionName, APIOptionHandler.O return optionName; } - private static String escapeMarkdown(String text) { + static String escapeMarkdown(String text) { if (text == null) { return ""; } - return text.replace("|", "\\|").replace("\\", "\\\\"); + // Escape existing backslashes first so that the backslash which escapes a table-cell + // separator remains a single backslash in the generated Markdown. + return text.replace("\\", "\\\\").replace("|", "\\|") + .replace("&", "&").replace("<", "<").replace(">", ">"); } private static String startLowerCase(String str) {