ic(3)
π ic(3) β Erlang Module Definition π
okay bestie, sit down, hydrate, because we're about to get into ic, the Erlang IDL Compiler, and it is lowkey iconic. this is the manual page, and yes i'm gonna make it cute, but no cap β every single flag, every type, every default is staying right here. π«Ά
β¨ NAME β¨
ic β the Erlang IDL Compiler. that's it. that's the name. periodt. π
πΈ DESCRIPTION πΈ
so the ic module is an Erlang implementation of an OMG IDL compiler. depending on which back-end you pick, the code it spits out maps to Erlang, C, or Java. and bestie, it's not just sitting there β the compiler generates client stubs and server skeletons for you. main character behavior, honestly. π
for each scope, two kinds of files get generated:
- Ordinary code files β these contain the object interface functions. the actual doing-stuff files.
- Header files β these are the ones used for defining record definitions.
so yeah. header files = record definitions, ordinary files = interface functions. got it? got it. β¨
π EXPORTS π
here's where the real ones live. the functions. the calls. let's go. π
π ic:gen/1 and ic:gen/2
ic:gen(FileName) -> Result
ic:gen(FileName, [Option]) -> Result
π Types
okay so this is the type situation, and i'm putting it verbatim because every single bit of it matters, bestie:
Result = ok | error | {ok, [Warning]} | {error, [Warning], [Error]}
Option = [ GeneralOption | CodeOption | WarningOption | BackendOption]
GeneralOption =
{outdir, String()} | {cfgfile, String()} | {use_preproc, bool()} |
{preproc_cmd, String()} | {preproc_flags, String()}
CodeOption =
{gen_hrl, bool()} | {serv_last_call, exception | exit} |
{{impl, String()}, String()} | {light_ifr, bool()}
this | {this, String()} | {{this, String()}, bool()} |
from | {from, String()} | {{from, String()}, bool()} |
handle_info | {handle_info, String()} | {{handle_info, String()}, bool()} |
timeout | {timeout, String()} | {{timeout, String()}, bool()} |
{scoped_op_calls, bool()} | {scl, bool()} |
{user_protocol, Prefix} |
{c_timeout, {SendTimeout, RecvTimeout}} |
{c_report, bool()} |
{precond, {atom(), atom()}} | {{precond, String()} {atom(), atom()}} |
{postcond, {atom(), atom()}} | {{postcond, String()} {atom(), atom()}}
WarningOption =
{'Wall', bool()} | {maxerrs, int() | infinity} |
{maxwarns, int() | infinity} | {nowarn, bool()} |
{warn_name_shadow, bool()} | {pedantic, bool()} |
{silent, bool()}
BackendOption = {be, Backend}
Backend = erl_corba | erl_template | erl_plain | erl_genserv |
c_client | c_server | java
DirNAme = string() | atom()
FileName = string() | atom()
π«Ά little shortcut for you: the tuple{Option, true}can be replaced by justOptionfor boolean values. so you don't have to write thetrueout. slay.
π¦ Calling it from the command line
the ic:gen/2 function can also be called from the command line, like this:
erlc "+Option" ... File.idl
and here's an example, because examples are self-care:
erlc "+{be,c_client}" '+{outdir, "../out"}' File.idl
β GENERAL OPTIONS β
these are the general ones. the foundational ones. the ones that set the whole vibe. let's break them down, one by one, no skipping. π
outdirβ places all the output files in the directory given by the option. and if that directory doesn't exist yet? it gets created. we love a proactive king. π
Example option: {outdir, "output/generated"}.
cfgfileβ usesFileNameas the configuration file. options will override the compiler defaults, but they can themselves be overridden by command line options. so it's a whole hierarchy, bestie. the default value is".ic_config". π
Example option: {cfgfile, "special.cfg"}.
use_preprocβ uses a preprocessor. the default value istrue.preproc_cmdβ this is the command string to invoke the preprocessor. the actual command gets built aspreproc_cmd++preproc_flags++FileName. yes, that's literally how it's constructed, i don't make the rules. πΈ
Example option: {preproc_cmd, "erl"}).
Example option: {preproc_cmd, "gcc -x c++ -E"}.
preproc_flagsβ the flags you give to the preprocessor. π¦
Example option: {preproc_flags, "-I../include"}.
and that's the general options wrapped, but bestie we are so not done β the code options, warning options, and back-end options are still coming. stay hydrated. π
β¨ CODE OPTIONS β¨
Ok bestie, these are the options that literally change what code comes out the other end. Read carefully π
light_ifrβ rn the default isfalse. To even use this one, Orber has to be configured to use Light IFR (go peek at Orber's User's Guide, iykyk). When you turn it on, the generated files that register the API in the IFR DB get minimized β smol files, big slay.
Example option: {light_ifr, true}.
gen_hrlβ generate header files. Default istrue. πserv_last_callβ makes the lastgen_serverhandle_calleither raise a CORBA exception or just exit plainly. Default is the exception.{{impl, IntfName}, ModName}β this one assumes the interface namedIntfNameis implemented by the module namedModName, and it'll generate calls to theModNamemodule in the server behavior. Heads up bestie:IntfNamemust be a fully scoped name, like"M1::I1". No shortcuts. πthisβ adds the object reference as the first parameter to the object implementation functions. Basically it makes the implementation aware of its own object reference, main character energy fr.
The option comes in three varieties: this which activates the parameter for all interfaces in the source file, {this, IntfName} which activates the parameter for a specified interface, and {{this, IntfName}, false} which deactivates the parameter for a specified interface.
Example option: this) activates the parameter for all interfaces.
Example option: {this, "M1::I1"} activates the parameter for all functions of M1::I1.
Example options: [this, {{this, "M1::I2"}, false}] activates the parameter for all interfaces except M1::I2.
fromβ adds the invoker's reference as the first parameter to the object implementation two-way functions. And if you use bothfromandthis, the invoker's reference parameter gets passed as the second parameter instead. This is what makes it possible for the implementation to respond to a request and keep executing afterwards β no cap. Consult thegen_serverand Orber docs for how you might use this one. π«Ά
The option comes in three varieties: from which activates the parameter for all interfaces in the source file, {from, IntfName} which activates the parameter for a specified interface, and {{from, IntfName}, false} which deactivates the parameter for a specified interface.
Example option: from) activates the parameter for all interfaces.
Example options: [{from, "M1::I1"}] activates the parameter for all functions of M1::I1.
Example options: [from, {{from, "M1::I2"}, false}] activates the parameter for all interfaces except M1::I2.
handle_infoβ makes the object server call a functionhandle_infoin the object implementation module on all unexpected messages. Super useful if your object implementation needs to trap exits. π¦
Example option: handle_info will activates module implementation handle_info for all interfaces in the source file.
Example option: {{handle_info, "M1::I1"}, true} will activates module implementation handle_info for the specified interface.
Example options: [handle_info, {{handle_info, "M1::I1"}, false}] will generate the handle_info call for all interfaces except M1::I1.
timeoutβ lets the user set a server response time limit. This should be a string that represents the scope for the interface which should have an extra variable for wait time initialization.
Example option: {timeout,"M::I"}) produces server stub which will has an extra timeout parameter in the initialization function for that interface.
Example option: timeout produces server stub which will has an extra timeout parameter in the initialization function for all interfaces in the source file.
Example options: [timeout, {{timeout,"M::I"}, false}] produces server stub which will has an extra timeout parameter in the initialization function for all interfaces except M1::I1.
scoped_op_callsβ used to produce more refined request calls to the server. When you set this totrue, the operation name mentioned in the call gets scoped. This is essential to avoid name clashes when talking to c-servers. It's available for the c-client, c-server and the Erlanggen_serverback ends. β Important: all the parts generated byichave to agree on the use of this option. Default isfalse.
Example options: [{be,c_genserv},{scoped_op_calls,true}]) produces client stubs which sends "scoped" requests to a gen_server or a c-server.
user_protocolβ used to define your own protocol, different from the default Erlang distribution +gen_serverprotocol. Currently only valid for C back-ends. For further details seeIC C protocol.
Example options: [{be,c_client},{user_protocol, "my_special"}]) produces client stubs which use C protocol functions with the prefix "my_special".
c_timeoutβ makes sends and receives have timeouts (C back-ends only). These timeouts are specified in milliseconds.
Example options: [{be,c_client},{c_timeout, {10000, 20000}}]) produces client stubs which use a 10 seconds send timeout, and a 20 seconds receive timeout.
c_reportβ generates code for writing encode/decode errors tostderr(C back-ends only). timeouts are specified in milliseconds.
Example options: [{be,c_client}, c_report]).
sclβ for compatibility with previous compiler versions up to3.3. So here's the tea: because of better semantic checks on enumerants, the compiler finds name clashes between user defined types and enumerant values in the same name space. Enable this option and the compiler turns off the extended semantic check on enumerant values. Default isfalse.
Example option: {scl,true}
precondβ adds a precondition call before the call to the operation implementation on the server side. π
The option comes in three varieties: {precond, {M, F}} which activates the call for operations in all interfaces in the source file, {{precond, IntfName}, {M, F}} which activates the call for all operations in a specific interface, and {{precond, OpName}, {M, F}} which activates the call for a specific operation.
The precondition function has the following signature m:f(Module, Function, Args).
Example option: {precond, {mod, fun}} adds the call of m:f for all operations in the idl file.
Example options: [{{precond, "M1::I"}, {mod, fun}}] adds the call of m:f for all operations in the interface M1::I1.
Example options: [{{precond, "M1::I::Op"}, {mod, fun}}] adds the call of m:f for the operation M1::I::Op.
postcondβ adds a postcondition call after the call to the operation implementation on the server side. β¨
The option comes in three varieties: {postcond, {M, F}} which activates the call for operations in all interfaces in the source file, {{postcond, IntfName}, {M, F}} which activates the call for all operations in a specific interface, and {{postcond, OpName}, {M, F}} which activates the call for a specific operation.
The postcondition function has the following signature m:f(Module, Function, Args, Result).
Example option: {postcond, {mod, fun}} adds the call of m:f for all operations in the idl file.
Example options: [{{postcond, "M1::I"}, {mod, fun}}] adds the call of m:f for all operations in the interface M1::I1.
Example options: [{{postcond, "M1::I::Op"}, {mod, fun}}] adds the call of m:f for the operation M1::I::Op.
π¨ WARNING OPTIONS π¨
Not me putting these in a separate lil section bc they're all about the yelling. π
'Wall'β activates all reasonable warning messages, in analogy with the gcc-Walloption. Default value istrue.maxerrsβ the maximum numbers of errors that can be detected before the compiler gives up. The option can either have an integer value or the atominfinity. Default number is10.maxwarnsβ the maximum numbers of warnings that can be detected before the compiler gives up. The option can either have an integer value or the atominfinity. Default value isinfinity.nowarnβ suppresses all warnings. Default value isfalse.warn_name_shadowβ a warning appears whenever names are shadowed due to inheritance; for example, if a type name is redefined from a base interface. β οΈ Note that it is illegal to overload operation and attribute names, as this causes an error to be produced. Default value istrue.pedanticβ activates all warning options. Default value isfalse.silentβ suppresses compiler printed output. Default value isfalse.
π BACK-END OPTIONS π
Which back-end IC will generate code for is determined by the supplied {be,atom()} option. If you leave it out, erl_corba is used. Currently, IC supports the following back-ends:
erl_corbaβ this option switches to the IDL generation for CORBA.erl_templateβ generate CORBA call-back module templates for each interface in the target IDL file. π Note, will overwrite existing files.erl_plainβ will produce plain Erlang modules which contain functions that map to the corresponding interface functions on the input file.erl_genservβ this is an IDL to Erlang generic server generation option.c_clientβ will produce a C client to the generic Erlang server.c_serverβ will produce a C server switch with functionality of a generic Erlang server.javaβ will produce Java client stubs with functionality of a generic Erlang server. βc_genservβ Deprecated. Usec_clientinstead. bestie pls upgrade π
π§ PREPROCESSOR π§
The IDL compiler allows several preprocessors to be used β the Erlang IDL preprocessor or other standard C preprocessors. Options can be used to provide extra flags such as include directories to the preprocessor. The build in the Erlang IDL preprocessor is used by default, but any standard C preprocessor such as gcc is adequate. π
The preprocessor command is formed by appending the prepoc_cmd to the preproc_flags option and then appending the input IDL file name.
π CONFIGURATION π
The compiler can be configured in two ways:
- Configuration file
- Command line options
The configuration file is optional and overrides the compiler defaults and is in turn overridden by the command line options. The configuration file shall contain options in the form of Erlang terms. The configuration file is read using file:consult.
An example of a configuration file, note the "." after each line. β
{outdir, gen_dir}.
{{impl, "M1::M2::object"}, "obj"}.
β¨ OUTPUT FILES β¨
okay bestie, this is the part where your hard work actually turns into stuff on disk πΎβ¨ The compiler will produce output in several files depending on scope declarations found in the IDL file.
At most three file types will be generated for each scope (and yes, that includes the top scope too π) β it all depends on the compiler back-end and the compiled interface.
Generally, the output per interface will be:
- a header file (
.hrl/.h) π - and one or more Erlang/C files (
.erl/.c) ποΈ
lowkey important: please look at the language mapping for each back-end for details, bestie β that's where the full tea is π«
Some things you can count on, fr fr:
- There will be at least one set of files for an IDL file, for the file level scope π
- Modules and interfaces also have their own set of generated files π
so yeah, one IDL file in, a whole little friend group of files out ππ¦ slay.
and that's the whole page, bestie!! π this beauty is from Ericsson AB, it's version ic 5.2.2, and it's living in section ic(3) β go forth and compile, you absolute icon πβ¨
π¦ where this page comes from
- fedora 43: erlang-ic 1:5.2.2-1.fc43 Β· Apache-2.0
- fedora 44: erlang-ic 1:5.2.2-1.fc44 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms