The syntax of multilib-generator was defined as below:
```
<primary arch>-<abi>-<additional arches>-<extensions>
```
And now extend with one more optional argument:
```
<primary arch>-<abi>-<additional arches>-<extensions>[-<extra-options>]
```
Detail syntax of `<extra-option>`:
```
<extra-options> := <extra-option> ',' <extra-options>
| <extra-option>
<extra-option> := <option> '/' <multi-lib-folder>
```
NOTE: Dash ('-') in the option name must replace with underline ('_'),
and leading dash should skip, e.g. `-fcf-protection=full` become
`fcf_protection=full`.
e.g.
rv64imafdc_zicfiss_zicfilp-lp64d---fcf_protection=full/cfi
It will build a multilib with
`-march=rv64imafdc_zicfiss_zicfilp -mabi=lp64d -fcf-protection=full`
And will use `rv64imafdc_zicfiss_zicfilp/lp64d/cfi` as multilib folder.
gcc/ChangeLog:
* config/riscv/multilib-generator: Support extra options in the
multilib config string.
* doc/install.texi (--with-multilib-generator): Document the extra
options syntax.
---
gcc/config/riscv/multilib-generator | 50 +++++++++++++++++++++--------
gcc/doc/install.texi | 35 ++++++++++++++++++--
2 files changed, 70 insertions(+), 15 deletions(-)
On 6/3/2026 2:14 AM, Kito Cheng wrote:
> The syntax of multilib-generator was defined as below:
>
> ```
> <primary arch>-<abi>-<additional arches>-<extensions>
> ```
>
> And now extend with one more optional argument:
>
> ```
> <primary arch>-<abi>-<additional arches>-<extensions>[-<extra-options>]
> ```
>
> Detail syntax of `<extra-option>`:
> ```
> <extra-options> := <extra-option> ',' <extra-options>
> | <extra-option>
>
> <extra-option> := <option> '/' <multi-lib-folder>
> ```
>
> NOTE: Dash ('-') in the option name must replace with underline ('_'),
> and leading dash should skip, e.g. `-fcf-protection=full` become
> `fcf_protection=full`.
>
> e.g.
>
> rv64imafdc_zicfiss_zicfilp-lp64d---fcf_protection=full/cfi
>
> It will build a multilib with
> `-march=rv64imafdc_zicfiss_zicfilp -mabi=lp64d -fcf-protection=full`
>
> And will use `rv64imafdc_zicfiss_zicfilp/lp64d/cfi` as multilib folder.
>
> gcc/ChangeLog:
>
> * config/riscv/multilib-generator: Support extra options in the
> multilib config string.
> * doc/install.texi (--with-multilib-generator): Document the extra
> options syntax.
Given you know this code better than anyone, happy to step aside and let
you self-approve :-)
jeff
@@ -51,6 +51,7 @@ arches = collections.OrderedDict()
abis = collections.OrderedDict()
required = []
reuse = []
+extra_multlib_option_dict = collections.OrderedDict()
def arch_canonicalize(arch, isa_spec):
this_file = os.path.abspath(os.path.join( __file__))
@@ -143,25 +144,45 @@ args = parser.parse_args()
if args.cmodel:
cmodels = [None] + args.cmodel.split(",")
+ for cmodel in cmodels[1:]:
+ extra_multlib_option_dict['mcmodel=%s' % cmodel] = cmodel
else:
cmodels = [None]
-cmodel_options = '/'.join(['mcmodel=%s' % x for x in cmodels[1:]])
-cmodel_dirnames = ' \\\n'.join(cmodels[1:])
-
for cmodel in cmodels:
for cfg in args.cfgs:
+ local_extra_multlib_option_dict = collections.OrderedDict()
try:
- (arch, abi, extra, ext) = cfg.split('-')
+ if cfg.count('-') == 3:
+ (arch, abi, extra, ext) = cfg.split('-')
+ extra_multlib_options = []
+ elif cfg.count('-') == 4:
+ (arch, abi, extra, ext, extra_multlib_option) = cfg.split('-')
+ # <extra-multilib-option> is a list of options separated by slash, and
+ # each option is consisted of option name and multi-lib dir separated by
+ # semicolon, the dash within the option should rewrite as underscore to
+ # prevent confusion of parsing.
+ # e.g.
+ # fcf_protection=full/cfi : -fcf-protection=full as option name and cfi
+ # as multilib path.
+ extra_multlib_options = extra_multlib_option.split(',')
+ for option in extra_multlib_options:
+ option = option.replace('_', '-')
+ option = option.split('/')
+ local_extra_multlib_option_dict[option[0]] = option[1]
+ extra_multlib_option_dict.update(local_extra_multlib_option_dict)
except:
- print ("Invalid configure string %s, <arch>-<abi>-<extra>-<extensions>\n"
+ print ("Invalid configure string %s, <arch>-<abi>-<extra>-<extensions>"
+ "[-<extra-multilib-option>]\n"
"<extra> and <extensions> can be empty, "
"e.g. rv32imafd-ilp32--" % cfg)
sys.exit(1)
- # Large code model only support rv64.
- if cmodel == "large" and arch.startswith("rv32"):
+ # Compact and large code model only support rv64.
+ if cmodel in ["compact", "large"] and arch.startswith("rv32"):
continue
+ elif cmodel:
+ local_extra_multlib_option_dict['mcmodel=%s' % cmodel] = cmodel
arch = arch_canonicalize (arch, args.misa_spec)
arches[arch] = 1
@@ -181,10 +202,13 @@ for cmodel in cmodels:
arches[alt] = 1
reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi))
- if cmodel:
- required.append('march=%s/mabi=%s/mcmodel=%s' % (arch, abi, cmodel))
- else:
- required.append('march=%s/mabi=%s' % (arch, abi))
+ extra_multlib_option_str = '/'.join(local_extra_multlib_option_dict.keys())
+
+ multilib_cfg_line = 'march=%s/mabi=%s' % (arch, abi)
+
+ if (len(extra_multlib_option_str) > 0):
+ multilib_cfg_line += '/' + extra_multlib_option_str
+ required.append(multilib_cfg_line)
arch_options = '/'.join(['march=%s' % x for x in arches.keys()])
arch_dirnames = ' \\\n'.join(arches.keys())
@@ -196,7 +220,7 @@ prog = sys.argv[0].split('/')[-1]
print('# This file was generated by %s with the command:' % prog)
print('# %s' % ' '.join(sys.argv))
-print('MULTILIB_OPTIONS = %s %s %s' % (arch_options, abi_options, cmodel_options))
-print('MULTILIB_DIRNAMES = %s %s %s' % (arch_dirnames, abi_dirnames, cmodel_dirnames))
+print('MULTILIB_OPTIONS = %s %s %s' % (arch_options, abi_options, " ".join(extra_multlib_option_dict.keys())))
+print('MULTILIB_DIRNAMES = %s %s %s' % (arch_dirnames, abi_dirnames, " ".join(extra_multlib_option_dict.values())))
print('MULTILIB_REQUIRED = %s' % ' \\\n'.join(required))
print('MULTILIB_REUSE = %s' % ' \\\n'.join(reuse))
@@ -1558,8 +1558,9 @@ values, possibly consisting of a single value. Currently only implemented
for riscv*-*-elf*. The accepted values and meanings are given below.
-Every config is constructed with four components: architecture string, ABI,
-reuse rule with architecture string and reuse rule with sub-extension.
+Every config is constructed with four mandatory components and one optional
+component: architecture string, ABI, reuse rule with architecture string,
+reuse rule with sub-extension and an optional list of extra options.
Example 1: Add multi-lib support for rv32i with ilp32.
@smallexample
@@ -1600,6 +1601,36 @@ medlow code model; rv64ima with lp64 and medany code model
rv64ima-lp64--;--cmodel=medlow,medany
@end smallexample
+A config may carry an optional fifth component, a list of extra options, which
+is appended after the sub-extension reuse rule:
+@smallexample
+<arch>-<abi>-<extra-arch>-<sub-ext>[-<extra-options>]
+@end smallexample
+
+The extra options are a comma separated list, and each entry pairs an option
+name with the multilib directory it should map to, separated by a slash:
+@smallexample
+<extra-options> := <extra-option> ',' <extra-options>
+ | <extra-option>
+
+<extra-option> := <option> '/' <multilib-folder>
+@end smallexample
+
+Because the dash (@samp{-}) is used as the component separator, any dash in an
+option name must be rewritten as an underscore (@samp{_}), and the leading dash
+of the option must be dropped. For example, @option{-fcf-protection=full} is
+written as @code{fcf_protection=full}.
+
+Example 7: Add multi-lib support for rv64imafdc with lp64d, plus a variant
+built with @option{-fcf-protection=full} placed in the @file{cfi} directory.
+@smallexample
+rv64imafdc_zicfiss_zicfilp-lp64d---fcf_protection=full/cfi
+@end smallexample
+
+This builds a multilib with
+@option{-march=rv64imafdc_zicfiss_zicfilp -mabi=lp64d -fcf-protection=full}
+and uses @file{rv64imafdc_zicfiss_zicfilp/lp64d/cfi} as the multilib folder.
+
@item --with-multi-buildlist=@var{file}
Specify a file containing a list of multilib directories to build.