build_script.c 12.4 KB
Newer Older
Maxime Perrotin's avatar
Maxime Perrotin committed
1
/* Buildsupport is (c) 2008-2016 European Space Agency
Maxime Perrotin's avatar
Maxime Perrotin committed
2
3
4
5
 * contact: maxime.perrotin@esa.int
 * License is LGPL, check LICENSE file */
/* build_script.c

Maxime Perrotin's avatar
Maxime Perrotin committed
6
  this backend generates the build script that generates the binary files
Maxime Perrotin's avatar
Maxime Perrotin committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

  1st version 20 may 2009

  Copyright 2014-2015 IB Krates <info@krates.ee>
       QGenc code generator integration

 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <assert.h>

#include "my_types.h"
#include "practical_functions.h"
#include "c_ast_construction.h"


void Create_script()
{
    FILE *script = NULL;

    if (file_exists(".", "build-script.sh") && rename("build-script.sh", "build-script.sh.old")) {
        ERROR ("[ERROR] Unable to rename the existing 'build-script.sh' file. Check for permission.\n");
        exit(-1);
    }
    else {
        create_file (".", "build-script.sh", &script);
        ERROR ("[INFO] A build script (build-script.sh) has been created.\n"
                    "       The next time you will run 'taste-generate-skeletons' or 'buildsupport',\n"
                    "       this script will be renamed to 'build-script.sh.old' and replaced with a new, updated one.\n"
                    "       If applicable, do not forget to merge the two files before running the new script.\n\n");
        }

    assert (NULL != script);

    fprintf (script, "#!/bin/bash\n\n"
45
46
47
48
49
50
51
                     "# This script will build your TASTE system (by default with the C runtime).\n\n"
                     "# You should not change this file as it was automatically generated.\n\n"
                     "# If you need additional preprocessing, create a file named 'user_init_pre.sh'\n"
                     "# and/or 'user_init_post.sh - They will never get overwritten.'\n\n"
                     "# Inside these files you may set some environment variables:\n"
                     "#    C_INCLUDE_PATH=/usr/include/xenomai/analogy/:$C_INCLUDE_PATH\n"
                     "#    unset USE_POHIC   \n\n"
52
53
54
55
                     "if [ -f user_init_pre.sh ]\n"
                     "then\n"
                     "    echo [INFO] Executing user-defined init script\n"
                     "    source user_init_pre.sh\n"
56
57
58
59
60
61
62
63
64
65
66
67
68
69
                     "fi\n\n"
                     "# Use PolyORB-HI-C runtime\n"
                     "USE_POHIC=1\n\n"
                     "# Detect models from Ellidiss tools v2, and convert them to 1.3\n"
                     "INTERFACEVIEW=%s\n"
                     "grep \"version => \\\"2\" %s >/dev/null && {\n"
                     "    echo '[INFO] Converting interface view from V2 to V1.3'\n"
                     "    TASTE --load-interface-view %s --export-interface-view-to-1_3 __iv_1_3.aadl\n"
                     "    INTERFACEVIEW=__iv_1_3.aadl\n"
                     "};\n\n",
                     get_context()->ifview,
                     get_context()->ifview,
                     get_context()->ifview);

70

Maxime Perrotin's avatar
Maxime Perrotin committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

    /* The first step is to invoke QGen to generate code from user model */
    FOREACH (fv, FV, get_system_ast()->functions, {

        if (qgenada == fv->language) {

        FOREACH(i, Interface, fv->interfaces, {
            switch (i->direction) {
                case PI: {
                    fprintf (script, "\n");
                    fprintf (script, "# Call QGen to generate Ada code\n");
                    fprintf (script, "printf \"Calling QGen to generate Ada code from %s.mdl with the following command line:\\n\"\n", i->name);
                    fprintf (script, "printf \"qgenc %s.mdl --typing %s_types.txt --incremental --no-misra --language ada --output %s\\n\"\n", i->name, i->name, i->distant_qgen->fv_name);
                    fprintf (script, "printf \"Output from QGen\\n\\n\"\n");
                    fprintf (script, "qgenc %s.mdl --typing %s_types.txt --incremental --no-misra --language ada --output %s\n", i->name, i->name, fv->name);
                    fprintf (script, "printf \"\\nEnd of output from QGen\\n\\n\"\n\n");
                    } break;
                case RI: break;
                default: break;
            }
        });
        }

        else if (qgenc == fv->language) {

        FOREACH(i, Interface, fv->interfaces, {
            switch (i->direction) {
                case PI: {
                    fprintf (script, "\n");
                    fprintf (script, "# Call QGen to generate C code\n");
                    fprintf (script, "printf \"Calling QGen to generate C code from %s.mdl with the following command line:\\n\"\n", i->name);
                    fprintf (script, "printf \"qgenc %s.mdl --typing %s_types.txt --incremental --no-misra --language c --output %s\\n\"\n", i->name, i->name, i->distant_qgen->fv_name);
                    fprintf (script, "printf \"Output from QGen\\n\\n\"\n");
                    fprintf (script, "qgenc %s.mdl --typing %s_types.txt --incremental --no-misra --language c --output %s\n\n", i->name, i->name, fv->name);
                    fprintf (script, "printf \"\\nEnd of output from QGen\\n\\n\"\n\n");
                    fprintf (script, "# Add QGen generated C code to C_INCLUDE_PATH\n");
                    fprintf (script, "export C_INCLUDE_PATH=../../%s/%s/:$C_INCLUDE_PATH\n", fv->name, fv->name);
                    } break;
                case RI: break;
                default: break;
            }
        });
        }
    });

    fprintf (script, "if [ -z \"$DEPLOYMENTVIEW\" ]\n"
                     "then\n"
                     "    DEPLOYMENTVIEW=DeploymentView.aadl\n"
119
120
121
122
123
124
125
126
                     "fi\n\n" 
                     "# Detect models from Ellidiss tools v2, and convert them to 1.3\n"
                     "grep \"version => \\\"2\" \"$DEPLOYMENTVIEW\" >/dev/null && {\n"
                     "    echo '[INFO] Converting deployment view from V2 to V1.3'\n"
                     "    TASTE --load-deployment-view \"$DEPLOYMENTVIEW\" --export-deployment-view-to-1_3 __dv_1_3.aadl\n"
                     "    DEPLOYMENTVIEW=__dv_1_3.aadl\n"
                     "};\n\n");

