make(3)

πŸ“¦
version 29.0.6 Β· 3 versions
, in ubuntu stonking

πŸ’– make β€” bestie's guide to the Erlang make utility πŸ’–

okay so first things first: we're in make(3), from the Erlang Module Definition family of pages. It's make, it's a module, and girl… it's a whole build system in Erlang clothes. Let's get into it 🫢


✨ NAME ✨

make β€” A Make Utility for Erlang</p> πŸ’… (yes, exactly like the UNIX Make vibe, but make it Erlang)


🌸 DESCRIPTION 🌸

The make module hands you a set of functions that are, in spirit, the UNIX-type Make functions. Same energy, different language, no cap.

πŸŽ€ Emakefile (the moment you've been waiting for)

make:all/0,1 and make:files/1,2 do a little detective work, in this exact order:

  1. first they look for {emake, Emake} inside options, and
  2. if that's not there, they go looking in the current working directory for a file literally named Emakefile.

If present, Emake should contain elements like this:

Modules.
{Modules,Options}.

So Modules is an atom, or a list of atoms. And bestie, it can be any of these:

  • a module name β€” for example, file1
  • a module name in another directory β€” for example, '../foo/file3'
  • a set of modules specified with wildcards β€” for example, 'file*'
  • a wildcard indicating all modules in the current directory, that is: '*'
  • a list of any of the above β€” for example, ['file*','../foo/file3','File4']

And Options? That's a list of compiler options. Simple as that πŸ’–

Emakefile gets read from top to bottom, okay? And if some module matches more than one entry, the first match is the one that wins β€” no take-backs. For example, this Emakefile here:

{'file1',[debug_info,{i,"../foo"}]}.
{'*',[debug_info]}.

means file1 should be compiled with the options [debug_info,{i,"../foo"}], while all the other files in the current directory get compiled with only the debug_info flag. Iconic behaviour, honestly πŸ‘‘

🌈 See Also

The Compiler Application β€” yes, the whole compiler app, go look, iykyk.


πŸ”₯ FUNCTIONS πŸ”₯

πŸ’œ all(Options) -> up_to_date | error

all(Options) -> up_to_date | error
                when
                    Options :: [Option],
                    Option ::
                        noexec | load | netload |
                        {emake, Emake} |
                        compile:option(),
                    Emake :: [EmakeElement],
                    EmakeElement :: Modules | {Modules,
[compile:option()]},
                    Modules :: atom() | [atom()].

So this function figures out which modules to compile and what compile options to use. How? It looks for the emake make option first, and if that's not there, it reads the config from a file named Emakefile (see above, bestie, we already covered that). And if no such file is found at all? The set of modules to compile just defaults to all modules in the current working directory. Easy.

Then it walks the whole set of modules and recompiles every single module where at least one of these conditions is true:

  • there's no object file, or
  • the source file has been modified since it was last compiled, or
  • an include file has been modified since the source file was last compiled.

As a side effect (yes, a side effect, we're being honest here πŸ™ˆ) the function prints the name of each module it tries to compile. And if compilation fails for some module, the make procedure stops and error is returned. That's it, that's the whole deal.

Options is a list of options for make and for the Erlang compiler. These are the make options that exist:

  • noexec β€” No execution mode. It just prints the name of each module that needs to be compiled. Like window shopping, but for builds πŸŽ€
  • load β€” Load mode. Loads all the recompiled modules.
  • netload β€” Net load mode. Loads all recompiled modules on all known nodes. Spread the love across the cluster ✨
  • {emake, Emake} β€” Rather than reading the Emakefile, you specify the configuration explicitly. Main character move.

And every item in Options that is not a make option? It's assumed to be a compiler option and is passed as-is straight to compile:file/2. No editing, no vibes-checking, straight through πŸ¦‹

🌸 files(ModFiles, Options) -> up_to_date | error

files(ModFiles, Options) -> up_to_date | error
                when
                    ModFiles ::
                        [(Module :: module()) | (File ::
file:filename())],
                    Options :: [Option],
                    Option :: noexec | load | netload | compile:option().

This one does exactly the same thing as all/0,1, except it's for the ModFiles you specify β€” which is a list of module names or file names. Same energy, but you picked the guest list πŸ’…

The file extension .erl can be omitted. Yes, really, you can just leave it off, she's flexible like that.

The Emakefile (if it exists) in the current directory gets searched for compiler options for each module. And if a given module doesn't exist in Emakefile, or if Emakefile doesn't exist at all β€” the module is still compiled. No abandonment here, we don't do that 🫢


⚠️ friendly reminder, bestie: if compilation fails for a module, the make procedure stops and returns error. Two outcomes, up_to_date or error, that's the whole range, no in-between situationship 😭

and that's the whole page, you ate it, periodt πŸ‘‘ This little love letter was brought to you by Ericsson AB, riding with tools 4.2.2, and it's the make(3) page β€” drop the date badge on your way out, mwah πŸ’–πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from