M2(1)

πŸ“¦
version 16-20260322 Β· 2 versions
, in ubuntu resolute

πŸŽ€ M2(1) β€” the GNU manual πŸŽ€

✨ NAME ✨

okay bestie, gm2 is just the GNU Modula-2 Compiler πŸ’… the whole name, no notes πŸ‘‘

✨ SYNOPSIS ✨

✨ DESCRIPTION ✨

✨ OPTIONS ✨

okay so first things first πŸ’– for every input file, the file name suffix decides what kind of compilation happens. these are the kinds gm2 knows about:

  • file.mod β€” Modula-2 implementation or program source files πŸ¦‹ if your project uses a different source extension, check out -fmod=
  • file.def β€” Modula-2 definition module source files πŸ™ˆ these don't get compiled on their own. in GNU Modula-2 they get parsed as needed when program or implementation modules are compiled. if your project uses another extension, look at -fdef= 🌸

You can specify more than one input file on the gm2 command line,

  • -g β€” make debugging info so debuggers like gdb can inspect and control the executable πŸ”₯
  • -I β€” the search path for definition and implementation modules 🧚 for example: gm2 -g -c -I.:../../libs foo.mod. if you don't specify this, the default path is the current directory followed by the right language dialect library directories ✨
  • -fauto-init β€” turns on auto initialization of pointers to NIL 🫢 whenever a block is created, every pointer declared in that scope gets its address assigned to NIL
  • -fbounds β€” turns on run time checking for subrange, array index and indirection via NIL pointers πŸ’…
  • -fcase β€” compile time checking to see whether a CASE statement needs an ELSE clause when you didn't specify one πŸ“
  • -fcpp β€” okay this one preprocesses your source with cpp -lang-asm -traditional-cpp. For further details about these options If -fcpp is supplied then all definition modules and implementation modules which are parsed will be preprocessed by cpp 🌈
  • -fdebug-builtins β€” calls a real function instead of the builtin equivalent πŸŽ€ super useful for checking the parameter values going into a builtin, since you can single step right into an intrinsic function πŸ¦‹
  • -fdef= β€” recognize the specified suffix as a definition module filename ✨ the default implementation and module filename suffix is .def. If you use this option, GNU Modula-2 will still fall back to that default if a requested definition module isn't found πŸ’–
  • -fdump-system-exports β€” displays all inbuilt system items πŸ™ˆ this is an internal command line option, so it's more of a behind-the-scenes thing
  • -fexceptions β€” turns on exception handling code πŸ‘‘ this one is on by default. You can disable it with -fno-exceptions, and then no references get made to the run time exception libraries
  • -fextended-opaque β€” lets opaque types be implemented as any type πŸ”₯ this is a GNU Modula-2 extension, and it needs the implementation module that defines the opaque type to be available so it can be resolved when compiling the module that imports it
  • -ffloatvalue β€” turns on run time checking to see whether a floating point number is about to exceed its range 🌸
  • -fgen-module-list=filename β€” tries to find all modules when linking and generates a module list 🧚 if the filename is -, then the contents aren't written and it's only used to force the linking of all module ctors. This option can't be used if -fuse-list= is enabled πŸ™…β€β™€οΈ
  • -findex β€” generates code to check whether array index values are out of bounds πŸ’… you can turn array index checking off with -fno-index
  • -fiso β€” turns on ISO standard features πŸ¦‹ right now this enables the ISO SYSTEM module and changes the default library search path so the ISO libraries get searched before the PIM libraries. It also affects how the DIV and MOD operators behave
  • -flibs= β€” modifies the default library search path πŸ“š the libraries you can supply are m2pim, m2iso, m2min, m2log and m2cor. These map onto the Programming in Modula-2 base libraries, ISO standard libraries, minimal library support, the Logitech compatible library, and Programming in Modula-2 with coroutines. You can specify multiple libraries, comma separated, and precedence goes to the first one in the list. You don't need -flibs=m2pim or -flibs=m2iso if you also specify -fpim, -fpim2, -fpim3, -fpim4 or -fiso. Unless you're using -flibs=m2min, you should include m2pim, since it provides the base modules all the other dialects use 🫢 and -fno-libs=- stops the gm2 driver from touching the search and library paths
  • -static-libgm2 β€” on systems that ship the m2 runtimes as both shared and static libraries, this forces the static version πŸ”₯
  • -fm2-debug-trace= β€” turns on trace debugging with a comma separated list: line,token,quad,all πŸ™ˆ this is an internal command line option
  • -fm2-dump= β€” enables dumping of the modula-2 internal representation of data structures using a comma separated list πŸ’– the list can contain quad,gimple,decl,all
  • -fm2-dump-decl=filestem β€” dumps the modula-2 representation of a symbol to the filestem you specify 🌈 this only takes effect if -fm2-dump-filter is specified
  • -fm2-dump-gimple=filestem β€” dumps the modula-2 gimple representation to the filestem you specify 🧚
  • -fm2-dump-quad=filestem β€” dumps the quadruple representation to the filestem you specify πŸ¦‹
  • -fm2-dump-filter=rules β€” filters the language dumps -fdump-lang-decl, -fdump-lang-gimple and-fdump-lang-quad on rules πŸŽ€ rules has to be a comma separated list, and it can take three forms: the full decl textual name of a procedure, [libname.]module.ident, or [filename:]module.ident. This is an internal command line option. Right now it only filters on procedure names, and regexp matching isn't implemented 😭 three examples following the forms above: -fm2-dump-filter=_M2_hello_init, -fm2-dump-filter=m2pim.StrIO.WriteString and -fm2-dump-filter=StrLib.mod:StrIO.WriteString
  • -fm2-file-offset-bits= β€” forces the type SYSTEM.COFF_T to be built with the number of bits you specify ✨ if you don't use this option, the default is CSSIZE_T bits
  • -fm2-g β€” makes the debugging experience better for new programmers πŸ’… the tradeoff is that nop instructions may be generated when needed, so single stepping is precise over all code related keywords. For example, when a list of nested IF statements ends with several END keywords, those get mapped onto a sequence of nop instructions πŸ™ˆ
  • -fm2-lower-case β€” renders keywords in error messages in lower case 🌸
  • -fm2-pathname= β€” specifies the module mangled prefix name for all modules in the include paths that follow 🧚
  • -fm2-pathnameI β€” for internal use only πŸ™ˆ the driver uses it to copy the user facing -I option
  • -fm2-pathname-root=pathroot β€” adds search paths derived from the specified pathroot 🫢
  • -fm2-pathname-rootI β€” for internal use only πŸ™ˆ the driver uses it to copy every user -fm2-pathname-root= facing option, in order, along with all the other -I options πŸ’–