Maxime Perrotin's avatar
Maxime Perrotin committed
127
128
129

    fprintf (script, "SKELS=\"%s\"\n\n", OUTPUT_PATH);

Maxime Perrotin's avatar
Maxime Perrotin committed
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    fprintf (script, "# Update the data view with local paths\n"
                     "taste-update-data-view\n\n");

    /* OpenGEODE-specific: call code generator on the fly */
    FOREACH (fv, FV, get_system_ast()->functions, {
        if (sdl == fv->language) {
            fprintf(script,
                    "# Generate code for OpenGEODE function %s\n"
                    "cd \"$SKELS\"/%s && "
                    "opengeode --toAda %s.pr system_structure.pr "
                    "&& cd $OLDPWD\n\n",
                    fv->name, fv->name, fv->name);
        }
    });

Maxime Perrotin's avatar
Maxime Perrotin committed
145
146
147
148
149
    /* VDM-Specific: call code generator and B mappers */
    FOREACH (fv, FV, get_system_ast()->functions, {
        if (vdm == fv->language) {
            fprintf(script,
                    "# Generate code for VDM function %s\n"
Maxime Perrotin's avatar
Maxime Perrotin committed
150
                    "# cd \"$SKELS\"/%s && "
Maxime Perrotin's avatar
Maxime Perrotin committed
151
152
153
154
155
156
157
                    "vdm2c %s.vdmpp %s_Interface.vdmpp out.vdm"
                    "&& cd $OLDPWD\n\n",
                    fv->name, fv->name, fv->name, fv->name);
        }
        /* TODO call B mappers or add --subVdm in orchestrator */
    });

Maxime Perrotin's avatar
Maxime Perrotin committed
158
159
160
161
162
163
164
    /* Remove old zip files and create fresh new ones from user code */
    FOREACH (fv, FV, get_system_ast()->functions, {
        //if (sdl != fv->language  PUT BACK WHEN OPENGEODE FULLY SUPPORTED
        if (vhdl != fv->language
            && gui != fv->language
            && rtds != fv->language
            && NULL == fv->zipfile) {
Maxime Perrotin's avatar
Maxime Perrotin committed
165
166
167
168
            fprintf (script,
                    "cd \"$SKELS\" && rm -f %s.zip && "
                    "zip %s %s/* && cd $OLDPWD\n\n",
                    fv->name, fv->name, fv->name);
Maxime Perrotin's avatar
Maxime Perrotin committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
        }
    })

    fprintf (script, "[ ! -z \"$CLEANUP\" ] && rm -rf binary\n\n");

    fprintf (script, "if [ -f ConcurrencyView.pro ]\n"
                     "then\n"
                     "    ORCHESTRATOR_OPTIONS+=\" -w ConcurrencyView.pro \"\n"
                     "fi\n\n"
                     "if [ ! -z \"$USE_POHIC\" ]\n"
                     "then\n"
                     "    OUTPUTDIR=binary.c\n"
                     "    ORCHESTRATOR_OPTIONS+=\" -p \"\n"
                     "elif [ ! -z \"$USE_POHIADA\" ]\n"
                     "then\n"
                     "    OUTPUTDIR=binary.ada\n"
                     "else\n"
                     "    OUTPUTDIR=binary\n"
187
                     "fi\n\n"
Maxime Perrotin's avatar
Maxime Perrotin committed
188
189
                     );

