Search code examples
erlangrecords

Erlang: Location of *.hrl files in multiple applications


I'm developing a series of related applications that will eventually be integrated into a single release. Several of the applications share identical record structures.

Should I:

a) Duplicate the *.hrl files that define the record structure in the include directory of each of the applications? b) Put a single file somewhere else in my application tree--- and, if so where?

Here's my current tree:

zpt$
   apps
       app1
          ebin
          include
             myrecords.hrl
          priv
          src
       app2
          ebin
          include
             myrecords.hrl
          priv
          src
       etc

Many thanks,

LRP


Solution

  • One approach I tried was to create an application which doesn't do anything, but contains the record definitions common to multiple projects. Then I used rebar to include it as a dependency. When including the hrl files, I use the include_lib syntax. That syntax allows you to include hrl files from another application.

    app
        ebin
        include
        priv
        src
            some_src.erl
        deps
            common_hrl_app
                include
                    common_records.hrl
                src
                ebin
            other_dep_app
                src
                    other_src.erl
                .
                .
                .
    

    include_lib example which could appear in either some_src.erl or other_src.erl:

    -include_lib("common_hrl_app/include/common_records.hrl").
    

    I like this approach because:

    1. It plays nicely with the rebar dependency system
    2. It allows me to track the hrls in one place in version control
    3. I can version this application, which allows me to pull specific versions if I want a new application to be compatible with another using the same records.

    Answering questions from the comments:

    I have a skeleton app file in the ebin directory which specifies the name and version of the application so rebar can verify the version. Here's an example

    {application,common_hrl_app,
             [{description,[]},
              {vsn,"1"},
              {registered,[]},
              {applications,[kernel,stdlib]},
              {env,[]},
              {modules,[]}]}.
    

    With rebar, you have the top level application, which can have multiple applications as dependencies. When rebar fetches these dependencies, it places them in the deps directory. If any of those applications has their own dependencies, those are also fetched to the deps directory, and so on. There isn't an infinitely nested hierarchy of deps directories.