okay that's the first half of the options, bestie πŸ¦‹

  • -fruntime-modules= β€” ✨ Give this a comma-separated list and you decide which run time modules come first and in what order. They get initialized before any other modules in the application dependency. By default the list is "m2iso:RTentity,m2iso:Storage,m2iso:SYSTEM," "m2iso:M2RTS,m2iso:RTExceptions,m2iso:IOLink". These modules only get linked into your executable if they're actually required, so a long list won't make your executable bigger. It only sets the initialization order for when they're needed 🧚
  • -fscaffold-dynamic β€” πŸ’œ This makes gm2 generate a dynamic scaffold when it compiles implementation and program modules. It's on by default. Use -fno-scaffold-dynamic to turn it off, or pick -fno-scaffold-static instead.
  • -fscaffold-c β€” 🌸 Generates a C source scaffold for the module you're currently compiling.
  • -fscaffold-c++ β€” πŸ¦‹ Generates a C++ source scaffold for the module you're currently compiling.
  • -fscaffold-main β€” πŸ‘‘ Forces the main function to be generated. You don't need this if -c is left out.
  • -fscaffold-static β€” πŸ“ Makes gm2 generate a static scaffold inside the program module. That scaffold is a sequence of calls to every dependent module's initialization and finalization procedures. It's super useful for debugging and single stepping through the initialization blocks of implementation modules πŸ”₯
  • -fshared β€” 🌈 Generates a shared library from the module.
  • -fsoft-check-all β€” πŸ’… Turns on every run time check. It's the same as invoking GNU Modula-2 with -fnil -frange -findex -fwholevalue -fwholediv -fcase -freturn.
  • -fsources β€” πŸ” Shows the path to the source of each module. You can use this at compile time to double-check you're using the right definition module 🫢
  • -fswig β€” 🧚 Generates a swig interface file.
  • -funbounded-by-reference β€” πŸ”₯ This turns on an optimization for unbounded parameters. It tries to pass non VAR unbounded parameters by reference, which skips the implicit copy inside the callee procedure. GNU Modula-2 only lets unbounded parameters go by reference if, inside the callee, they aren't written to, no address is calculated on the array, and they aren't passed as a VAR parameter. You can still write code that breaks this optimization, so use it carefully. For example, you could take the address of an array, pass both the address and the array to a procedure, read from the array inside that procedure, and write to the location through the address parameter.
⚠️ Bestie, this one is dangerous! Because of that, it is not enabled when the -O option is specified.
  • -fuse-list=filename β€” πŸ“œ If -fscaffold-static is enabled, this uses the file filename for the initialization order of modules. If -fscaffold-dynamic is enabled instead, the file is used to force linking of all module ctors. You can't use this option if -fgen-module-list= is enabled πŸ™ˆ
  • -fwholediv β€” βž— Generates code that detects whole number division by zero and modulus by zero.
  • -fwholevalue β€” πŸ”’ Generates code that detects whole number overflow and underflow.
  • -Wcase-enum β€” ⚠️ Gives you a warning if a CASE statement selects on an enumerated type expression and is missing one or more CASE labels. If the CASE statement has a default ELSE clause, no warning is issued. The -Wall option turns this flag on too πŸ’–
  • -Wuninit-variable-checking β€” πŸ‘€ Gives you a warning if a variable gets used before it's initialized. The checking only happens in the first basic block in each procedure. It doesn't check parameters, array types, or set types.
  • -Wuninit-variable-checking=all,known,cond β€” πŸ”Ž Gives you a warning if a variable gets used before it's initialized. Checking only happens in the first basic block in each procedure if known is specified. If cond or all is specified, checking keeps going into conditional branches of the flow graph. All checking stops when a procedure call is invoked or the top of a loop is encountered. The -Wall option turns this on with -Wuninit-variable-checking=known. Using -Wuninit-variable-checking=all will increase compile time 🐒
  • -fwideset β€” πŸŽ€ Turns on access to the run time support library module M2WIDESET. It's on by default. You can disable wideset support with -fno-wideset, and then there will be no reference to the run time M2WIDESET library.

✨ SEE ALSO ✨

gpl(7), gfdl(7), fsf-funding(7), gcc(1) and the Info entries for gm2 and gcc πŸ“š

Copyright (c) 1999-2026 Free Software Foundation, Inc.

Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation. There are no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the man page gfdl(7) πŸ’œ


That's the whole page, bestie! πŸ¦‹ Source: gcc-16, dated 2026-03-22, M2(1) 🌈 Stay iconic! πŸ’…βœ¨

πŸ“¦ where this page comes from