190
191
192
193
194
195
196
    fprintf (script, "if [ -f user_init_post.sh ]\n"
                     "then\n"
                     "    echo [INFO] Executing user-defined init script\n"
                     "    source user_init_post.sh\n"
                     "fi\n\n"
                     "assert-builder-ocarina.py \\\n"
                     "\t--fast \\\n"
Maxime Perrotin's avatar
Maxime Perrotin committed
197
198
199
200
201
202
203
204
205
                     "\t--debug \\\n");

    if (get_context()->polyorb_hi_c)
        fprintf (script,"\t--with-polyorb-hi-c \\\n");
    if (get_context()->aadlv2)
        fprintf (script, "\t--aadlv2 \\\n");
    if (get_context()->keep_case)
        fprintf (script, "\t--keep-case \\\n");

206
    fprintf (script, "\t--interfaceView \"$INTERFACEVIEW\" \\\n");
Maxime Perrotin's avatar
Maxime Perrotin committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

    /* When invoked with -gw, we do not know the exact name of the deployment view
       -> we assume that it's the default spelling given by TASTE-IV */
    fprintf (script, "\t--deploymentView \"$DEPLOYMENTVIEW\" \\\n");

    fprintf (script, "\t-o \"$OUTPUTDIR\"");

    FOREACH (fv, FV, get_system_ast()->functions, {

        if (gui != fv->language) {
            fprintf (script, " \\\n\t");

            switch (fv->language) {
                //case sdl: fprintf (script, "--subOG ");   UNCOMMENT WHEN OPENGEODE FULLY SUPPORTED
                //      break;
                case scade: fprintf (script, "--subSCADE ");
                      break;
                case simulink: fprintf (script, "--subSIMULINK ");
                      break;
                case rtds: fprintf (script, "--subRTDS ");
                      break;
                case c:
Maxime Perrotin's avatar
Maxime Perrotin committed
229
                case vdm:
Maxime Perrotin's avatar
Maxime Perrotin committed
230
231
232
233
234
235
                case blackbox_device:
                    fprintf (script, "--subC ");
                    break;
                case cpp:
                    fprintf (script, "--subCPP ");
                    break;
Maxime Perrotin's avatar
Maxime Perrotin committed
236
                case sdl:
Maxime Perrotin's avatar
Maxime Perrotin committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
                case ada: fprintf (script, "--subAda ");
                      break;
                case vhdl: fprintf (script, "--subVHDL ");
                      break;
                case qgenada: fprintf (script, "--subQGenAda ");
                      break;
                case qgenc: fprintf (script, "--subQGenC ");
                      break;
                default:
                     ERROR ("** Error: unsupported language (function %s)\n", fv->name);
                     ERROR ("  -> please manually check the build-script.sh file\n");
                     break;
            }

            fprintf (script, "%s", fv->name);
            /* ObjectGEODE systems are treated differently from all other languages,
               because it directly refers to .pr files, instead of zip files 
            if (sdl == fv->language) { UNCOMMENT WHEN OPENGEODE FULLY SUPPORTED
                fprintf (script, ":\"$SKELS\"/%s/system_implementation.pr, \"$SKELS\"/%s/system_structure.pr, \"$SKELS\"/%s/DataView.pr",
                fv->name, 
                fv->name, 
                fv->name);
            } */
            /*else*/
            if (rtds == fv->language && NULL == fv->zipfile) {
                fprintf (script, ":\"$SKELS\"/%s/%s.zip", fv->name, fv->name);
            }
            else if (NULL != fv->zipfile) {
                fprintf (script, ":\"$SKELS\"/%s", fv->zipfile);
            }
            else if (vhdl != fv->language) {
                fprintf(script, ":\"$SKELS\"/%s.zip", fv->name);
            }
        }

    })
Maxime Perrotin's avatar
Maxime Perrotin committed
273
274
275
276
277
278
279
280
281
282
    /* If node is configured with code coverage flag, set the option */
    FOREACH (process, Process, get_system_ast()->processes, {
        if (true == process->coverage) {
            fprintf(script,
                    " \\\n\t--nodeOptions %s@gcov=on",
                    process->name);
        }
    });

    /* Let user add custom orchestrator flags */
Maxime Perrotin's avatar
Maxime Perrotin committed
283
284
285
286
    fprintf (script, " \\\n\t$ORCHESTRATOR_OPTIONS\n");
    close_file(&script);

    if (chmod ("build-script.sh", S_IRWXG | S_IRWXO | S_IRWXU)) {
Maxime Perrotin's avatar
Maxime Perrotin committed
287
        fprintf (stderr, "Warning: Unable to change mode of build-script.sh to make it executable\n");
Maxime Perrotin's avatar
Maxime Perrotin committed
288
289
290
291
292
293
294
295
296
297
298
    }
}


/* External interface */
void Generate_Build_Script()
{
    if (get_context()->gw && !get_context()->glue && !get_context()->onlycv) {
    Create_script();
    }
}