1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
15 #if defined SOLARIS || defined SOLARIS8
16 #include <sys/utsname.h>
19 #include "../common/memory.h"
20 #include "../common/path.h"
21 #include "../common/version_internal.h"
22 #include "../common/userinfo.h"
23 #include "ttcn3/ttcn3_preparser.h"
24 #include "asn1/asn1_preparser.h"
27 #include "../common/license.h"
32 static const char *program_name
= NULL
;
33 static unsigned int error_count
= 0;
34 static boolean suppress_warnings
= FALSE
;
35 void free_string2_list(struct string2_list
* act_elem
);
36 void free_string_list(struct string_list
* act_elem
);
37 void ERROR(const char *fmt
, ...)
40 fprintf(stderr
, "%s: error: ", program_name
);
41 va_start(parameters
, fmt
);
42 vfprintf(stderr
, fmt
, parameters
);
44 fprintf(stderr
, "\n");
49 void WARNING(const char *fmt
, ...)
52 if (suppress_warnings
) return;
53 fprintf(stderr
, "%s: warning: ", program_name
);
54 va_start(parameters
, fmt
);
55 vfprintf(stderr
, fmt
, parameters
);
61 void NOTIFY(const char *fmt
, ...)
64 va_start(parameters
, fmt
);
65 vfprintf(stderr
, fmt
, parameters
);
71 void DEBUG(unsigned level
, const char *fmt
, ...)
74 fprintf(stderr
, "%*s", 2 * level
, "");
75 va_start(parameters
, fmt
);
76 vfprintf(stderr
, fmt
, parameters
);
82 void path_error(const char *fmt
, ...)
87 err_msg
= mprintf_va_list(fmt
, ap
);
94 #if defined SOLARIS || defined SOLARIS8
95 /** Automatic detection of Solaris version based on uname() system call.
96 * Distinguishing is needed because some socket functions use socklen_t
97 * (which is an alias for unsigned int) as length arguments on Solaris 8.
98 * On Solaris 2.6 the argument type is simply int and no socklen_t or other
100 * Note: It was discovered later that Solaris 7 (which is used rarely within
101 * Ericsson) already uses socklen_t thus the SOLARIS8 platform identifier is a
103 static const char *get_platform_string(void)
107 if (uname(&name
) < 0) {
108 WARNING("System call uname() failed: %s", strerror(errno
));
112 if (sscanf(name
.release
, "%d.%d", &major
, &minor
) == 2 && major
== 5) {
113 if (minor
<= 6) return "SOLARIS";
114 else return "SOLARIS8";
116 ERROR("Invalid OS release: %s", name
.release
);
121 #define get_platform_string() "LINUX"
122 #elif defined FREEBSD
123 #define get_platform_string() "FREEBSD"
125 #define get_platform_string() "WIN32"
126 #elif defined INTERIX
127 #define get_platform_string() "INTERIX"
129 #error Platform was not set.
132 /** structure for describing TTCN-3 and ASN.1 modules */
133 struct module_struct
{
134 char *dir_name
; /* directory of the TTCN-3 or ASN.1 file, it is NULL if the
135 file is in the current working directory */
136 char *file_name
; /* name of the TTCN-3 or ASN.1 file */
137 char *module_name
; /* name of the TTCN-3 or ASN.1 module */
138 boolean is_regular
; /* indicates whether the name of the source file follows
139 the default naming convention */
142 /** structure for describing test ports and other C/C++ modules */
144 char *dir_name
; /* directory of the C/C++ source files, it is NULL if the
145 files are in the current working directory */
146 char *file_prefix
; /* the common prefix of the header and source file */
147 char *header_name
; /* name of the C/C++ header file, which has .hh or .h or .hpp
148 suffix, it is NULL if there is no header file */
149 char *source_name
; /* name of the C/C++ source file, which has .cc or .c or .cpp
150 suffix, it is NULL if there is no source file */
151 boolean has_hh_suffix
; /* indicates whether the header file is present and
152 has .hh or .hpp suffix */
153 boolean has_cc_suffix
; /* indicates whether the source file is present and
154 has .cc or .cpp suffix */
157 /** structure for directories that pre-compiled files are taken from */
158 struct base_dir_struct
{
159 const char *dir_name
; /* name of the directory */
160 boolean has_modules
; /* indicates whether there are TTCN-3/ASN.1 modules in
161 the directory (it is set to FALSE if dir_name
162 contains user C/C++ files only */
165 /** data structure that describes the information needed for the Makefile */
166 struct makefile_struct
{
168 size_t nTTCN3Modules
;
169 struct module_struct
*TTCN3Modules
;
172 size_t nTTCN3PPModules
;
173 struct module_struct
*TTCN3PPModules
;
175 boolean TTCN3ModulesRegular
;
176 boolean BaseTTCN3ModulesRegular
;
177 size_t nTTCN3IncludeFiles
;
178 char **TTCN3IncludeFiles
;
181 struct module_struct
*ASN1Modules
;
182 boolean ASN1ModulesRegular
;
183 boolean BaseASN1ModulesRegular
;
186 struct user_struct
*UserFiles
;
187 boolean UserHeadersRegular
;
188 boolean UserSourcesRegular
;
189 boolean BaseUserHeadersRegular
;
190 boolean BaseUserSourcesRegular
;
195 boolean central_storage
;
197 struct base_dir_struct
*BaseDirs
;
203 boolean force_overwrite
;
204 boolean use_runtime_2
;
207 char *code_splitting_mode
;
209 char *tcov_file_name
;
210 struct string_list
* profiled_file_list
; /* not owned */
212 boolean linkingStrategy
;
213 boolean hierarchical
;
214 struct string_list
* sub_project_dirs
; /* not owned */
215 struct string_list
* ttcn3_prep_includes
; /* not owned */
216 struct string_list
* ttcn3_prep_defines
; /* not owned */
217 struct string_list
* ttcn3_prep_undefines
; /* not owned */
218 struct string_list
* prep_includes
; /* not owned */
219 struct string_list
* prep_defines
; /* not owned */
220 struct string_list
* prep_undefines
; /* not owned */
221 boolean codesplittpd
;
223 boolean disablesubtypecheck
;
224 const char *cxxcompiler
;
225 const char *optlevel
;
226 const char *optflags
;
232 boolean forcexerinasn
;
233 boolean defaultasomit
;
234 boolean gccmsgformat
;
235 boolean linenumbersonlymsg
;
236 boolean includesourceinfo
;
237 boolean addsourcelineinfo
;
238 boolean suppresswarnings
;
239 boolean outparamboundness
;
240 boolean omit_in_value_list
;
241 boolean warnings_for_bad_variants
;
242 boolean disable_predef_ext_folder
;
243 struct string_list
* solspeclibraries
; /* not owned */
244 struct string_list
* sol8speclibraries
; /* not owned */
245 struct string_list
* linuxspeclibraries
; /* not owned */
246 struct string_list
* freebsdspeclibraries
; /* not owned */
247 struct string_list
* win32speclibraries
; /* not owned */
248 const char *ttcn3preprocessor
;
249 struct string_list
* linkerlibraries
; /* not owned */
250 struct string_list
* additionalObjects
; /* not owned */
251 struct string_list
* linkerlibsearchpath
; /* not owned */
252 char* generatorCommandOutput
; /* not owned */
253 struct string2_list
* target_placement_list
; /* not owned */
256 /** Initializes structure \a makefile with empty lists and default settings. */
257 static void init_makefile_struct(struct makefile_struct
*makefile
)
259 makefile
->project_name
= NULL
;
260 makefile
->nTTCN3Modules
= 0;
261 makefile
->TTCN3Modules
= NULL
;
262 makefile
->preprocess
= FALSE
;
263 makefile
->nTTCN3PPModules
= 0;
264 makefile
->TTCN3PPModules
= NULL
;
265 makefile
->TTCN3ModulesRegular
= TRUE
;
266 makefile
->BaseTTCN3ModulesRegular
= TRUE
;
267 makefile
->nTTCN3IncludeFiles
= 0;
268 makefile
->TTCN3IncludeFiles
= NULL
;
269 makefile
->nASN1Modules
= 0;
270 makefile
->ASN1Modules
= NULL
;
271 makefile
->ASN1ModulesRegular
= TRUE
;
272 makefile
->BaseASN1ModulesRegular
= TRUE
;
273 makefile
->nUserFiles
= 0;
274 makefile
->UserFiles
= NULL
;
275 makefile
->UserHeadersRegular
= TRUE
;
276 makefile
->UserSourcesRegular
= TRUE
;
277 makefile
->BaseUserHeadersRegular
= TRUE
;
278 makefile
->BaseUserSourcesRegular
= TRUE
;
279 makefile
->nOtherFiles
= 0;
280 makefile
->OtherFiles
= NULL
;
281 makefile
->central_storage
= FALSE
;
282 makefile
->nBaseDirs
= 0;
283 makefile
->BaseDirs
= NULL
;
284 makefile
->working_dir
= get_working_dir();
285 makefile
->gnu_make
= FALSE
;
286 makefile
->single_mode
= FALSE
;
287 makefile
->ets_name
= NULL
;
288 makefile
->output_file
= NULL
;
289 makefile
->force_overwrite
= FALSE
;
290 makefile
->use_runtime_2
= FALSE
;
291 makefile
->dynamic
= FALSE
;
292 makefile
->gcc_dep
= FALSE
;
293 makefile
->code_splitting_mode
= NULL
;
294 makefile
->coverage
= FALSE
;
295 makefile
->tcov_file_name
= NULL
;
296 makefile
->profiled_file_list
= NULL
;
297 makefile
->library
= FALSE
;
298 makefile
->linkingStrategy
= FALSE
;
299 makefile
->hierarchical
= FALSE
;
300 makefile
->sub_project_dirs
= NULL
;
301 makefile
->ttcn3_prep_includes
= NULL
;
302 makefile
->prep_includes
= NULL
;
303 makefile
->prep_defines
= NULL
;
304 makefile
->outparamboundness
= FALSE
;
305 makefile
->omit_in_value_list
= FALSE
;
306 makefile
->warnings_for_bad_variants
= FALSE
;
307 makefile
->solspeclibraries
= NULL
;
308 makefile
->sol8speclibraries
= NULL
;
309 makefile
->linuxspeclibraries
= NULL
;
310 makefile
->freebsdspeclibraries
= NULL
;
311 makefile
->win32speclibraries
= NULL
;
312 makefile
->linkerlibraries
= NULL
;
313 makefile
->additionalObjects
= NULL
;
314 makefile
->linkerlibsearchpath
= NULL
;
315 makefile
->generatorCommandOutput
= NULL
;
316 makefile
->target_placement_list
= NULL
;
319 /** Deallocates all memory associated with structure \a makefile. */
320 static void free_makefile_struct(const struct makefile_struct
*makefile
)
322 Free(makefile
->project_name
);
324 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
325 Free(makefile
->TTCN3Modules
[i
].dir_name
);
326 Free(makefile
->TTCN3Modules
[i
].file_name
);
327 Free(makefile
->TTCN3Modules
[i
].module_name
);
329 Free(makefile
->TTCN3Modules
);
330 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
331 Free(makefile
->TTCN3PPModules
[i
].dir_name
);
332 Free(makefile
->TTCN3PPModules
[i
].file_name
);
333 Free(makefile
->TTCN3PPModules
[i
].module_name
);
335 Free(makefile
->TTCN3PPModules
);
336 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
337 Free(makefile
->TTCN3IncludeFiles
[i
]);
338 Free(makefile
->TTCN3IncludeFiles
);
339 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
340 Free(makefile
->ASN1Modules
[i
].dir_name
);
341 Free(makefile
->ASN1Modules
[i
].file_name
);
342 Free(makefile
->ASN1Modules
[i
].module_name
);
344 Free(makefile
->ASN1Modules
);
345 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
346 Free(makefile
->UserFiles
[i
].dir_name
);
347 Free(makefile
->UserFiles
[i
].file_prefix
);
348 Free(makefile
->UserFiles
[i
].header_name
);
349 Free(makefile
->UserFiles
[i
].source_name
);
351 Free(makefile
->UserFiles
);
352 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) Free(makefile
->OtherFiles
[i
]);
353 Free(makefile
->OtherFiles
);
354 Free(makefile
->BaseDirs
);
355 Free(makefile
->working_dir
);
356 Free(makefile
->ets_name
);
357 Free(makefile
->output_file
);
358 Free(makefile
->code_splitting_mode
);
359 Free(makefile
->tcov_file_name
);
362 /** Displays the contents of structure \a makefile as debug messages. */
363 static void dump_makefile_struct(const struct makefile_struct
*makefile
,
367 DEBUG(level
, "Data used for Makefile generation:");
368 DEBUG(level
+ 1, "TTCN-3 project name: %s", makefile
->project_name
);
369 DEBUG(level
+ 1, "TTCN-3 modules: (%u pcs.)", makefile
->nTTCN3Modules
);
370 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
371 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
372 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
373 if (module
->dir_name
!= NULL
)
374 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
375 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
376 DEBUG(level
+ 3, "Follows the naming convention: %s",
377 module
->is_regular
? "yes" : "no");
379 DEBUG(level
+ 1, "TTCN-3 preprocessing: %s",
380 makefile
->preprocess
? "yes" : "no");
381 if (makefile
->preprocess
) {
382 DEBUG(level
+ 1, "TTCN-3 modules to be preprocessed: (%u pcs.)",
383 makefile
->nTTCN3PPModules
);
384 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
385 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
386 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
387 if (module
->dir_name
!= NULL
)
388 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
389 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
390 DEBUG(level
+ 3, "Follows the naming convention: %s",
391 module
->is_regular
? "yes" : "no");
393 DEBUG(level
+ 1, "TTCN-3 include files: (%u pcs.)",
394 makefile
->nTTCN3IncludeFiles
);
395 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
396 DEBUG(level
+ 2, "File name: %s", makefile
->TTCN3IncludeFiles
[i
]);
398 DEBUG(level
+ 1, "All local TTCN-3 modules follow the naming convention: %s",
399 makefile
->TTCN3ModulesRegular
? "yes" : "no");
400 if (makefile
->central_storage
) DEBUG(level
+ 1, "All TTCN-3 modules from other "
401 "directories follow the naming convention: %s",
402 makefile
->BaseTTCN3ModulesRegular
? "yes" : "no");
403 DEBUG(level
+ 1, "ASN.1 modules: (%u pcs.)", makefile
->nASN1Modules
);
404 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
405 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
406 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
407 if (module
->dir_name
!= NULL
)
408 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
409 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
410 DEBUG(level
+ 3, "Follows the naming convention: %s",
411 module
->is_regular
? "yes" : "no");
413 DEBUG(level
+ 1, "All local ASN.1 modules follow the naming convention: %s",
414 makefile
->ASN1ModulesRegular
? "yes" : "no");
415 if (makefile
->central_storage
) DEBUG(level
+ 1, "All ASN.1 modules from other "
416 "directories follow the naming convention: %s",
417 makefile
->BaseASN1ModulesRegular
? "yes" : "no");
418 DEBUG(level
+ 1, "User C/C++ modules: (%u pcs.)", makefile
->nUserFiles
);
419 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
420 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
421 DEBUG(level
+ 2, "File prefix: %s", user
->file_prefix
);
422 if (user
->dir_name
!= NULL
)
423 DEBUG(level
+ 3, "Directory: %s", user
->dir_name
);
424 if (user
->header_name
!= NULL
) {
425 DEBUG(level
+ 3, "Header file: %s", user
->header_name
);
426 DEBUG(level
+ 3, "Header file has .hh or .hpp suffix: %s",
427 user
->has_hh_suffix
? "yes" : "no");
429 if (user
->source_name
!= NULL
) {
430 DEBUG(level
+ 3, "Source file: %s", user
->source_name
);
431 DEBUG(level
+ 3, "Source file has .cc or .cpp suffix: %s",
432 user
->has_cc_suffix
? "yes" : "no");
433 DEBUG(level
+ 3, "Object file: %s.o", user
->file_prefix
);
436 DEBUG(level
+ 1, "All local C/C++ header files follow the naming "
437 "convention: %s", makefile
->UserHeadersRegular
? "yes" : "no");
438 DEBUG(level
+ 1, "All local C/C++ source files follow the naming "
439 "convention: %s", makefile
->UserSourcesRegular
? "yes" : "no");
440 if (makefile
->central_storage
) {
441 DEBUG(level
+ 1, "All C/C++ header files from other directories follow the "
442 "naming convention: %s", makefile
->BaseUserHeadersRegular
? "yes" : "no");
443 DEBUG(level
+ 1, "All C/C++ source files from other directories follow the "
444 "naming convention: %s", makefile
->BaseUserSourcesRegular
? "yes" : "no");
446 DEBUG(level
+ 1, "Other files: (%u pcs.)", makefile
->nOtherFiles
);
447 for (i
= 0; i
< makefile
->nOtherFiles
; i
++)
448 DEBUG(level
+ 2, "File name: %s", makefile
->OtherFiles
[i
]);
449 DEBUG(level
+ 1, "Use pre-compiled files from central storage: %s",
450 makefile
->central_storage
? "yes" : "no");
451 if (makefile
->central_storage
) {
452 DEBUG(level
+ 1, "Directories of pre-compiled files: (%u pcs.)",
453 makefile
->nBaseDirs
);
454 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
455 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
456 DEBUG(level
+ 2, "Directory: %s", base_dir
->dir_name
);
457 DEBUG(level
+ 3, "Has TTCN-3/ASN.1 modules: %s",
458 base_dir
->has_modules
? "yes" : "no");
461 DEBUG(level
+ 1, "Working directory: %s",
462 makefile
->working_dir
!= NULL
? makefile
->working_dir
: "<unknown>");
463 DEBUG(level
+ 1, "GNU make: %s", makefile
->gnu_make
? "yes" : "no");
464 DEBUG(level
+ 1, "Execution mode: %s",
465 makefile
->single_mode
? "single" : "parallel");
466 DEBUG(level
+ 1, "Name of executable: %s",
467 makefile
->ets_name
!= NULL
? makefile
->ets_name
: "<unknown>");
468 DEBUG(level
+ 1, "Output file: %s",
469 makefile
->output_file
!= NULL
? makefile
->output_file
: "<unknown>");
470 DEBUG(level
+ 1, "Force overwrite: %s",
471 makefile
->force_overwrite
? "yes" : "no");
472 DEBUG(level
+ 1, "Use function test runtime: %s",
473 makefile
->use_runtime_2
? "yes" : "no");
474 DEBUG(level
+ 1, "Use dynamic linking: %s",
475 makefile
->dynamic
? "yes" : "no");
476 DEBUG(level
+ 1, "Code splitting mode: %s",
477 makefile
->code_splitting_mode
!= NULL
?
478 makefile
->code_splitting_mode
: "<unknown>");
479 DEBUG(level
+ 1, "Code coverage file: %s",
480 makefile
->tcov_file_name
!= NULL
?
481 makefile
->tcov_file_name
: "<unknown>");
482 if (makefile
->profiled_file_list
) {
483 char* lists
= mcopystr(makefile
->profiled_file_list
->str
);
484 struct string_list
* iter
= makefile
->profiled_file_list
->next
;
485 while(iter
!= NULL
) {
486 lists
= mputprintf(lists
, " %s", iter
->str
);
489 DEBUG(level
+ 1, "Profiled file list(s): %s", lists
);
492 #ifdef COVERAGE_BUILD
493 DEBUG(level
+ 1, "Enable coverage: %s", makefile
->coverage
? "yes" : "no");
497 /** Returns the name of an existing file that is related to command line
498 * argument \a argument. Tries the given list of suffixes. NULL pointer is
499 * returned if no file was found. The returned string shall be deallocated
501 static char *get_file_name_for_argument(const char *argument
)
503 static const char * const suffix_list
[] = {
504 "", ".ttcnpp", ".ttcnin", ".ttcn", ".ttcn3", ".3mp", ".asn", ".asn1",
505 ".cc", ".c", ".cpp", ".hh", ".h",".hpp", ".cfg", ".prj", NULL
507 const char * const *suffix_ptr
;
508 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
509 char *file_name
= mputstr(mcopystr(argument
), *suffix_ptr
);
510 if (get_path_status(file_name
) == PS_FILE
) return file_name
;
516 /** Converts \a path_name to an absolute directory using \a working_dir.
517 * NULL pointer is returned if \a path_name does not contain a directory or
518 * the resulting absolute directory is identical to \a working_dir.
519 * The returned string shall be deallocated by the caller. */
520 static char *get_dir_name(const char *path_name
, const char *working_dir
)
522 char *dir_name
= get_dir_from_path(path_name
);
523 if (dir_name
!= NULL
) {
524 char *absolute_dir
= get_absolute_dir(dir_name
, working_dir
, TRUE
);
526 if (absolute_dir
== NULL
|| working_dir
== NULL
) {
527 /* an error occurred */
529 } else if (!strcmp(absolute_dir
, working_dir
)) {
530 /* the directory is identical to the working dir */
533 } else return absolute_dir
;
537 /** Returns whether \a dirname1 and \a dirname2 contain the same (canonized
538 * absolute) directories. NULL pointer is handled in a special way: it is
539 * identical only to itself. */
540 static boolean
is_same_directory(const char *dirname1
, const char *dirname2
)
542 if (dirname1
== NULL
) {
543 if (dirname2
== NULL
) return TRUE
;
546 if (dirname2
== NULL
) return FALSE
;
547 else if (strcmp(dirname1
, dirname2
)) return FALSE
;
552 /** Returns whether the file \a filename1 in directory \a dirname1 is identical
553 * to file \a filename2 in directory \a dirname2. Only the directory names can
555 static boolean
is_same_file(const char *dirname1
, const char *filename1
,
556 const char *dirname2
, const char *filename2
)
558 /* first examine the file names for efficiency reasons */
559 if (strcmp(filename1
, filename2
)) return FALSE
;
560 else return is_same_directory(dirname1
, dirname2
);
563 /** Determines whether the TTCN-3 or ASN.1 module identifiers \a module1 and
564 * \a module2 are the same. Characters '-' and '_' in module names are not
566 static boolean
is_same_module(const char *module1
, const char *module2
)
570 switch (module1
[i
]) {
572 if (module2
[i
] == '\0') return TRUE
;
576 if (module2
[i
] != '-' && module2
[i
] != '_') return FALSE
;
579 if (module1
[i
] != module2
[i
]) return FALSE
;
583 return FALSE
; /* to avoid warnings */
586 /** Determines the suffix (i.e. the character sequence following the last dot)
587 * of file or path name \a file_name. NULL pointer is returned if \a file_name
588 * does not contain any dot character or the last character of it is a dot.
589 * The suffix is not copied, the returned pointer points to the tail of
591 static const char *get_suffix(const char *file_name
)
593 size_t last_dot
= (size_t)-1;
595 for (i
= 0; file_name
[i
] != '\0'; i
++)
596 if (file_name
[i
] == '.') last_dot
= i
;
597 if (last_dot
== (size_t)-1 || file_name
[last_dot
+ 1] == '\0') return NULL
;
598 else return file_name
+ last_dot
+ 1;
601 /** Truncates the suffix (i.e. the last dot and the characters following it)
602 * from \a file_name and returns a copy of the prefix of \a file_name.
603 * If \a file_name does not have a suffix an exact copy of it is returned.
604 * The returned string shall be deallocated by the caller. */
605 static char *cut_suffix(const char *file_name
)
608 size_t last_dot
= (size_t)-1;
610 for (i
= 0; file_name
[i
] != '\0'; i
++)
611 if (file_name
[i
] == '.') last_dot
= i
;
612 ret_val
= mcopystr(file_name
);
613 if (last_dot
!= (size_t)-1) ret_val
= mtruncstr(ret_val
, last_dot
);
617 /** Determines the name of the preprocessed file from \a file_name.
618 * It is assumed that \a file_name has ttcnpp suffix.
619 * The returned string shall be deallocated by the caller. */
620 static char *get_preprocessed_file_name(const char *file_name
)
622 char *ret_val
= cut_suffix(file_name
);
623 ret_val
= mputstr(ret_val
, ".ttcn");
627 /** Check if any of the preprocessed ttcn file names with the preprocessed
628 * (TTCN-3) suffix is equal to any other file given in the \a makefile */
629 static void check_preprocessed_filename_collision(
630 struct makefile_struct
*makefile
)
633 if (makefile
->nTTCN3PPModules
== 0) {
634 WARNING("TTCN-3 preprocessing (option `-p') is enabled, but no TTCN-3 "
635 "files to be preprocessed were given for the Makefile.");
637 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
638 const struct module_struct
*pp_module
= makefile
->TTCN3PPModules
+ i
;
639 /* name of the intermediate preprocessed file */
640 char *preprocessed_name
= get_preprocessed_file_name(pp_module
->file_name
);
642 for (j
= 0; j
< makefile
->nTTCN3Modules
; j
++) {
643 struct module_struct
*module
= makefile
->TTCN3Modules
+ j
;
644 if (is_same_file(pp_module
->dir_name
, preprocessed_name
,
645 module
->dir_name
, module
->file_name
)) {
646 if (is_same_module(pp_module
->module_name
, module
->module_name
)) {
647 /* same file with the same module */
648 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
649 pp_module
->file_name
);
650 char *m_pathname
= compose_path_name(module
->dir_name
,
652 WARNING("File `%s' containing TTCN-3 module `%s' is generated by "
653 "the preprocessor from `%s'. Removing the file from the list of "
654 "normal TTCN-3 modules.", m_pathname
, module
->module_name
,
658 Free(module
->dir_name
);
659 Free(module
->file_name
);
660 Free(module
->module_name
);
661 makefile
->nTTCN3Modules
--;
662 memmove(module
, module
+ 1, (makefile
->nTTCN3Modules
- j
) *
663 sizeof(*makefile
->TTCN3Modules
));
664 makefile
->TTCN3Modules
=
665 (struct module_struct
*)Realloc(makefile
->TTCN3Modules
,
666 makefile
->nTTCN3Modules
* sizeof(*makefile
->TTCN3Modules
));
668 /* same file with different module */
669 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
670 pp_module
->file_name
);
671 char *m_pathname
= compose_path_name(module
->dir_name
,
673 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
674 "with file `%s' containing TTCN-3 module `%s'.", pp_pathname
,
675 pp_module
->module_name
, m_pathname
, module
->module_name
);
679 } else if (is_same_module(pp_module
->module_name
, module
->module_name
)) {
680 /* different file with the same module */
681 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
682 pp_module
->file_name
);
683 char *m_pathname
= compose_path_name(module
->dir_name
,
685 ERROR("Both files `%s' and `%s' contain TTCN-3 module `%s'.",
686 pp_pathname
, m_pathname
, pp_module
->module_name
);
691 for (j
= 0; j
< makefile
->nASN1Modules
; j
++) {
692 struct module_struct
*module
= makefile
->ASN1Modules
+ j
;
693 if (is_same_file(pp_module
->dir_name
, preprocessed_name
,
694 module
->dir_name
, module
->file_name
)) {
695 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
696 pp_module
->file_name
);
697 char *m_pathname
= compose_path_name(module
->dir_name
,
699 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
700 "with file `%s' containing ASN.1 module `%s'.", pp_pathname
,
701 pp_module
->module_name
, m_pathname
, module
->module_name
);
706 for (j
= 0; j
< makefile
->nOtherFiles
; j
++) {
707 char *dir_name
= get_dir_name(makefile
->OtherFiles
[j
],
708 makefile
->working_dir
);
709 char *file_name
= get_file_from_path(makefile
->OtherFiles
[j
]);
710 if (is_same_file(pp_module
->dir_name
, preprocessed_name
, dir_name
,
712 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
713 pp_module
->file_name
);
714 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
715 "with other file `%s'.", pp_pathname
, pp_module
->module_name
,
716 makefile
->OtherFiles
[j
]);
722 Free(preprocessed_name
);
726 /** Checks the name clash between existing module \a module and newly added
727 * module with parameters \a path_name, \a dir_name, \a file_name,
728 * \a module_name. Both the existing and the new module shall be of the same
729 * kind, parameter \a kind shall contain the respective string (either "ASN.1"
730 * or "TTCN-3"). If a clash is found the parameters of the new module except
731 * \a path_name are deallocated and TRUE is returned. Otherwise FALSE is
733 static boolean
check_module_clash_same(const struct module_struct
*module
,
734 const char *kind
, const char *path_name
, char *dir_name
, char *file_name
,
737 if (is_same_module(module_name
, module
->module_name
)) {
738 if (is_same_file(dir_name
, file_name
,
739 module
->dir_name
, module
->file_name
)) {
740 /* the same file was given twice: just issue a warning */
741 WARNING("File `%s' was given more than once for the Makefile.",
744 /* two different files contain the same module: this cannot be
745 * resolved as the generated C++ files will clash */
746 char *path_name1
= compose_path_name(module
->dir_name
,
748 char *path_name2
= compose_path_name(dir_name
, file_name
);
749 ERROR("Both files `%s' and `%s' contain %s module `%s'.",
750 path_name1
, path_name2
, kind
, module_name
);
761 /** Checks the name clash between existing module \a module and newly added
762 * module with parameters \a dir_name, \a file_name, \a module_name. The two
763 * modules shall be of different kinds (one is ASN.1, the other is TTCN-3).
764 * Parameters \a kind1 and \a kind2 shall contain the respective strings. If a
765 * clash is found the parameters of the new module are deallocated and TRUE is
766 * returned. Otherwise FALSE is returned. */
767 static boolean
check_module_clash_different(const struct module_struct
*module
,
768 const char *kind1
, char *dir_name
, char *file_name
, char *module_name
,
771 if (is_same_module(module_name
, module
->module_name
)) {
772 /* two different files contain the same module: this cannot be resolved
773 * as the generated C++ files will clash */
774 char *path_name1
= compose_path_name(module
->dir_name
, module
->file_name
);
775 char *path_name2
= compose_path_name(dir_name
, file_name
);
776 ERROR("File `%s' containing %s module `%s' and file `%s' containing "
777 "%s module `%s' cannot be used together in the same Makefile.",
778 path_name1
, kind1
, module
->module_name
, path_name2
, kind2
, module_name
);
788 /** Adds a TTCN-3 module to Makefile descriptor structure \a makefile.
789 * The name of the TTCN-3 source file is \a path_name, the module identifier
790 * is \a module_name. It is checked whether a file or module with the same name
791 * already exists in \a makefile and an appropriate warning or error is
793 static void add_ttcn3_module(struct makefile_struct
*makefile
,
794 const char *path_name
, char *module_name
)
796 struct module_struct
*module
;
797 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
798 char *file_name
= get_file_from_path(path_name
);
799 const char *suffix
= get_suffix(file_name
);
801 boolean is_preprocessed
= FALSE
;
803 if (suffix
!= NULL
) {
804 if (!strcmp(suffix
, "ttcnpp")) {
805 if (makefile
->preprocess
) is_preprocessed
= TRUE
;
806 else WARNING("The suffix of TTCN-3 file `%s' indicates that it should be "
807 "preprocessed, but TTCN-3 preprocessing is not enabled. The file "
808 "will be added to the list of normal TTCN-3 modules in the Makefile.",
810 } else if (!strcmp(suffix
, "ttcnin")) {
811 WARNING("The suffix of file `%s' indicates that it should be a "
812 "preprocessor include file, but it contains a TTCN-3 module named `%s'. "
813 "The file will be added to the list of normal TTCN-3 modules in the "
814 "Makefile.", path_name
, module_name
);
818 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
819 if (check_module_clash_different(makefile
->ASN1Modules
+ i
, "ASN.1",
820 dir_name
, file_name
, module_name
, "TTCN-3")) return;
822 /* never entered if suffix is NULL */
823 if (is_preprocessed
) {
825 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
826 if (check_module_clash_same(makefile
->TTCN3PPModules
+ i
, "TTCN-3",
827 path_name
, dir_name
, file_name
, module_name
)) return;
829 /* clashes with normal TTCN-3 modules will be checked (and maybe resolved)
830 * in \a check_preprocessed_filename_collision() */
831 /* add it to the list of TTCN-3 modules to be preprocessed */
832 makefile
->TTCN3PPModules
= (struct module_struct
*)
833 Realloc(makefile
->TTCN3PPModules
,
834 (makefile
->nTTCN3PPModules
+ 1) * sizeof(*makefile
->TTCN3PPModules
));
835 module
= makefile
->TTCN3PPModules
+ makefile
->nTTCN3PPModules
;
836 makefile
->nTTCN3PPModules
++;
837 module
->dir_name
= dir_name
;
838 module
->file_name
= file_name
;
839 module
->module_name
= module_name
;
840 file_prefix
= cut_suffix(file_name
);
841 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
842 else module
->is_regular
= FALSE
;
845 /* the file is not preprocessed */
846 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
847 if (check_module_clash_same(makefile
->TTCN3Modules
+ i
, "TTCN-3",
848 path_name
, dir_name
, file_name
, module_name
)) return;
850 /* clashes with preprocessed TTCN-3 modules will be checked (and maybe
851 * resolved) in \a check_preprocessed_filename_collision() */
852 /* add it to the list of normal TTCN-3 modules */
853 makefile
->TTCN3Modules
= (struct module_struct
*)
854 Realloc(makefile
->TTCN3Modules
,
855 (makefile
->nTTCN3Modules
+ 1) * sizeof(*makefile
->TTCN3Modules
));
856 module
= makefile
->TTCN3Modules
+ makefile
->nTTCN3Modules
;
857 makefile
->nTTCN3Modules
++;
858 module
->dir_name
= dir_name
;
859 module
->file_name
= file_name
;
860 module
->module_name
= module_name
;
861 if (suffix
!= NULL
&& !strcmp(suffix
, "ttcn")) {
862 char *file_prefix
= cut_suffix(file_name
);
863 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
864 else module
->is_regular
= FALSE
;
867 module
->is_regular
= FALSE
;
872 /** ASN.1 filename shall contain no hyphen */
873 static boolean
is_valid_asn1_filename(const char* file_name
)
875 if (0 == strchr(file_name
, '-')) {
881 /** Adds an ASN.1 module to Makefile descriptor structure \a makefile.
882 * The name of the ASN.1 source file is \a path_name, the module identifier
883 * is \a module_name. It is checked whether a file or module with the same name
884 * already exists in \a makefile and an appropriate warning or error is
886 static void add_asn1_module(struct makefile_struct
*makefile
,
887 const char *path_name
, char *module_name
)
889 struct module_struct
*module
;
890 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
891 char *file_name
= get_file_from_path(path_name
);
892 const char *suffix
= get_suffix(file_name
);
894 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
895 if (check_module_clash_same(makefile
->ASN1Modules
+ i
, "ASN.1", path_name
,
896 dir_name
, file_name
, module_name
)) return;
898 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
899 if (check_module_clash_different(makefile
->TTCN3Modules
+ i
, "TTCN-3",
900 dir_name
, file_name
, module_name
, "ASN.1")) return;
902 if (makefile
->preprocess
) {
903 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
904 if (check_module_clash_different(makefile
->TTCN3PPModules
+ i
, "TTCN-3",
905 dir_name
, file_name
, module_name
, "ASN.1")) return;
908 makefile
->ASN1Modules
= (struct module_struct
*)
909 Realloc(makefile
->ASN1Modules
,
910 (makefile
->nASN1Modules
+ 1) * sizeof(*makefile
->ASN1Modules
));
911 module
= makefile
->ASN1Modules
+ makefile
->nASN1Modules
;
912 makefile
->nASN1Modules
++;
913 module
->dir_name
= dir_name
;
914 module
->file_name
= file_name
;
915 module
->module_name
= module_name
;
916 if (suffix
!= NULL
&& !strcmp(suffix
, "asn")) {
917 char *file_prefix
= cut_suffix(file_name
);
918 /* replace all '_' with '-' in file name prefix */
919 for (i
= 0; file_prefix
[i
] != '\0'; i
++)
920 if (file_prefix
[i
] == '_') file_prefix
[i
] = '-';
921 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
922 else module
->is_regular
= FALSE
;
925 module
->is_regular
= FALSE
;
929 /** Adds the file named \a path_name to the list of files pointed by \a list_ptr
930 * and \a list_size. The suffix or contents of \a path_name are not examined,
931 * only duplicate entries are checked. In case of duplicate entries warning is
932 * reported only if argument \a report_warning is set to TRUE. */
933 static void add_path_to_list(size_t *list_size
, char ***list_ptr
,
934 const char *path_name
, const char *working_dir
, boolean report_warning
)
937 char *dir_name
= get_dir_name(path_name
, working_dir
);
938 char *file_name
= get_file_from_path(path_name
);
939 char *canonized_path_name
= compose_path_name(dir_name
, file_name
);
942 for (i
= 0; i
< *list_size
; i
++) {
943 if (!strcmp(canonized_path_name
, (*list_ptr
)[i
])) {
944 if (report_warning
) WARNING("File `%s' was given more than once for the "
945 "Makefile.", path_name
);
946 Free(canonized_path_name
);
950 *list_ptr
= (char**)Realloc(*list_ptr
, (*list_size
+ 1) * sizeof(**list_ptr
));
951 (*list_ptr
)[*list_size
] = canonized_path_name
;
955 /** Adds a C/C++ header or source file or an other file named \a path_name to
956 * Makefile descriptor structure \a makefile. The file is classified based on
957 * its suffix and not by content. If the file clashes with existing files or
958 * modules the appropriate warning or error is generated. */
959 static void add_user_file(struct makefile_struct
*makefile
,
960 const char *path_name
)
962 const char *suffix
= get_suffix(path_name
);
963 if (suffix
!= NULL
) {
964 if (!strcmp(suffix
, "ttcn") || !strcmp(suffix
, "ttcn3") ||
965 !strcmp(suffix
, "3mp") || !strcmp(suffix
, "ttcnpp")) {
966 /* The file content was already checked. Since it doesn't look like
967 * a valid TTCN-3 file, these suffixes are suspect */
968 WARNING("File `%s' does not contain a valid TTCN-3 module. "
969 "It will be added to the Makefile as other file.", path_name
);
971 else if (!strcmp(suffix
, "ttcnin")) {
972 /* this is a TTCN-3 include file */
973 if (makefile
->preprocess
) {
974 add_path_to_list(&makefile
->nTTCN3IncludeFiles
,
975 &makefile
->TTCN3IncludeFiles
, path_name
, makefile
->working_dir
, TRUE
);
979 WARNING("The suffix of file `%s' indicates that it is a TTCN-3 "
980 "include file, but TTCN-3 preprocessing is not enabled. The file "
981 "will be added to the Makefile as other file.", path_name
);
984 else if (!strcmp(suffix
, "asn") || !strcmp(suffix
, "asn1")) {
985 /* The file content was already checked. Since it doesn't look like
986 * a valid ASN.1 file, these suffixes are suspect */
987 WARNING("File `%s' does not contain a valid ASN.1 module. "
988 "It will be added to the Makefile as other file.", path_name
);
990 else if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "c") || !strcmp(suffix
, "cpp")) {
991 /* this is a source file */
992 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
993 char *file_name
= get_file_from_path(path_name
);
994 char *file_prefix
= cut_suffix(file_name
);
995 struct user_struct
*user
;
997 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
998 user
= makefile
->UserFiles
+ i
;
999 if (!strcmp(file_prefix
, user
->file_prefix
)) {
1000 if (user
->source_name
!= NULL
) {
1001 /* the source file is already present */
1002 if (is_same_file(dir_name
, file_name
,
1003 user
->dir_name
, user
->source_name
)) {
1004 WARNING("File `%s' was given more than once for the Makefile.", path_name
);
1007 char *path_name1
= compose_path_name(user
->dir_name
, user
->source_name
);
1008 char *path_name2
= compose_path_name(dir_name
, file_name
);
1009 ERROR("C/C++ source files `%s' and `%s' cannot be used together "
1010 "in the same Makefile.", path_name1
, path_name2
);
1016 /* a header file with the same prefix is already present */
1017 if (is_same_directory(dir_name
, user
->dir_name
)) {
1018 user
->source_name
= file_name
;
1020 if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "cpp"))
1021 user
->has_cc_suffix
= TRUE
;
1024 char *path_name1
= compose_path_name(dir_name
, file_name
);
1025 char *path_name2
= compose_path_name(user
->dir_name
, user
->header_name
);
1026 ERROR("C/C++ source file `%s' cannot be used together with "
1027 "header file `%s' in the same Makefile.", path_name1
,
1039 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1040 (makefile
->nUserFiles
+ 1) * sizeof(*makefile
->UserFiles
));
1041 user
= makefile
->UserFiles
+ makefile
->nUserFiles
;
1042 makefile
->nUserFiles
++;
1043 user
->dir_name
= dir_name
;
1044 user
->file_prefix
= file_prefix
;
1045 user
->header_name
= NULL
;
1046 user
->source_name
= file_name
;
1047 user
->has_hh_suffix
= FALSE
;
1048 if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "cpp")) user
->has_cc_suffix
= TRUE
;
1049 else user
->has_cc_suffix
= FALSE
;
1052 else if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "h")) {
1053 /* this is a header file */
1054 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
1055 char *file_name
= get_file_from_path(path_name
);
1056 char *file_prefix
= cut_suffix(file_name
);
1057 struct user_struct
*user
;
1059 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1060 user
= makefile
->UserFiles
+ i
;
1061 if (!strcmp(file_prefix
, user
->file_prefix
)) {
1062 if (user
->header_name
!= NULL
) {
1063 /* the header file is already present */
1064 if (is_same_file(dir_name
, file_name
, user
->dir_name
, user
->header_name
)) {
1065 WARNING("File `%s' was given more than once for the Makefile.", path_name
);
1068 char *path_name1
= compose_path_name(user
->dir_name
, user
->header_name
);
1069 char *path_name2
= compose_path_name(dir_name
, file_name
);
1070 ERROR("C/C++ header files `%s' and `%s' cannot be used together "
1071 "in the same Makefile.", path_name1
, path_name2
);
1077 /* a source file with the same prefix is already present */
1078 if (is_same_directory(dir_name
, user
->dir_name
)) {
1079 user
->header_name
= file_name
;
1081 if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "hpp"))
1082 user
->has_hh_suffix
= TRUE
;
1085 char *path_name1
= compose_path_name(dir_name
, file_name
);
1086 char *path_name2
= compose_path_name(user
->dir_name
, user
->source_name
);
1087 ERROR("C/C++ header file `%s' cannot be used together with "
1088 "source file `%s' in the same Makefile.", path_name1
, path_name2
);
1099 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1100 (makefile
->nUserFiles
+ 1) * sizeof(*makefile
->UserFiles
));
1101 user
= makefile
->UserFiles
+ makefile
->nUserFiles
;
1102 makefile
->nUserFiles
++;
1103 user
->dir_name
= dir_name
;
1104 user
->file_prefix
= file_prefix
;
1105 user
->header_name
= file_name
;
1106 user
->source_name
= NULL
;
1107 if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "hpp")) user
->has_hh_suffix
= TRUE
;
1108 else user
->has_hh_suffix
= FALSE
;
1109 user
->has_cc_suffix
= FALSE
;
1112 } /* end if (suffix != NULL) */
1113 /* treat the file as other file if it was not handled yet */
1114 add_path_to_list(&makefile
->nOtherFiles
, &makefile
->OtherFiles
, path_name
,
1115 makefile
->working_dir
, TRUE
);
1118 /** Removes the generated C++ header and/or source files of module \a module
1119 * from Makefile descriptor structure \a makefile. A warning is displayed if
1120 * such file is found. */
1121 static void drop_generated_files(struct makefile_struct
*makefile
,
1122 const struct module_struct
*module
)
1124 char *module_name
= mcopystr(module
->module_name
);
1126 /* transform all '-' characters in ASN.1 module name to '_' */
1127 for (i
= 0; module_name
[i
] != '\0'; i
++)
1128 if (module_name
[i
] == '-') module_name
[i
] = '_';
1129 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1130 struct user_struct
*user
= makefile
->UserFiles
+ i
;
1131 if (!strcmp(module_name
, user
->file_prefix
)) {
1132 char *m_pathname
= compose_path_name(module
->dir_name
, module
->file_name
);
1133 /** Note: if central storage is used the generated C++ files are placed
1134 * into the same directory as the TTCN-3/ASN.1 modules, otherwise the
1135 * files are generated into the working directory. */
1136 boolean is_same_dir
= is_same_directory(user
->dir_name
,
1137 makefile
->central_storage
? module
->dir_name
: NULL
);
1138 if (user
->header_name
!= NULL
) {
1139 char *u_pathname
= compose_path_name(user
->dir_name
,
1141 if (is_same_dir
&& user
->has_hh_suffix
) {
1142 WARNING("Header file `%s' is generated from module `%s' (file `%s'). "
1143 "Removing it from the list of user files.", u_pathname
,
1144 module
->module_name
, m_pathname
);
1146 ERROR("Header file `%s' cannot be used together with module `%s' "
1147 "(file `%s') in the same Makefile.", u_pathname
,
1148 module
->module_name
, m_pathname
);
1152 if (user
->source_name
!= NULL
) {
1153 char *u_pathname
= compose_path_name(user
->dir_name
,
1155 if (is_same_dir
&& user
->has_cc_suffix
) {
1156 WARNING("Source file `%s' is generated from module `%s' (file "
1157 "`%s'). Removing it from the list of user files.", u_pathname
,
1158 module
->module_name
, m_pathname
);
1160 ERROR("Source file `%s' cannot be used together with module "
1161 "`%s' (file `%s') in the same Makefile.", u_pathname
,
1162 module
->module_name
, m_pathname
);
1167 Free(user
->dir_name
);
1168 Free(user
->file_prefix
);
1169 Free(user
->header_name
);
1170 Free(user
->source_name
);
1171 makefile
->nUserFiles
--;
1172 memmove(user
, user
+ 1, (makefile
->nUserFiles
- i
) *
1173 sizeof(*makefile
->UserFiles
));
1174 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1175 makefile
->nUserFiles
* sizeof(*makefile
->UserFiles
));
1182 /** Drops all C++ header and source files of the Makefile descriptor structure
1183 * \a makefile that are generated from its TTCN-3 or ASN.1 modules. */
1184 static void filter_out_generated_files(struct makefile_struct
*makefile
)
1187 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1188 drop_generated_files(makefile
, makefile
->TTCN3Modules
+ i
);
1190 if (makefile
->preprocess
) {
1191 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1192 drop_generated_files(makefile
, makefile
->TTCN3PPModules
+ i
);
1195 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1196 drop_generated_files(makefile
, makefile
->ASN1Modules
+ i
);
1200 /** Completes the list of user C/C++ header and source files in \a makefile.
1201 * If only the source file was given the function looks for the corresponding
1202 * header file or vice versa. */
1203 static void complete_user_files(const struct makefile_struct
*makefile
)
1206 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1207 struct user_struct
*user
= makefile
->UserFiles
+ i
;
1208 if (user
->header_name
== NULL
) {
1209 static const char * const suffix_list
[] = { "hh", "h", "hpp", NULL
};
1210 const char * const *suffix_ptr
;
1211 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
1212 char *file_name
= mprintf("%s.%s", user
->file_prefix
, *suffix_ptr
);
1213 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1214 if (get_path_status(path_name
) == PS_FILE
) {
1216 user
->header_name
= file_name
;
1217 if (!strcmp(*suffix_ptr
, "hh") || !strcmp(*suffix_ptr
, "hpp"))
1218 user
->has_hh_suffix
= TRUE
;
1225 else if (user
->source_name
== NULL
) {
1226 static const char * const suffix_list
[] = { "cc", "c", "cpp", NULL
};
1227 const char * const *suffix_ptr
;
1228 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
1229 char *file_name
= mprintf("%s.%s", user
->file_prefix
, *suffix_ptr
);
1230 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1231 if (get_path_status(path_name
) == PS_FILE
) {
1233 user
->source_name
= file_name
;
1234 if (!strcmp(*suffix_ptr
, "cc") || !strcmp(*suffix_ptr
, "cpp"))
1235 user
->has_cc_suffix
= TRUE
;
1245 /** Converts the directory name pointed by \a dir_ptr to a relative pathname
1246 * based on \a working_dir. The original directory name is deallocated and
1247 * replaced with a new string. Nothing happens if \a dir_ptr points to NULL. */
1248 static void replace_dir_with_relative(char **dir_ptr
, const char *working_dir
)
1250 if (*dir_ptr
!= NULL
) {
1251 char *rel_dir
= get_relative_dir(*dir_ptr
, working_dir
);
1257 /** Converts the directory part of path name pointed by \a path_ptr to a relative
1258 * pathname based on \a working_dir. The original path name is deallocated and
1259 * replaced with a new string. */
1260 static void convert_path_to_relative(char **path_ptr
, const char *working_dir
)
1262 char *dir_name
= get_dir_name(*path_ptr
, working_dir
);
1263 if (dir_name
!= NULL
) {
1264 char *file_name
= get_file_from_path(*path_ptr
);
1265 replace_dir_with_relative(&dir_name
, working_dir
);
1267 *path_ptr
= compose_path_name(dir_name
, file_name
);
1273 /** Converts all directories used by the Makefile descriptor structure
1274 * \a makefile to relative pathnames based on the working directory stored in
1276 static void convert_dirs_to_relative(struct makefile_struct
*makefile
)
1279 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1280 replace_dir_with_relative(&makefile
->TTCN3Modules
[i
].dir_name
,
1281 makefile
->working_dir
);
1283 if (makefile
->preprocess
) {
1284 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1285 replace_dir_with_relative(&makefile
->TTCN3PPModules
[i
].dir_name
,
1286 makefile
->working_dir
);
1288 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++) {
1289 convert_path_to_relative(makefile
->TTCN3IncludeFiles
+ i
,
1290 makefile
->working_dir
);
1293 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1294 replace_dir_with_relative(&makefile
->ASN1Modules
[i
].dir_name
,
1295 makefile
->working_dir
);
1297 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1298 replace_dir_with_relative(&makefile
->UserFiles
[i
].dir_name
,
1299 makefile
->working_dir
);
1301 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) {
1302 convert_path_to_relative(makefile
->OtherFiles
+ i
, makefile
->working_dir
);
1304 if (makefile
->ets_name
!= NULL
)
1305 convert_path_to_relative(&makefile
->ets_name
, makefile
->working_dir
);
1308 /* Returns whether the string \a file_name contains special characters. */
1309 static boolean
has_special_chars(const char *file_name
)
1311 if (file_name
!= NULL
) {
1313 for (i
= 0; ; i
++) {
1314 int c
= (unsigned char)file_name
[i
];
1344 if (!isascii(c
) || !isprint(c
)) return TRUE
;
1352 /** Checks whether the path name composed of \a dir_name and \a file_name
1353 * contains special characters that are not allowed in the Makefile. Parameter
1354 * \a what contains the description of the corresponding file. */
1355 static void check_special_chars_in_path(const char *dir_name
,
1356 const char *file_name
, const char *what
)
1358 if (has_special_chars(dir_name
) || has_special_chars(file_name
)) {
1359 char *path_name
= compose_path_name(dir_name
, file_name
);
1360 ERROR("The name of %s `%s' contains special characters that cannot be "
1361 "handled properly by the `make' utility and/or the shell.", what
,
1367 /** Checks whether the directory names or file names that will be used in the
1368 * generated Makefile contain special characters that cannot be handled by the
1369 * "make" utility. */
1370 static void check_special_chars(const struct makefile_struct
*makefile
)
1373 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1374 check_special_chars_in_path(makefile
->TTCN3Modules
[i
].dir_name
,
1375 makefile
->TTCN3Modules
[i
].file_name
, "TTCN-3 file");
1377 if (makefile
->preprocess
) {
1378 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1379 check_special_chars_in_path(makefile
->TTCN3PPModules
[i
].dir_name
,
1380 makefile
->TTCN3PPModules
[i
].file_name
,
1381 "TTCN-3 file to be preprocessed");
1384 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1385 check_special_chars_in_path(makefile
->ASN1Modules
[i
].dir_name
,
1386 makefile
->ASN1Modules
[i
].file_name
, "ASN.1 file");
1388 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1389 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1390 if (user
->source_name
!= NULL
)
1391 check_special_chars_in_path(user
->dir_name
, user
->source_name
,
1392 "C/C++ source file");
1393 else check_special_chars_in_path(user
->dir_name
, user
->header_name
,
1394 "C/C++ header file");
1396 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) {
1397 check_special_chars_in_path(NULL
, makefile
->OtherFiles
[i
], "other file");
1401 /** Adds base directory \a dir_name to Makefile descriptor structure
1402 * \a makefile. Flag \a has_modules indicates whether \a dir_name contains
1403 * TTCN-3 and/or ASN.1 modules. The new directory is ignored if it is already
1404 * added to \a makefile. */
1405 static void add_base_dir(struct makefile_struct
*makefile
,
1406 const char *dir_name
, boolean has_modules
)
1408 struct base_dir_struct
*base_dir
;
1409 if (dir_name
!= NULL
) {
1411 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1412 base_dir
= makefile
->BaseDirs
+ i
;
1413 if (!strcmp(dir_name
, base_dir
->dir_name
)) {
1414 if (has_modules
) base_dir
->has_modules
= TRUE
;
1418 makefile
->BaseDirs
= (struct base_dir_struct
*)Realloc(makefile
->BaseDirs
,
1419 (makefile
->nBaseDirs
+ 1) * sizeof(*makefile
->BaseDirs
));
1420 base_dir
= makefile
->BaseDirs
+ makefile
->nBaseDirs
;
1421 makefile
->nBaseDirs
++;
1422 base_dir
->dir_name
= dir_name
;
1423 base_dir
->has_modules
= has_modules
;
1427 /** Collects all directories that are used in the Makefile descriptor structure
1428 * \a makefile in order to use pre-compiled files from them. */
1429 static void collect_base_dirs(struct makefile_struct
*makefile
)
1432 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1433 add_base_dir(makefile
, makefile
->TTCN3Modules
[i
].dir_name
, TRUE
);
1435 if (makefile
->preprocess
) {
1436 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1437 add_base_dir(makefile
, makefile
->TTCN3PPModules
[i
].dir_name
, TRUE
);
1440 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1441 add_base_dir(makefile
, makefile
->ASN1Modules
[i
].dir_name
, TRUE
);
1443 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1444 add_base_dir(makefile
, makefile
->UserFiles
[i
].dir_name
, FALSE
);
1446 if (makefile
->nBaseDirs
== 0) {
1447 WARNING("Usage of pre-compiled files from central storage (option `-c') "
1448 "is enabled, but all given files are located in the current working "
1453 /** Checks whether the TTCN-3, ASN.1 and C++ files follow the default naming
1454 * convention and sets the appropriate flags accordingly. */
1455 static void check_naming_convention(struct makefile_struct
*makefile
)
1457 /* initially set all flags to true */
1458 makefile
->TTCN3ModulesRegular
= TRUE
;
1459 makefile
->BaseTTCN3ModulesRegular
= TRUE
;
1460 makefile
->ASN1ModulesRegular
= TRUE
;
1461 makefile
->BaseASN1ModulesRegular
= TRUE
;
1462 makefile
->UserHeadersRegular
= TRUE
;
1463 makefile
->UserSourcesRegular
= TRUE
;
1464 makefile
->BaseUserHeadersRegular
= TRUE
;
1465 makefile
->BaseUserSourcesRegular
= TRUE
;
1466 if (makefile
->central_storage
) {
1467 /* this project (Makefile) will use pre-compiled files from other
1470 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1471 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1472 if (module
->dir_name
!= NULL
) {
1473 if (!module
->is_regular
) makefile
->BaseTTCN3ModulesRegular
= FALSE
;
1476 if (!module
->is_regular
) makefile
->TTCN3ModulesRegular
= FALSE
;
1478 if (!makefile
->TTCN3ModulesRegular
&& !makefile
->BaseTTCN3ModulesRegular
)
1481 /* ttcnpp files are ttcn files */
1482 if ((makefile
->TTCN3ModulesRegular
|| makefile
->BaseTTCN3ModulesRegular
) &&
1483 makefile
->preprocess
) {
1484 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1485 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1486 if (module
->dir_name
!= NULL
) {
1487 if (!module
->is_regular
) makefile
->BaseTTCN3ModulesRegular
= FALSE
;
1489 if (!module
->is_regular
) makefile
->TTCN3ModulesRegular
= FALSE
;
1491 if (!makefile
->TTCN3ModulesRegular
&& !makefile
->BaseTTCN3ModulesRegular
)
1495 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1496 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1497 if (module
->dir_name
!= NULL
) {
1498 if (!module
->is_regular
) makefile
->BaseASN1ModulesRegular
= FALSE
;
1501 if (!module
->is_regular
) makefile
->ASN1ModulesRegular
= FALSE
;
1503 if (!makefile
->ASN1ModulesRegular
&& !makefile
->BaseASN1ModulesRegular
)
1506 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1507 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1508 if (user
->dir_name
!= NULL
) {
1509 if (!user
->has_cc_suffix
)
1510 makefile
->BaseUserSourcesRegular
= FALSE
;
1511 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1512 makefile
->BaseUserHeadersRegular
= FALSE
;
1515 if (!user
->has_cc_suffix
)
1516 makefile
->UserSourcesRegular
= FALSE
;
1517 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1518 makefile
->UserHeadersRegular
= FALSE
;
1520 if (!makefile
->UserHeadersRegular
&& !makefile
->UserSourcesRegular
&&
1521 !makefile
->BaseUserHeadersRegular
&&
1522 !makefile
->BaseUserSourcesRegular
) break;
1525 /* this project (Makefile) will-be stand-alone */
1527 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1528 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1529 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1530 makefile
->TTCN3ModulesRegular
= FALSE
;
1534 if (makefile
->TTCN3ModulesRegular
&& makefile
->preprocess
) {
1535 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1536 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1537 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1538 makefile
->TTCN3ModulesRegular
= FALSE
;
1543 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1544 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1545 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1546 makefile
->ASN1ModulesRegular
= FALSE
;
1550 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1551 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1552 if (!user
->has_cc_suffix
)
1553 makefile
->UserSourcesRegular
= FALSE
;
1554 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1555 makefile
->UserHeadersRegular
= FALSE
;
1556 if (!makefile
->UserHeadersRegular
&& !makefile
->UserSourcesRegular
)
1562 /** Prints the name of the TTCN-3 or ASN.1 source file that belongs to module
1563 * \a module to file \a fp. */
1564 static void print_file_name(FILE *fp
, const struct module_struct
*module
)
1566 char *path_name
= compose_path_name(module
->dir_name
, module
->file_name
);
1567 fprintf(fp
, " %s", path_name
);
1571 /** Prints the name of the preprocessed TTCN-3 source file that belongs to
1572 * module \a module to file \a fp. */
1573 static void print_preprocessed_file_name(FILE *fp
,
1574 const struct module_struct
*module
)
1576 char *preprocessed_name
= get_preprocessed_file_name(module
->file_name
);
1577 char *path_name
= compose_path_name(module
->dir_name
, preprocessed_name
);
1578 fprintf(fp
, " %s", path_name
);
1580 Free(preprocessed_name
);
1583 /** Prints the name of the generated header, source or object file of module
1584 * \a module to file \a fp. The name of the directory is added only if
1585 * \a add_directory is TRUE. Parameter \a suffix shall be "hh", "cc", "hpp", "cpp" or "o". */
1586 static void print_generated_file_name(FILE *fp
,
1587 const struct module_struct
*module
, boolean add_directory
, const char *suffix
)
1589 char *file_name
= mcopystr(module
->module_name
);
1590 /* replace '-' with '_' */
1592 for (i
= 0; file_name
[i
] != '\0'; i
++)
1593 if (file_name
[i
] == '-') file_name
[i
] = '_';
1594 /* append the suffix */
1595 file_name
= mputprintf(file_name
, "%s", suffix
);
1596 /* add the directory name if necessary */
1597 if (add_directory
) {
1598 char *path_name
= compose_path_name(module
->dir_name
, file_name
);
1600 file_name
= path_name
;
1602 fprintf(fp
, " %s", file_name
);
1606 /** Prints the name of the user C/C++ header file of user module \a user if the
1607 * above file exists. */
1608 static void print_header_name(FILE *fp
, const struct user_struct
*user
)
1610 if (user
->header_name
!= NULL
) {
1611 char *path_name
= compose_path_name(user
->dir_name
, user
->header_name
);
1612 fprintf(fp
, " %s", path_name
);
1617 /** Prints the name of the user C/C++ source file of user module \a user if the
1618 * above file exists. */
1619 static void print_source_name(FILE *fp
, const struct user_struct
*user
)
1621 if (user
->source_name
!= NULL
) {
1622 char *path_name
= compose_path_name(user
->dir_name
, user
->source_name
);
1623 fprintf(fp
, " %s", path_name
);
1628 /** Prints the name of the user C/C++ object file of user module \a user if the
1629 * above file exists (i.e. the respective source file is present). */
1630 static void print_object_name(FILE *fp
, const struct user_struct
*user
)
1632 if (user
->source_name
!= NULL
) {
1633 char *file_name
= mprintf("%s.o", user
->file_prefix
);
1634 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1636 fprintf(fp
, " %s", path_name
);
1641 static void print_shared_object_name(FILE *fp
, const struct user_struct
*user
)
1643 if (user
->source_name
!= NULL
) {
1644 char *file_name
= mprintf("%s.so", user
->file_prefix
);
1645 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1647 fprintf(fp
, " %s", path_name
);
1651 /** Prints the splitted files' names for a given module. */
1652 static void print_splitted_file_names(FILE *fp
,
1653 const struct makefile_struct
*makefile
, const struct module_struct
*module
)
1655 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
1656 print_generated_file_name(fp
, module
, FALSE
, "_seq.cc");
1657 print_generated_file_name(fp
, module
, FALSE
, "_set.cc");
1658 print_generated_file_name(fp
, module
, FALSE
, "_seqof.cc");
1659 print_generated_file_name(fp
, module
, FALSE
, "_setof.cc");
1660 print_generated_file_name(fp
, module
, FALSE
, "_union.cc");
1664 static void fprint_extra_targets(FILE* fp
, struct string2_list
* target_placement_list
, const char* placement
)
1666 struct string2_list
* act_elem
= target_placement_list
;
1668 if (act_elem
->str1
&& act_elem
->str2
&& (strcmp(act_elem
->str2
,placement
)==0)) {
1669 fprintf(fp
, " %s", act_elem
->str1
);
1671 act_elem
= act_elem
->next
;
1675 #undef COMMENT_PREFIX
1676 #define COMMENT_PREFIX "# "
1678 /** Prints the Makefile based on structure \a makefile. */
1679 static void print_makefile(struct makefile_struct
*makefile
)
1681 boolean add_refd_prjs
= FALSE
;
1682 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
1683 add_refd_prjs
= hasSubProject(makefile
->project_name
);
1686 add_refd_prjs
= makefile
->sub_project_dirs
&& makefile
->sub_project_dirs
->str
;
1688 NOTIFY("Generating Makefile skeleton...");
1690 if (makefile
->force_overwrite
||
1691 get_path_status(makefile
->output_file
) == PS_NONEXISTENT
) {
1696 const char *rm_command
= makefile
->gnu_make
? "$(RM)" : "rm -f";
1698 boolean run_compiler
= (makefile
->nASN1Modules
> 0)
1699 || (makefile
->nTTCN3Modules
) || (makefile
->nTTCN3PPModules
> 0);
1701 expstring_t titan_dir
= 0;
1702 const char * last_slash
= strrchr(program_name
, '/');
1703 if (last_slash
!= NULL
) {
1704 size_t path_len
= last_slash
- program_name
;
1705 titan_dir
= mcopystr(program_name
);
1706 /* Chop off the program name, and the /bin before it (if any) */
1708 && memcmp(titan_dir
+ path_len
- 4, "/bin", 4) == 0) {
1709 titan_dir
= mtruncstr(titan_dir
, path_len
- 4);
1712 titan_dir
= mtruncstr(titan_dir
, path_len
);
1717 fp
= fopen(makefile
->output_file
, "w");
1719 ERROR("Cannot open output file `%s' for writing: %s",
1720 makefile
->output_file
, strerror(errno
));
1723 user_info
= get_user_info();
1724 fprintf(fp
, "# This Makefile was generated by the Makefile Generator\n"
1725 "# of the TTCN-3 Test Executor version " PRODUCT_NUMBER
"\n"
1727 COPYRIGHT_STRING
"\n\n"
1728 "# The following make commands are available:\n"
1729 "# - make, make all Builds the %s.\n"
1730 "# - make archive Archives all source files.\n"
1731 "# - make check Checks the semantics of TTCN-3 and ASN.1 "
1735 "# - make compile Translates TTCN-3 and ASN.1 modules to C++.\n"
1736 "# - make dep Creates/updates dependency list.\n"
1737 "# - make executable Builds the executable test suite.\n"
1738 "# - make library Builds the library archive.\n"
1739 "# - make objects Builds the object files without linking the "
1740 "executable.\n", user_info
,
1741 makefile
->library
? "library archive." : "executable test suite",
1742 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ?
1743 "# - make clean Removes generated files from project.\n" :
1744 "# - make clean Removes all generated files.\n",
1745 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ?
1746 "# - make clean-all Removes all generated files from the project hierarchy.\n" : "");
1748 if (makefile
->dynamic
)
1749 fprintf(fp
, "# - make shared_objects Builds the shared object files "
1750 "without linking the executable.\n");
1751 if (makefile
->preprocess
)
1752 fputs("# - make preprocess Preprocess TTCN-3 files.\n", fp
);
1753 if (makefile
->central_storage
) {
1754 fputs("# WARNING! This Makefile uses pre-compiled files from the "
1755 "following directories:\n", fp
);
1756 for (i
= 0; i
< makefile
->nBaseDirs
; i
++)
1757 fprintf(fp
, "# %s\n", makefile
->BaseDirs
[i
].dir_name
);
1758 fputs("# The executable tests will be consistent only if all directories "
1760 "# the same platform and the same version of TTCN-3 Test Executor "
1762 "# C++ compiler with the same command line switches.\n\n", fp
);
1764 if (makefile
->gnu_make
) {
1765 fputs("# WARNING! This Makefile can be used with GNU make only.\n"
1766 "# Other versions of make may report syntax errors in it.\n\n"
1768 "# Do NOT touch this line...\n"
1770 ".PHONY: all shared_objects executable library objects check clean dep archive", fp
);
1771 if (makefile
->preprocess
) fputs(" preprocess", fp
);
1772 if (add_refd_prjs
) {
1773 fprintf(fp
, "\\\n referenced-all referenced-shared_objects referenced-executable referenced-library referenced-objects referenced-check"
1774 "\\\n referenced-clean%s",
1775 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ?
1778 fprint_extra_targets(fp
, makefile
->target_placement_list
, "PHONY");
1780 if (makefile
->gcc_dep
) {
1781 fputs("\n\n.SUFFIXES: .d", fp
);
1786 if (makefile
->linkingStrategy
) {
1787 const char* tpd_name
= getTPDFileName(makefile
->project_name
);
1789 fputs("# Titan Project Descriptor file what this Makefile is generated from.\n", fp
);
1790 fprintf(fp
, "TPD = %s\n\n", tpd_name
);
1792 const char* root_dir
= getPathToRootDir(makefile
->project_name
);
1794 fputs("# Relative path to top directory at OS level.\n", fp
);
1795 fprintf(fp
, "ROOT_DIR = %s\n\n", root_dir
);
1799 if (add_refd_prjs
) {
1800 struct string_list
* act_elem
= NULL
;
1801 struct string_list
* head
= NULL
;
1802 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {// pair with free_string_list
1803 head
= act_elem
= getRefWorkingDirs(makefile
->project_name
);
1806 act_elem
= makefile
->sub_project_dirs
;
1808 if (!makefile
->linkingStrategy
)
1809 fputs("# This is the top level makefile of a Makefile hierarchy generated from\n", fp
);
1810 fputs("# Titan Project Descriptor hierarchy. List of referenced project\n"
1811 "# working directories (ordered by dependencies):\n", fp
);
1813 if (act_elem
->str
) {
1814 fprintf(fp
, "# %s\n", act_elem
->str
);
1816 act_elem
= act_elem
->next
;
1818 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) { // pair with getRefWorkingDirs
1819 free_string_list(head
);
1821 fputs("REFERENCED_PROJECT_DIRS = ", fp
);
1822 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
1823 head
= act_elem
= getRefWorkingDirs(makefile
->project_name
); // pair with free_string_list
1826 act_elem
= makefile
->sub_project_dirs
;
1829 if (act_elem
->str
) {
1830 fprintf(fp
, "%s ", act_elem
->str
);
1832 act_elem
= act_elem
->next
;
1835 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {// pair with getRefWorkingDirs
1836 free_string_list(head
);
1841 "# Set these variables...\n"
1843 "# The path of your TTCN-3 Test Executor installation:\n"
1844 "# Uncomment this line to override the environment variable.\n"
1846 "# TTCN3_DIR = %s\n"
1848 "# The value below points to the location of the TITAN version\n"
1849 "# that generated this makefile.\n" : ""
1850 , titan_dir
? titan_dir
: "");
1851 if (titan_dir
) Free(titan_dir
);
1853 if (makefile
->cxxcompiler
) {
1854 cxx
= makefile
->cxxcompiler
;
1859 fprintf(fp
, "\n# Your platform: (SOLARIS, SOLARIS8, LINUX, FREEBSD or "
1862 "# Your C++ compiler:\n"
1863 "# (if you change the platform, you may need to change the compiler)\n"
1864 "CXX = %s \n\n", get_platform_string(), cxx
);
1867 if (makefile
->preprocess
|| makefile
->ttcn3preprocessor
) {
1868 if (makefile
->ttcn3preprocessor
) {
1869 cpp
= makefile
->ttcn3preprocessor
;
1873 fprintf(fp
,"# C preprocessor used for TTCN-3 files:\n"
1874 "CPP = %s\n\n", cpp
);
1877 fputs("# Flags for the C++ preprocessor (and makedepend as well):\n"
1878 "CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)/include", fp
);
1880 if (makefile
->use_runtime_2
) fputs(" -DTITAN_RUNTIME_2", fp
);
1882 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1883 fprintf(fp
, " -I%s", makefile
->BaseDirs
[i
].dir_name
);
1886 if (makefile
->prep_includes
) {
1887 struct string_list
* act_elem
= makefile
->prep_includes
;
1889 if (act_elem
->str
) {
1890 fprintf(fp
, " -I%s", act_elem
->str
);
1892 act_elem
= act_elem
->next
;
1896 if (makefile
->prep_defines
) {
1897 struct string_list
* act_elem
= makefile
->prep_defines
;
1899 if (act_elem
->str
) {
1900 fprintf(fp
, " -D%s", act_elem
->str
);
1902 act_elem
= act_elem
->next
;
1906 if (makefile
->prep_undefines
) {
1907 struct string_list
* act_elem
= makefile
->prep_undefines
;
1909 if (act_elem
->str
) {
1910 fprintf(fp
, " -U%s", act_elem
->str
);
1912 act_elem
= act_elem
->next
;
1918 if (makefile
->gcc_dep
) {
1919 fprintf(fp
, "# Flags for dependency generation\n"
1920 "CXXDEPFLAGS = -%s\n\n", strstr(cxx
, "g++") ? "MM" : "xM1");
1923 if (makefile
->preprocess
|| makefile
->ttcn3_prep_includes
|| makefile
->ttcn3_prep_defines
) {
1924 fputs("# Flags for preprocessing TTCN-3 files:\n"
1925 "CPPFLAGS_TTCN3 =", fp
);
1927 if (makefile
->preprocess
) {
1928 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1929 fprintf(fp
, " -I%s", makefile
->BaseDirs
[i
].dir_name
);
1932 if (makefile
->ttcn3_prep_includes
) {
1933 struct string_list
* act_elem
= makefile
->ttcn3_prep_includes
;
1935 if (act_elem
->str
) {
1936 fprintf(fp
, " -I%s", act_elem
->str
);
1938 act_elem
= act_elem
->next
;
1941 if (makefile
->ttcn3_prep_defines
) {
1942 struct string_list
* act_elem
= makefile
->ttcn3_prep_defines
;
1944 if (act_elem
->str
) {
1945 fprintf(fp
, " -D%s", act_elem
->str
);
1947 act_elem
= act_elem
->next
;
1950 if (makefile
->ttcn3_prep_undefines
) {
1951 struct string_list
* act_elem
= makefile
->ttcn3_prep_undefines
;
1953 if (act_elem
->str
) {
1954 fprintf(fp
, " -U%s", act_elem
->str
);
1956 act_elem
= act_elem
->next
;
1962 /* code splitting: command line argument wins */
1963 if (makefile
->code_splitting_mode
== NULL
) {
1964 if (makefile
->codesplittpd
) {
1965 makefile
->code_splitting_mode
= mcopystr("-U type");
1969 fprintf(fp
, "# Flags for the C++ compiler:\n"
1970 "CXXFLAGS = %s%s %s %s\n\n"
1971 "# Flags for the linker:\n"
1972 "LDFLAGS = %s%s\n\n"
1973 "ifeq ($(PLATFORM), WIN32)\n"
1974 "# Silence linker warnings.\n"
1975 "LDFLAGS += -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc\n"
1977 "# Utility to create library files\n"
1980 "# Flags for the TTCN-3 and ASN.1 compiler:\n"
1981 "COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n\n"
1982 "# Execution mode: (either ttcn3 or ttcn3-parallel)\n"
1983 "TTCN3_LIB = ttcn3%s%s%s\n\n"
1985 "# The path of your OpenSSL installation:\n"
1986 "# If you do not have your own one, leave it unchanged.\n"
1987 "%sOPENSSL_DIR = $(TTCN3_DIR)\n\n"
1989 "# The path of your libxml2 installation:\n"
1990 "# If you do not have your own one, leave it unchanged.\n"
1991 "XMLDIR = $(TTCN3_DIR)\n\n"
1992 "# Directory to store the archived source files:\n",
1993 makefile
->dynamic
? "-Wall -fPIC" : "-Wall", /* CXXFLAGS */
1994 makefile
->coverage
? " -fprofile-arcs -ftest-coverage -g" : "", /* CXXFLAGS COVERAGE */
1995 makefile
->optlevel
? makefile
->optlevel
: "", /* CXXFLAGS optimization level */
1996 makefile
->optflags
? makefile
->optflags
: "", /* CXXFLAGS optimization level */
1997 makefile
->dynamic
? "-fPIC" : "", /* LDFLAGS */
1998 makefile
->coverage
? " -fprofile-arcs -ftest-coverage -g -lgcov" : "", /* LDFLAGS COVERAGE */
1999 /* COMPILER_FLAGS */
2000 makefile
->use_runtime_2
? " -L -R " : " -L ",
2001 (makefile
->code_splitting_mode
? makefile
->code_splitting_mode
: ""),
2002 (makefile
->quietly
? " -q" : ""),
2003 (makefile
->disablesubtypecheck
? " -y" : ""),
2004 (makefile
->disableber
? " -b" : ""),
2005 (makefile
->disableraw
? " -r" : ""),
2006 (makefile
->disabletext
? " -x" : ""),
2007 (makefile
->disablexer
? " -X" : ""),
2008 (makefile
->disablejson
? " -j" : ""),
2009 (makefile
->forcexerinasn
? " -a" : ""),
2010 (makefile
->defaultasomit
? " -d" : ""),
2011 (makefile
->gccmsgformat
? " -g" : ""),
2012 (makefile
->linenumbersonlymsg
? " -i" : ""),
2013 (makefile
->includesourceinfo
? " -l" : ""),
2014 /*(makefile->addsourcelineinfo ? " -L" : ""),*/
2015 (makefile
->suppresswarnings
? " -w" : ""),
2016 (makefile
->outparamboundness
? " -Y" : ""),
2017 (makefile
->omit_in_value_list
? " -M" : ""),
2018 (makefile
->warnings_for_bad_variants
? " -E" : ""),
2019 (makefile
->tcov_file_name
? makefile
->tcov_file_name
: ""),
2020 (makefile
->profiled_file_list
? " -z $(PROFILED_FILE_LIST)" : ""),
2021 /* end of COMPILER FLAGS */
2022 (makefile
->use_runtime_2
? "-rt2" : ""), /* TTCN3_LIB */
2023 (makefile
->single_mode
? "" : "-parallel"),
2024 (makefile
->dynamic
? "-dynamic": "")
2026 ,(makefile
->disable_predef_ext_folder
? "# " : "")
2029 if (!makefile
->gnu_make
) {
2030 fputs("# Note: you can set any directory except ./archive\n", fp
);
2032 fputs("ARCHIVE_DIR = backup\n\n"
2034 "# You may change these variables. Add your files if necessary...\n"
2036 "# TTCN-3 modules of this project:\n"
2037 "TTCN3_MODULES =", fp
);
2038 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2039 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2040 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2041 /* If the file is in the current directory or
2042 * is not in the current directory but central directory is not used,
2043 * it goes into TTCN3_MODULES */
2044 print_file_name(fp
, module
);
2046 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_MODULES");
2047 if (makefile
->preprocess
) {
2049 "# TTCN-3 modules to preprocess:\n"
2050 "TTCN3_PP_MODULES =", fp
);
2051 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2052 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2053 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2054 print_file_name(fp
, module
);
2056 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_PP_MODULES");
2058 if (makefile
->central_storage
) {
2060 "# TTCN-3 modules used from central project(s):\n"
2061 "BASE_TTCN3_MODULES =", fp
);
2062 if (!makefile
->linkingStrategy
) {
2063 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2064 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2065 /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
2066 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
2068 if (makefile
->preprocess
) {
2070 "# TTCN-3 modules to preprocess used from central project(s):\n"
2071 "BASE_TTCN3_PP_MODULES =", fp
);
2072 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2073 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2074 if (module
->dir_name
!= NULL
&& !isTtcnPPFileInLibrary(module
->file_name
))
2075 print_file_name(fp
, module
);
2079 else { // new linking strategy
2080 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2081 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2082 /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
2083 if (module
->dir_name
!= NULL
&& !isTtcn3ModuleInLibrary(module
->module_name
))
2084 print_file_name(fp
, module
);
2087 "# TTCN-3 library linked modules used from central project(s):\n"
2088 "BASE2_TTCN3_MODULES =", fp
);
2089 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2090 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2091 /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
2092 if (module
->dir_name
!= NULL
&& isTtcn3ModuleInLibrary(module
->module_name
))
2093 print_file_name(fp
, module
);
2095 if (makefile
->preprocess
) {
2097 "# TTCN-3 modules to preprocess used from central project(s):\n"
2098 "BASE_TTCN3_PP_MODULES =", fp
);
2099 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2100 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2101 if (module
->dir_name
!= NULL
&& !isTtcnPPFileInLibrary(module
->file_name
))
2102 print_file_name(fp
, module
);
2105 "# TTCN-3 library linked modules to preprocess used from central project(s):\n"
2106 "BASE2_TTCN3_PP_MODULES =", fp
);
2107 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2108 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2109 if (module
->dir_name
!= NULL
&& isTtcnPPFileInLibrary(module
->file_name
))
2110 print_file_name(fp
, module
);
2115 if (makefile
->preprocess
) {
2117 "# Files to include in TTCN-3 preprocessed modules:\n"
2118 "TTCN3_INCLUDES =", fp
);
2119 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
2120 fprintf(fp
, " %s", makefile
->TTCN3IncludeFiles
[i
]);
2121 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_INCLUDES");
2124 "# ASN.1 modules of this project:\n"
2125 "ASN1_MODULES =", fp
);
2126 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2127 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2128 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2129 print_file_name(fp
, module
);
2131 fprint_extra_targets(fp
, makefile
->target_placement_list
, "ASN1_MODULES");
2132 if (makefile
->central_storage
) {
2134 "# ASN.1 modules used from central project(s):\n"
2135 "BASE_ASN1_MODULES =", fp
);
2136 if (!makefile
->linkingStrategy
) {
2137 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2138 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2139 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
2143 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2144 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2145 if (module
->dir_name
!= NULL
&& !isAsn1ModuleInLibrary(module
->module_name
))
2146 print_file_name(fp
, module
);
2149 "# ASN.1 library linked modules used from central project(s):\n"
2150 "BASE2_ASN1_MODULES =", fp
);
2151 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2152 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2153 if (module
->dir_name
!= NULL
&& isAsn1ModuleInLibrary(module
->module_name
))
2154 print_file_name(fp
, module
);
2158 if (makefile
->preprocess
) {
2160 "# TTCN-3 source files generated by the C preprocessor:\n"
2161 "PREPROCESSED_TTCN3_MODULES =", fp
);
2162 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2163 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2164 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2165 print_preprocessed_file_name(fp
, module
);
2167 if (makefile
->central_storage
) {
2169 "# TTCN-3 files generated by the CPP used from central project(s):\n"
2170 "BASE_PREPROCESSED_TTCN3_MODULES =", fp
);
2171 if (!makefile
->linkingStrategy
) {
2172 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2173 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2174 if (module
->dir_name
!= NULL
)
2175 print_preprocessed_file_name(fp
, module
);
2178 else { // new linking strategy
2179 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2180 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2181 if (module
->dir_name
!= NULL
&& !isTtcnPPFileInLibrary(module
->file_name
))
2182 print_preprocessed_file_name(fp
, module
);
2185 "# TTCN-3 library linked files generated by the CPP used from central project(s):\n"
2186 "BASE2_PREPROCESSED_TTCN3_MODULES =", fp
);
2187 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2188 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2189 if (module
->dir_name
!= NULL
&& isTtcnPPFileInLibrary(module
->file_name
))
2190 print_preprocessed_file_name(fp
, module
);
2195 if (makefile
->profiled_file_list
) {
2196 if (makefile
->profiled_file_list
->next
&& !makefile
->central_storage
) {
2197 // merge all profiled file lists into one list
2199 "# Text file containing the list of profiled TTCN-3 files of "
2201 "PROFILED_FILE_LIST = %s.merged\n"
2202 "PROFILED_FILE_LIST_SEGMENTS =",
2203 makefile
->profiled_file_list
->str
);
2204 struct string_list
* iter
= makefile
->profiled_file_list
;
2205 while(iter
!= NULL
) {
2206 fprintf(fp
, " %s", iter
->str
);
2211 // only one profiled file list is needed
2213 "# Text file containing the list of profiled TTCN-3 files of "
2215 "PROFILED_FILE_LIST = %s", makefile
->profiled_file_list
->str
);
2219 "# C++ source & header files generated from the TTCN-3 & ASN.1 "
2222 "GENERATED_SOURCES =", fp
);
2223 if (makefile
->gnu_make
&& makefile
->TTCN3ModulesRegular
) {
2224 fputs(" $(TTCN3_MODULES:.ttcn=.cc)", fp
);
2225 if (makefile
->code_splitting_mode
) {
2226 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2227 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2228 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2229 print_splitted_file_names(fp
, makefile
, module
);
2232 if (makefile
->preprocess
) {
2233 fputs(" $(TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2234 if (makefile
->code_splitting_mode
) {
2235 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2236 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2237 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2238 print_splitted_file_names(fp
, makefile
, module
);
2243 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2244 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2245 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2246 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2247 if (makefile
->code_splitting_mode
)
2248 print_splitted_file_names(fp
, makefile
, module
);
2251 if (makefile
->preprocess
) {
2252 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2253 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2254 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2255 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2256 if (makefile
->code_splitting_mode
)
2257 print_splitted_file_names(fp
, makefile
, module
);
2262 if (makefile
->gnu_make
&& makefile
->ASN1ModulesRegular
) {
2263 fputs(" $(ASN1_MODULES:.asn=.cc)", fp
);
2264 if (makefile
->code_splitting_mode
) {
2265 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2266 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2267 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2268 print_splitted_file_names(fp
, makefile
, module
);
2273 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2274 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2275 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2276 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2277 if (makefile
->code_splitting_mode
)
2278 print_splitted_file_names(fp
, makefile
, module
);
2283 fputs("\nGENERATED_HEADERS =", fp
);
2284 if (makefile
->gnu_make
) {
2285 fputs(" $(GENERATED_SOURCES:.cc=.hh)", fp
);
2288 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2289 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2290 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2291 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2293 if (makefile
->preprocess
) {
2294 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2295 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2296 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2297 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2300 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2301 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2302 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2303 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2306 if (makefile
->central_storage
) {
2308 "# C++ source & header files generated from the TTCN-3 & ASN.1 "
2310 "# central project(s):\n"
2311 "BASE_GENERATED_SOURCES =", fp
);
2312 if (makefile
->gnu_make
&& makefile
->BaseTTCN3ModulesRegular
) {
2313 fputs(" $(BASE_TTCN3_MODULES:.ttcn=.cc)", fp
);
2314 if (makefile
->code_splitting_mode
) {
2315 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2316 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2317 if (module
->dir_name
!= NULL
) {
2318 print_splitted_file_names(fp
, makefile
, module
);
2322 if (makefile
->preprocess
) {
2323 fputs(" $(BASE_TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2324 if (makefile
->code_splitting_mode
) {
2325 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2326 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2327 if (module
->dir_name
!= NULL
) {
2328 print_splitted_file_names(fp
, makefile
, module
);
2334 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2335 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2336 if (module
->dir_name
!= NULL
) {
2337 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2338 if (makefile
->code_splitting_mode
)
2339 print_splitted_file_names(fp
, makefile
, module
);
2342 if (makefile
->preprocess
) {
2343 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2344 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2345 if (module
->dir_name
!= NULL
) {
2346 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2347 if (makefile
->code_splitting_mode
)
2348 print_splitted_file_names(fp
, makefile
, module
);
2353 if (makefile
->gnu_make
&& makefile
->BaseASN1ModulesRegular
) {
2354 fputs(" $(BASE_ASN1_MODULES:.asn=.cc)", fp
);
2355 if (makefile
->code_splitting_mode
) {
2356 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2357 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2358 if (module
->dir_name
!= NULL
) {
2359 print_splitted_file_names(fp
, makefile
, module
);
2364 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2365 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2366 if (module
->dir_name
!= NULL
) {
2367 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2368 if (makefile
->code_splitting_mode
)
2369 print_splitted_file_names(fp
, makefile
, module
);
2373 fputs("\nBASE_GENERATED_HEADERS =", fp
);
2374 if (makefile
->gnu_make
) {
2375 fputs(" $(BASE_GENERATED_SOURCES:.cc=.hh)", fp
);
2377 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2378 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2379 if (module
->dir_name
!= NULL
)
2380 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2382 if (makefile
->preprocess
) {
2383 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2384 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2385 if (module
->dir_name
!= NULL
)
2386 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2389 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2390 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2391 if (module
->dir_name
!= NULL
)
2392 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2397 if (makefile
->linkingStrategy
) {
2399 "# C++ source & header files generated from the TTCN-3 "
2400 " library linked modules of\n"
2401 "# central project(s):\n"
2402 "BASE2_GENERATED_SOURCES =", fp
);
2403 if (makefile
->gnu_make
&& makefile
->BaseTTCN3ModulesRegular
) {
2404 fputs(" $(BASE2_TTCN3_MODULES:.ttcn=.cc)", fp
);
2405 fputs(" $(BASE2_ASN1_MODULES:.asn=.cc)", fp
);
2406 if (makefile
->preprocess
)
2407 fputs(" $(BASE2_TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2410 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2411 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2412 if (module
->dir_name
!= NULL
&& isTtcn3ModuleInLibrary(module
->module_name
)) {
2413 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2416 if (makefile
->preprocess
) {
2417 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2418 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2419 if (module
->dir_name
!= NULL
&& isTtcnPPFileInLibrary(module
->file_name
)) {
2420 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2426 fputs("\nBASE2_GENERATED_HEADERS =", fp
);
2427 if (makefile
->gnu_make
) {
2428 fputs(" $(BASE2_GENERATED_SOURCES:.cc=.hh)", fp
);
2431 ERROR("the usage of 'Z' flag requires GNU make");
2435 "# C/C++ Source & header files of Test Ports, external functions "
2437 "# other modules:\n"
2438 "USER_SOURCES =", fp
);
2439 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2440 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2441 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2442 print_source_name(fp
, user
);
2444 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_SOURCES");
2445 fputs("\nUSER_HEADERS =", fp
);
2446 if (makefile
->gnu_make
&& makefile
->UserHeadersRegular
) {
2447 fputs(" $(USER_SOURCES:.cc=.hh)", fp
);
2449 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2450 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2451 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2452 print_header_name(fp
, user
);
2455 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_HEADERS");
2456 if (makefile
->central_storage
) {
2458 "# C/C++ Source & header files of Test Ports, external functions "
2460 "# other modules used from central project(s):\n"
2461 "BASE_USER_SOURCES =", fp
);
2462 if (!makefile
->linkingStrategy
) {
2463 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2464 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2465 if (user
->dir_name
!= NULL
) {
2466 print_source_name(fp
, user
);
2469 fputs("\nBASE_USER_HEADERS =", fp
);
2470 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2471 fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp
);
2474 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2475 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2476 if (user
->dir_name
!= NULL
)
2477 print_header_name(fp
, user
);
2482 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2483 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2484 if (user
->dir_name
!= NULL
&& !isSourceFileInLibrary(user
->source_name
)) {
2485 print_source_name(fp
, user
);
2488 fputs("\nBASE_USER_HEADERS =", fp
);
2489 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2490 fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp
);
2493 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2494 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2495 if (user
->dir_name
!= NULL
&& !isHeaderFileInLibrary(user
->header_name
))
2496 print_header_name(fp
, user
);
2501 "# C/C++ Source & header files of Test Ports, external functions "
2503 "# other modules used from library linked central project(s):\n"
2504 "BASE2_USER_SOURCES =", fp
);
2505 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2506 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2507 if (user
->dir_name
!= NULL
&& isSourceFileInLibrary(user
->source_name
)) {
2508 print_source_name(fp
, user
);
2511 fputs("\nBASE2_USER_HEADERS =", fp
);
2512 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2513 fputs(" $(BASE2_USER_SOURCES:.cc=.hh)", fp
);
2516 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2517 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2518 if (user
->dir_name
!= NULL
&& isHeaderFileInLibrary(user
->header_name
))
2519 print_header_name(fp
, user
);
2524 if (makefile
->dynamic
) {
2526 "# Shared object files of this project:\n"
2527 "SHARED_OBJECTS =", fp
);
2528 if (makefile
->gnu_make
) {
2529 fputs(" $(GENERATED_SOURCES:.cc=.so)", fp
);
2531 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2532 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2533 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2534 print_generated_file_name(fp
, module
, FALSE
, ".so");
2535 if (makefile
->code_splitting_mode
!= NULL
)
2536 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2537 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2538 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2539 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2540 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2541 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2545 if (makefile
->preprocess
) {
2546 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2547 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2548 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2549 print_generated_file_name(fp
, module
, FALSE
, ".so");
2550 if (makefile
->code_splitting_mode
!= NULL
)
2551 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2552 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2553 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2554 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2555 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2556 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2561 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2562 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2563 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2564 print_generated_file_name(fp
, module
, FALSE
, ".so");
2565 if (makefile
->code_splitting_mode
!= NULL
)
2566 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2567 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2568 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2569 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2570 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2571 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2576 if (makefile
->gnu_make
&& makefile
->UserSourcesRegular
) {
2577 fputs(" $(USER_SOURCES:.cc=.so)", fp
);
2579 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2580 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2581 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2582 print_shared_object_name(fp
, user
);
2588 "# Object files of this project that are needed for the executable "
2590 "OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)\n\n" /* never := */
2591 "GENERATED_OBJECTS =", fp
);
2592 if (makefile
->gnu_make
) {
2593 fputs(" $(GENERATED_SOURCES:.cc=.o)", fp
);
2595 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2596 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2597 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2598 print_generated_file_name(fp
, module
, FALSE
, ".o");
2599 if (makefile
->code_splitting_mode
!= NULL
)
2600 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2601 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2602 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2603 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2604 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2605 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2609 if (makefile
->preprocess
) {
2610 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2611 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2612 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2613 print_generated_file_name(fp
, module
, FALSE
, ".o");
2614 if (makefile
->code_splitting_mode
!= NULL
)
2615 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2616 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2617 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2618 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2619 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2620 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2625 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2626 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2627 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2628 print_generated_file_name(fp
, module
, FALSE
, ".o");
2629 if (makefile
->code_splitting_mode
!= NULL
)
2630 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2631 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2632 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2633 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2634 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2635 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2641 fputs("\n\nUSER_OBJECTS =", fp
);
2642 if (makefile
->gnu_make
&& makefile
->UserSourcesRegular
) {
2643 fputs(" $(USER_SOURCES:.cc=.o)", fp
);
2645 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2646 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2647 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2648 print_object_name(fp
, user
);
2651 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_OBJECTS");
2653 if (makefile
->gcc_dep
) {
2654 /* GNU Make processes included makefiles in reverse order. By putting
2655 * user sources first, their .d will be generated last, after the
2656 * GENERATED_SOURCES (and GENERATED_HEADERS) have been created.
2657 * This avoid spurious errors during incremental dependency generation */
2658 fputs("\n\nDEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d)", fp
);
2661 if (makefile
->central_storage
) {
2662 if (makefile
->dynamic
) {
2664 "# Shared object files of central project(s):\n"
2665 "BASE_SHARED_OBJECTS =", fp
);
2666 if (!makefile
->linkingStrategy
) {
2667 if (makefile
->gnu_make
) {
2668 fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp
);
2671 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2672 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2673 if (module
->dir_name
!= NULL
)
2674 print_generated_file_name(fp
, module
, TRUE
, ".so");
2676 if (makefile
->preprocess
) {
2677 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2678 const struct module_struct
*module
=
2679 makefile
->TTCN3PPModules
+ i
;
2680 if (module
->dir_name
!= NULL
)
2681 print_generated_file_name(fp
, module
, TRUE
, ".so");
2684 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2685 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2686 if (module
->dir_name
!= NULL
)
2687 print_generated_file_name(fp
, module
, TRUE
, ".so");
2690 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2691 fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp
);
2694 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2695 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2696 if (user
->dir_name
!= NULL
)
2697 print_shared_object_name(fp
, user
);
2701 else { // new linkingStrategy
2702 if (makefile
->gnu_make
) {
2703 fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp
);
2706 ERROR("the usage of 'Z' flag requires GNU make");
2708 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2709 fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp
);
2712 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2713 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2714 if (user
->dir_name
!= NULL
&& !isSourceFileInLibrary(user
->source_name
))
2715 print_shared_object_name(fp
, user
);
2721 "# Object files of central project(s) that are needed for the "
2722 "executable test suite:\n"
2723 "BASE_OBJECTS =", fp
);
2724 if (!makefile
->linkingStrategy
) {
2725 if (makefile
->gnu_make
) {
2726 fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp
);
2729 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2730 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2731 if (module
->dir_name
!= NULL
)
2732 print_generated_file_name(fp
, module
, TRUE
, ".o");
2734 if (makefile
->preprocess
) {
2735 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2736 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2737 if (module
->dir_name
!= NULL
)
2738 print_generated_file_name(fp
, module
, TRUE
, ".o");
2741 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2742 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2743 if (module
->dir_name
!= NULL
)
2744 print_generated_file_name(fp
, module
, TRUE
, ".o");
2747 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2748 fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp
);
2751 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2752 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2753 if (user
->dir_name
!= NULL
)
2754 print_object_name(fp
, user
);
2758 else { // new linkingStrategy
2759 if (makefile
->gnu_make
) {
2760 fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp
);
2763 ERROR("the usage of 'Z' flag requires GNU make");
2765 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2766 fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp
);
2769 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2770 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2771 if (user
->dir_name
!= NULL
&& !isSourceFileInLibrary(user
->source_name
))
2772 print_object_name(fp
, user
);
2777 if (makefile
->linkingStrategy
) {
2779 "# Object files of library linked central project(s) that are needed for the "
2780 "executable test suite:\n"
2781 "BASE2_OBJECTS =", fp
);
2782 if (makefile
->gnu_make
) {
2783 if (makefile
->dynamic
)
2784 fputs(" $(BASE2_GENERATED_SOURCES:.cc=.so)", fp
);
2786 fputs(" $(BASE2_GENERATED_SOURCES:.cc=.o)", fp
);
2788 else ERROR("the usage of 'Z' flag requires GNU make");
2790 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2791 if (makefile
->dynamic
)
2792 fputs(" $(BASE2_USER_SOURCES:.cc=.so)", fp
);
2794 fputs(" $(BASE2_USER_SOURCES:.cc=.o)", fp
);
2797 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2798 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2799 if (user
->dir_name
!= NULL
&& isSourceFileInLibrary(user
->source_name
)) {
2800 if (makefile
->dynamic
)
2801 print_shared_object_name(fp
, user
);
2803 print_object_name(fp
, user
);
2807 if (makefile
->hierarchical
) {
2809 "#Libraries of referenced project(s) that are needed for the "
2810 "executable or library target:\n"
2811 "BASE2_LIBRARY =", fp
);
2812 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
2813 struct string2_list
* act_elem
= head
;
2815 if (act_elem
->str2
) {
2817 fprintf(fp
, "%s/lib%s.%s", act_elem
->str1
, act_elem
->str2
,
2818 isDynamicLibrary(act_elem
->str2
) ? "so" : "a");
2820 act_elem
= act_elem
->next
;
2822 free_string2_list(head
);
2827 "# Other files of the project (Makefile, configuration files, etc.)\n"
2828 "# that will be added to the archived source files:\n"
2829 "OTHER_FILES =", fp
);
2830 for (i
= 0; i
< makefile
->nOtherFiles
; i
++)
2831 fprintf(fp
, " %s", makefile
->OtherFiles
[i
]);
2832 fprint_extra_targets(fp
, makefile
->target_placement_list
, "OTHER_FILES");
2834 if (makefile
->ets_name
) {
2835 const char *ets_suffix
= NULL
;
2836 /* EXECUTABLE variable */
2838 "# The name of the executable test suite:\n"
2839 "EXECUTABLE = %s", makefile
->ets_name
);
2842 /* add the .exe suffix unless it is already present */
2843 ets_suffix
= get_suffix(makefile
->ets_name
);
2844 if (ets_suffix
== NULL
|| strcmp(ets_suffix
, "exe"))
2849 if (makefile
->linkingStrategy
) {
2851 fputs("DYNAMIC_LIBRARY = lib$(EXECUTABLE).so\n", fp
);
2852 fputs("STATIC_LIBRARY = lib$(EXECUTABLE).a\n", fp
);
2854 char* name_prefix
= cut_suffix(makefile
->ets_name
);
2855 fprintf(fp
, "DYNAMIC_LIBRARY = lib%s.so\n", name_prefix
);
2856 fprintf(fp
, "STATIC_LIBRARY = lib%s.a\n", name_prefix
);
2860 /* LIBRARY variable */
2861 ets_suffix
= get_suffix(makefile
->ets_name
);
2862 if (ets_suffix
!= NULL
&& !strcmp(ets_suffix
, "exe")) {
2863 char* name_prefix
= cut_suffix(makefile
->ets_name
);
2864 fprintf(fp
, "\n\nLIBRARY = %s%s%s\n", "lib", name_prefix
? name_prefix
: "library",
2865 makefile
->dynamic
? ".so" : ".a");
2870 fprintf(fp
, "\n\nLIBRARY = lib$(EXECUTABLE)%s\n",
2871 makefile
->dynamic
? ".so" : ".a");
2873 fprintf(fp
, "\n\nLIBRARY = lib%s%s\n",
2874 makefile
->ets_name
, makefile
->dynamic
? ".so" : ".a");
2880 "# The name of the executable test suite:\n"
2884 if (!makefile
->linkingStrategy
|| !buildObjects(makefile
->project_name
, add_refd_prjs
)) {
2886 "TARGET = $(%s)", makefile
->library
? "LIBRARY" : "EXECUTABLE");
2889 if (makefile
->dynamic
) {
2891 "TARGET = $(SHARED_OBJECTS)", fp
);
2895 "TARGET = $(OBJECTS)", fp
);
2900 "# Do not modify these unless you know what you are doing...\n"
2901 "# Platform specific additional libraries:\n"
2904 fputs("SOLARIS_LIBS = -lsocket -lnsl -lxml2", fp
);
2906 fputs(" -lresolv", fp
);
2908 if (makefile
->solspeclibraries
) {
2909 struct string_list
* act_elem
= makefile
->solspeclibraries
;
2911 if (act_elem
->str
) {
2912 fprintf(fp
, " -l%s", act_elem
->str
);
2914 act_elem
= act_elem
->next
;
2919 fputs("SOLARIS8_LIBS = -lsocket -lnsl -lxml2", fp
);
2921 fputs(" -lresolv", fp
);
2923 if (makefile
->sol8speclibraries
) {
2924 struct string_list
* act_elem
= makefile
->sol8speclibraries
;
2926 if (act_elem
->str
) {
2927 fprintf(fp
, " -l%s", act_elem
->str
);
2929 act_elem
= act_elem
->next
;
2934 fputs("LINUX_LIBS = -lxml2", fp
);
2936 fputs(" -lpthread -lrt", fp
);
2938 if (makefile
->linuxspeclibraries
) {
2939 struct string_list
* act_elem
= makefile
->linuxspeclibraries
;
2941 if (act_elem
->str
) {
2942 fprintf(fp
, " -l%s", act_elem
->str
);
2944 act_elem
= act_elem
->next
;
2949 fputs("FREEBSD_LIBS = -lxml2", fp
);
2950 if (makefile
->freebsdspeclibraries
) {
2951 struct string_list
* act_elem
= makefile
->freebsdspeclibraries
;
2953 if (act_elem
->str
) {
2954 fprintf(fp
, " -l%s", act_elem
->str
);
2956 act_elem
= act_elem
->next
;
2961 fputs("WIN32_LIBS = -lxml2", fp
);
2962 if (makefile
->win32speclibraries
) {
2963 struct string_list
* act_elem
= makefile
->win32speclibraries
;
2965 if (act_elem
->str
) {
2966 fprintf(fp
, " -l%s", act_elem
->str
);
2968 act_elem
= act_elem
->next
;
2974 "# Rules for building the executable...\n"
2976 fprintf(fp
, "all:%s $(TARGET) ;\n\n", add_refd_prjs
?" referenced-all":"");
2978 if (makefile
->dynamic
) {
2979 fprintf(fp
, "shared_objects:%s $(SHARED_OBJECTS) ;\n\n", add_refd_prjs
?" referenced-shared_objects":"");
2983 "executable:%s $(EXECUTABLE) ;\n\n"
2984 "library:%s $(LIBRARY) ;\n\n"
2985 "objects:%s $(OBJECTS) compile;\n\n", add_refd_prjs
?" referenced-executable":"", add_refd_prjs
?" referenced-library":"", add_refd_prjs
?" referenced-objects":"");
2987 /* target $(EXECUTABLE) */
2988 if (makefile
->dynamic
&& makefile
->library
) {
2989 /* There is no need to create the .so for all the source files */
2990 fputs("$(EXECUTABLE): $(LIBRARY)\n"
2991 "\tif $(CXX) $(LDFLAGS) -o $@ $(LIBRARY)", fp
);
2994 fprintf(fp
, "$(EXECUTABLE): %s", makefile
->dynamic
? "$(SHARED_OBJECTS)" : "$(OBJECTS)");
2995 if (!makefile
->linkingStrategy
) { // use the old linking method
2996 if (makefile
->central_storage
) {
2997 if (makefile
->dynamic
) {
2998 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
3000 fputs(" $(BASE_OBJECTS)", fp
);
3005 if (!makefile
->library
) {
3006 if (makefile
->dynamic
) {
3007 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
3010 fputs(" $(BASE_OBJECTS)", fp
);
3012 if (makefile
->hierarchical
) {
3013 fputs(" $(BASE2_LIBRARY)", fp
);
3018 "\tif $(CXX) $(LDFLAGS) -o $@ %s",
3019 #if defined (SOLARIS) || defined (SOLARIS8)
3022 makefile
->dynamic
? "-Wl,--no-as-needed " : ""); /* start writing the link step */
3024 if (makefile
->gnu_make
) fputs("$^", fp
);
3026 if (makefile
->dynamic
) {
3027 fputs("$(SHARED_OBJECTS)", fp
);
3028 if (makefile
->central_storage
)
3029 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
3032 fputs("$(OBJECTS)", fp
);
3033 if (makefile
->central_storage
)
3034 fputs(" $(BASE_OBJECTS)", fp
);
3039 if (makefile
->additionalObjects
) {
3040 struct string_list
* act_elem
= makefile
->additionalObjects
;
3042 if (act_elem
->str
) {
3043 fprintf(fp
, " %s", act_elem
->str
);
3045 act_elem
= act_elem
->next
;
3050 "\t-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB)"
3052 "\t-L$(OPENSSL_DIR)/lib -lcrypto");
3053 if (!makefile
->linkingStrategy
) {
3054 if (makefile
->linkerlibraries
) {
3055 struct string_list
* act_elem
= makefile
->linkerlibraries
;
3057 if (act_elem
->str
) {
3058 fprintf(fp
, " -l%s", act_elem
->str
);
3060 act_elem
= act_elem
->next
;
3063 if (makefile
->linkerlibsearchpath
) {
3064 struct string_list
* act_elem
= makefile
->linkerlibsearchpath
;
3066 if (act_elem
->str
) {
3067 fprintf(fp
, " -L%s", act_elem
->str
);
3069 act_elem
= act_elem
->next
;
3073 "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
3074 "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
3076 else { // new linking strategy
3077 fputs (" \\\n", fp
);
3078 if (makefile
->linkerlibraries
&& !makefile
->library
) {
3079 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
3080 struct string2_list
* act_elem
= head
;
3082 if (act_elem
->str1
&& act_elem
->str2
) {
3083 fprintf(fp
, "\t-L%s -Wl,-rpath=%s -l%s \\\n", act_elem
->str1
, act_elem
->str1
, act_elem
->str2
);
3085 act_elem
= act_elem
->next
;
3087 free_string2_list(head
);
3089 struct string_list
* act_head
= getExternalLibPaths(makefile
->project_name
);
3090 struct string_list
* act_ext_elem
= act_head
;
3091 while (act_ext_elem
) {
3092 if (act_ext_elem
->str
) {
3093 fprintf(fp
, "\t-L%s \\\n", act_ext_elem
->str
);
3095 act_ext_elem
= act_ext_elem
->next
;
3097 free_string_list(act_head
);
3098 act_head
= getExternalLibs(makefile
->project_name
);
3099 act_ext_elem
= act_head
;
3100 while (act_ext_elem
) {
3101 if (act_ext_elem
->str
) {
3102 fprintf(fp
, "\t-l%s \\\n", act_ext_elem
->str
);
3104 act_ext_elem
= act_ext_elem
->next
;
3106 free_string_list(act_head
);
3109 "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
3110 "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
3112 /* If the compiler will not be run because there are no TTCN(PP) or ASN.1
3113 * files, create the "compile" marker file which is checked by the
3114 * superior makefile if using this project as central storage */
3115 if (!run_compiler
) fputs("\ttouch compile\n", fp
);
3116 /* End of target $(EXECUTABLE) */
3118 /* target $(LIBRARY) */
3119 if (makefile
->dynamic
) {
3121 "$(LIBRARY): $(OBJECTS)%s\n"
3122 "\t$(CXX) -shared -o $@ $(OBJECTS)",
3123 makefile
->hierarchical
? " $(BASE2_LIBRARY)" : "");
3124 if (makefile
->central_storage
&& !makefile
->linkingStrategy
) {
3125 fputs(" $(BASE_SHARED_OBJECTS) ;\n"
3126 "\tln -s $@ $(subst lib, ,$@) > /dev/null 2>&1 ;", fp
);
3128 if (makefile
->linkingStrategy
) {
3129 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
3130 struct string2_list
* act_elem
= head
;
3131 // If the project is Executable on Top Level the linker can link the *.a and *.so together
3132 while (act_elem
&& !isTopLevelExecutable(makefile
->project_name
)) {
3133 if (act_elem
->str1
&& act_elem
->str2
&& isDynamicLibrary(act_elem
->str2
)) {
3135 fprintf(fp
, "\t-L%s -Wl,-rpath=%s -l%s", act_elem
->str1
, act_elem
->str1
, act_elem
->str2
);
3138 const char* mainLibName
= getLibFromProject(makefile
->project_name
);
3139 ERROR("Library archive 'lib%s.a' cannot be linked to dynamic library 'lib%s.so' "
3141 act_elem
->str2
, mainLibName
? mainLibName
: "", makefile
->project_name
);
3142 free_string2_list(head
);
3145 act_elem
= act_elem
->next
;
3147 free_string2_list(head
);
3148 struct string_list
* act_head
= getExternalLibPaths(makefile
->project_name
);
3149 struct string_list
* act_ext_elem
= act_head
;
3150 while (act_ext_elem
) {
3151 if (act_ext_elem
->str
) {
3153 fprintf(fp
, "\t-L%s", act_ext_elem
->str
);
3155 act_ext_elem
= act_ext_elem
->next
;
3157 free_string_list(act_head
);
3158 act_head
= getExternalLibs(makefile
->project_name
);
3159 act_ext_elem
= act_head
;
3160 while (act_ext_elem
) {
3161 if (act_ext_elem
->str
) {
3163 fprintf(fp
, "\t-l%s", act_ext_elem
->str
);
3165 act_ext_elem
= act_ext_elem
->next
;
3167 free_string_list(act_head
);
3170 else { // static linking
3172 "$(LIBRARY): $(OBJECTS)%s\n"
3173 "\t$(AR) -r%s $(ARFLAGS) $(LIBRARY) $(OBJECTS)",
3174 makefile
->hierarchical
? " $(BASE2_LIBRARY)" : "",
3175 makefile
->linkingStrategy
? "cT" : "");
3176 if (makefile
->central_storage
&& !makefile
->linkingStrategy
) {
3177 fputs(" $(BASE_OBJECTS)", fp
);
3179 if (makefile
->linkingStrategy
) {
3180 if ( makefile
->library
) {
3181 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
3182 struct string2_list
* act_elem
= head
;
3184 if (act_elem
->str2
&& !isDynamicLibrary(act_elem
->str2
)) {
3186 fprintf(fp
, "\t%s/lib%s.a", act_elem
->str1
, act_elem
->str2
);
3189 const char* mainLibName
= getLibFromProject(makefile
->project_name
);
3190 if (act_elem
->str2
) {
3191 ERROR("Dynamic library 'lib%s.so' cannot be linked to static library 'lib%s.a' "
3193 act_elem
->str2
, mainLibName
? mainLibName
: "", makefile
->project_name
);
3197 struct string_list
* ext_libs
= getExternalLibs(makefile
->project_name
);
3198 if (ext_libs
&& ext_libs
->str
) {
3199 ERROR("Third party dynamic library '%s' cannot be linked to static library 'lib%s.a' "
3200 "in project '%s' ", ext_libs
->str
,
3201 mainLibName
? mainLibName
: "", makefile
->project_name
);
3202 free_string_list(ext_libs
);
3205 free_string_list(ext_libs
);
3208 act_elem
= act_elem
->next
;
3210 free_string2_list(head
);
3212 struct string_list
* act_head
= getExternalLibs(makefile
->project_name
);
3213 struct string_list
* act_ext_elem
= act_head
;
3214 while (act_ext_elem
) {
3215 if (act_ext_elem
->str
&& hasExternalLibrary(act_ext_elem
->str
, makefile
->project_name
)) {
3217 fprintf(fp
, "\tlib%s.a", act_ext_elem
->str
);
3218 ERROR("linking static 3d party or sytem library 'lib%s.a' to "
3219 "project library 'lib%s.a' is not supported ",
3220 act_ext_elem
->str
, makefile
->ets_name
);
3223 act_ext_elem
= act_ext_elem
->next
;
3225 free_string_list(act_head
);
3229 fputs("\n\n.cc.o .c.o:\n"
3230 "\t$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<\n\n", fp
);
3232 if (makefile
->gcc_dep
) {
3233 fputs(".cc.d .c.d:\n"
3234 "\t@echo Creating dependency file for '$<'; set -e; \\\n"
3235 "\t$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \\\n"
3236 "\t| sed 's/\\($*\\)\\.o[ :]*/\\1.o $@ : /g' > $@; \\\n"
3237 "\t[ -s $@ ] || rm -f $@\n\n", fp
);
3238 /* "set -e" causes bash to exit the script if any statement
3239 * returns nonzero (failure).
3240 * The sed line transforms the first line of the dependency from
3241 * "x.o: x.cc" to "x.o x.d: x.cc", making the dependency file depend
3242 * on the source and headers.
3243 * [ -s x.d ] checks that the generated dependency is not empty;
3244 * otherwise it gets deleted.
3248 if (makefile
->dynamic
) {
3250 "\t$(CXX) -shared -o $@ $<\n\n", fp
);
3253 if (makefile
->preprocess
) {
3254 fputs("%.ttcn: %.ttcnpp $(TTCN3_INCLUDES)\n"
3255 "\t$(CPP) -x c -nostdinc $(CPPFLAGS_TTCN3) $< $@\n\n"
3256 "preprocess: $(PREPROCESSED_TTCN3_MODULES) ;\n\n", fp
);
3259 boolean merge_profiled_file_lists
= makefile
->profiled_file_list
3260 && makefile
->profiled_file_list
->next
&& !makefile
->central_storage
;
3261 if (makefile
->central_storage
) {
3262 boolean is_first
= TRUE
;
3263 fprintf(fp
, "$(GENERATED_SOURCES) $(GENERATED_HEADERS):%s compile-all compile ",
3264 makefile
->hierarchical
? " update" : "");
3266 if (add_refd_prjs
) fputs("referenced-dep", fp
);
3267 /* These extra compile dependencies for the generated .cc are here to
3268 * check if all the referenced projects are up to date.
3269 * If the referenced projects are built too then they are not needed
3270 * (and cause problems as the included .d depends on the .cc).
3272 if (!add_refd_prjs
) for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
3273 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
3274 if (base_dir
->has_modules
) {
3280 fprintf(fp
, "%s/compile", base_dir
->dir_name
);
3283 if (makefile
->preprocess
) {
3285 "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
3287 "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3288 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
3290 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n"
3291 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ",
3292 rm_command
, add_refd_prjs
?" referenced-check":"",
3293 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3294 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3295 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3296 if (makefile
->gnu_make
) {
3297 if (add_refd_prjs
) // referenced-check cannot be compiled it is not a ttcn modul
3298 fprintf(fp
, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3299 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
3301 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n",
3302 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3303 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3304 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3310 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
3311 "\t$(PREPROCESSED_TTCN3_MODULES) "
3312 "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
3313 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp
);
3315 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
3317 "update: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
3318 "\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) $(BASE2_PREPROCESSED_TTCN3_MODULES)\n"
3319 "ifneq ($(wildcard $(GENERATED_SOURCES)), ) \n"
3320 "ifeq ($(wildcard $?), ) \n"
3321 "\ttouch compile-all; \n"
3322 "\ttouch update; \n"
3326 if (makefile
->profiled_file_list
) {
3328 "compile:: $(PROFILED_FILE_LIST)\n"
3329 "\ttouch $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) "
3330 "$(ASN1_MODULES)", fp
);
3333 "compile:%s $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) "
3335 "\t@echo \"compiling \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
3336 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3337 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3338 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) %s\\\n"
3339 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s - $?\n"
3341 makefile
->profiled_file_list
? ":" : "",
3342 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3343 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3344 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES)":"");
3346 "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
3348 "\t$(MAKE) preprocess\n"
3349 "\t@echo \"compiling all \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
3350 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3351 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3352 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) %s"
3354 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3355 "\t- $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)\n"
3356 "\ttouch $@ compile\n\n",
3357 makefile
->linkingStrategy
? "\\\n\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) "
3358 "$(BASE2_PREPROCESSED_TTCN3_MODULES) \n":"\n",
3359 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3360 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3361 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3365 "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n", rm_command
);
3367 "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3368 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n"
3369 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ",
3370 add_refd_prjs
?" referenced-check":"",
3371 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3372 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3373 if (makefile
->gnu_make
) {
3374 if (add_refd_prjs
) // referenced-check cannot be compiled it is not a ttcn modul
3375 fprintf(fp
, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3376 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n",
3377 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3378 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3384 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
3385 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp
);
3388 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
3390 "update: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
3391 "\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) $(BASE2_PREPROCESSED_TTCN3_MODULES)\n"
3392 "ifneq ($(wildcard $(GENERATED_SOURCES)), ) \n"
3393 "ifeq ($(wildcard $?), ) \n"
3394 "\ttouch compile-all; \n"
3395 "\ttouch update; \n"
3400 if (makefile
->profiled_file_list
) {
3402 "compile:: $(PROFILED_FILE_LIST)\n"
3403 "\ttouch $(TTCN3_MODULES) $(ASN1_MODULES)", fp
);
3406 "compile:%s $(TTCN3_MODULES) $(ASN1_MODULES)\n"
3407 "\t@echo \"compiling \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
3408 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3409 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3410 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3413 makefile
->profiled_file_list
? ":" : "",
3414 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) " : "",
3415 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) " : "");
3417 "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) %s\n",
3418 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES)" : "");
3419 fputs("\t@echo \"compiling all \"'$(patsubst %.tpd, %, $(TPD))';\n", fp
);
3420 fprintf(fp
,"\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3421 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3422 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3423 "\t- $(TTCN3_MODULES) $(ASN1_MODULES)\n"
3424 "\ttouch $@ compile\n\n",
3425 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) " : "",
3426 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) " : "");
3428 if (!makefile
->hierarchical
)
3429 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
3430 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
3431 if (base_dir
->has_modules
) {
3433 fprintf(fp
, "%s/compile:", base_dir
->dir_name
);
3434 for (j
= 0; j
< makefile
->nTTCN3Modules
; j
++) {
3435 const struct module_struct
*module
= makefile
->TTCN3Modules
+ j
;
3436 if (module
->dir_name
!= NULL
&&
3437 !strcmp(base_dir
->dir_name
, module
->dir_name
))
3438 print_file_name(fp
, module
);
3440 for (j
= 0; j
< makefile
->nTTCN3PPModules
; j
++) {
3441 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ j
;
3442 if (module
->dir_name
!= NULL
&&
3443 !strcmp(base_dir
->dir_name
, module
->dir_name
))
3444 print_file_name(fp
, module
);
3446 for (j
= 0; j
< makefile
->nASN1Modules
; j
++) {
3447 const struct module_struct
*module
= makefile
->ASN1Modules
+ j
;
3448 if (module
->dir_name
!= NULL
&&
3449 !strcmp(base_dir
->dir_name
, module
->dir_name
))
3450 print_file_name(fp
, module
);
3453 "\t@echo 'Central directory %s is not up-to-date!'\n"
3454 "\t@exit 2\n\n", base_dir
->dir_name
);
3458 else { /* not central storage */
3459 fprintf(fp
, "$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile\n"
3460 "\t@if [ ! -f $@ ]; then %s compile; $(MAKE) compile; fi\n\n"
3462 "check:%s $(TTCN3_MODULES) ", rm_command
,
3463 merge_profiled_file_lists
? "check:: $(PROFILED_FILE_LIST)\n\n" : "",
3464 merge_profiled_file_lists
? ":" : "");
3465 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3466 fputs("$(ASN1_MODULES)\n"
3467 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", fp
);
3468 if (makefile
->gnu_make
) fputs("$^", fp
);
3471 "\t$(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)",
3474 if (makefile
->profiled_file_list
) {
3475 fputs("\n\ncompile:: $(PROFILED_FILE_LIST)\n"
3476 "\ttouch $(TTCN3_MODULES) ", fp
);
3477 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3478 fputs("$(ASN1_MODULES)", fp
);
3481 "compile:%s $(TTCN3_MODULES) ", makefile
->profiled_file_list
? ":" : "");
3482 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3483 fputs("$(ASN1_MODULES)\n"
3484 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) ", fp
);
3485 if (makefile
->gnu_make
) fputs("$^", fp
);
3488 "\t$(TTCN3_MODULES) ", fp
);
3489 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3490 fputs("$(ASN1_MODULES)", fp
);
3495 if (merge_profiled_file_lists
) {
3496 fputs("$(PROFILED_FILE_LIST): $(PROFILED_FILE_LIST_SEGMENTS)\n"
3497 "\tcat $(PROFILED_FILE_LIST_SEGMENTS) > $(PROFILED_FILE_LIST)\n\n", fp
);
3501 if (makefile
->linkingStrategy
) {
3502 fprintf(fp
, "clean:%s\n", (add_refd_prjs
&& !makefile
->hierarchical
) ?
3503 " referenced-clean" : "");
3504 if (makefile
->dynamic
&& (makefile
->central_storage
|| makefile
->linkingStrategy
)) {
3505 fprintf(fp
,"\tfind . -type l -name \"*.so\" -exec unlink {} \\;\n");
3507 fprintf(fp
, "\t%s $(EXECUTABLE) $(DYNAMIC_LIBRARY) $(STATIC_LIBRARY) "
3508 "$(OBJECTS) $(GENERATED_HEADERS) \\\n"
3509 "\t$(GENERATED_SOURCES) ", rm_command
);
3510 if (makefile
->dynamic
) fputs("$(SHARED_OBJECTS) ", fp
);
3511 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3512 fputs("compile", fp
);
3513 if (makefile
->central_storage
) fputs(" compile-all", fp
);
3514 if (makefile
->gcc_dep
) fputs(" $(DEPFILES)", fp
);
3515 if (merge_profiled_file_lists
) {
3516 fputs(" $(PROFILED_FILE_LIST)", fp
);
3519 "\ttags *.log%s%s\n\n",
3520 add_refd_prjs
?" referenced*":"",
3521 makefile
->hierarchical
? " update":"");
3524 fprintf(fp
, "clean:%s\n"
3525 "\t-%s $(EXECUTABLE) $(LIBRARY) $(OBJECTS) $(GENERATED_HEADERS) \\\n"
3526 "\t$(GENERATED_SOURCES) ", add_refd_prjs
?" referenced-clean":"", rm_command
);
3527 if (makefile
->dynamic
) fputs("$(SHARED_OBJECTS) ", fp
);
3528 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3529 fputs("compile", fp
);
3530 if (makefile
->central_storage
) fputs(" compile-all", fp
);
3531 if (makefile
->gcc_dep
) fputs(" $(DEPFILES)", fp
);
3532 if (merge_profiled_file_lists
) {
3533 fputs(" $(PROFILED_FILE_LIST)", fp
);
3537 add_refd_prjs
?" referenced*":"");
3541 if (makefile
->linkingStrategy
&& makefile
->hierarchical
)
3542 fprintf(fp
, "clean-all: %s clean\n", add_refd_prjs
? "referenced-clean-all":"");
3545 fputs("\n\ndep: $(GENERATED_SOURCES) $(USER_SOURCES)",fp
);
3546 if (add_refd_prjs
) {
3547 fprintf(fp
, "\n\t%s referenced-dep", rm_command
);
3549 else fputs(" ;",fp
);
3551 if (makefile
->gcc_dep
) {
3553 "ifeq ($(findstring n,$(MAKEFLAGS)),)\n"
3554 "ifeq ($(filter clean%s check compile archive diag%s,$(MAKECMDGOALS)),)\n"
3555 "-include $(DEPFILES)\n"
3558 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ? " clean-all" : "",
3559 (makefile
->preprocess
? " preprocess" : ""));
3560 /* Don't include .d files when cleaning etc.; make will try to build them
3561 * and this involves running the Titan compiler. Same for preprocess.
3562 * The check target would be pointless if running the compiler
3563 * without generating code was always preceded by running the compiler
3564 * _and_ generating C++ code. */
3566 else { /* old-style dep with makedepend. Do not check compiler version. */
3567 fputs("\n\tmakedepend $(CPPFLAGS) -DMAKEDEPEND_RUN ", fp
);
3568 if (makefile
->gnu_make
) fputs("$^", fp
);
3569 else fputs("$(GENERATED_SOURCES) $(USER_SOURCES)", fp
);
3572 if (makefile
->linkingStrategy
) {
3575 "\t@perl $(TTCN3_DIR)/bin/ttcn3_archive.pl\n\n", fp
);
3580 "\tmkdir -p $(ARCHIVE_DIR)\n"
3581 "\ttar -cvhf - ", fp
);
3582 if (makefile
->central_storage
) {
3583 fprintf(fp
, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n",
3584 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) " : "");
3585 if (makefile
->preprocess
) {
3586 fprintf(fp
, "\t$(TTCN3_PP_MODULES) $(BASE_TTCN3_PP_MODULES) "
3587 "%s $(TTCN3_INCLUDES) \\\n",
3588 makefile
->linkingStrategy
? "$(BASE2_TTCN3_PP_MODULES)" : "");
3590 fprintf(fp
, "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3591 "\t$(USER_HEADERS) $(BASE_USER_HEADERS) %s\\\n"
3592 "\t$(USER_SOURCES) $(BASE_USER_SOURCES) %s",
3593 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) " : "",
3594 makefile
->linkingStrategy
? "$(BASE2_USER_HEADERS) " : "",
3595 makefile
->linkingStrategy
? "$(BASE2_USER_SOURCES)" : "");
3598 fputs("$(TTCN3_MODULES) ", fp
);
3599 if (makefile
->preprocess
) {
3600 fputs("$(TTCN3_PP_MODULES) \\\n"
3601 "\t$(TTCN3_INCLUDES) ", fp
);
3603 fputs("$(ASN1_MODULES) \\\n"
3604 "\t$(USER_HEADERS) $(USER_SOURCES)", fp
);
3606 fputs(" $(OTHER_FILES) \\\n"
3607 "\t| gzip >$(ARCHIVE_DIR)/`basename $(TARGET) .exe`-"
3608 "`date '+%y%m%d-%H%M'`.tgz\n\n", fp
);
3611 fprintf(fp
, "diag:\n"
3612 "\t$(TTCN3_DIR)/bin/compiler -v 2>&1\n"
3613 "\t$(TTCN3_DIR)/bin/mctr_cli -v 2>&1\n"
3614 "\t$(CXX) -v 2>&1\n"
3616 "\t@echo TTCN3_DIR=$(TTCN3_DIR)\n"
3617 "\t@echo OPENSSL_DIR=$(OPENSSL_DIR)\n"
3618 "\t@echo XMLDIR=$(XMLDIR)\n"
3619 "\t@echo PLATFORM=$(PLATFORM)\n\n",
3620 makefile
->dynamic
? "" : "\t$(AR) -V 2>&1\n");
3622 if (add_refd_prjs
) {
3623 fprintf(fp
, "referenced-all referenced-shared_objects referenced-executable referenced-library \\\n"
3624 "referenced-objects referenced-check \\\n"
3625 "referenced-clean%s:\n"
3626 "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
3627 "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
3629 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ? "-all" : "");
3630 fputs("referenced-dep:\n"
3631 "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
3632 "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
3634 "\ttouch $@\n\n", fp
);
3637 if (makefile
->generatorCommandOutput
) {
3638 fputs("### Project specific rules generated by user written script:\n\n", fp
);
3639 fputs(makefile
->generatorCommandOutput
, fp
);
3640 fputs("\n### End of project specific rules.\n\n", fp
);
3644 "# Add your rules here if necessary...\n"
3647 if (strcmp(makefile
->output_file
, "Makefile")) {
3648 NOTIFY("Makefile skeleton was written to `%s'.", makefile
->output_file
);
3650 NOTIFY("Makefile skeleton was generated.");
3654 ERROR("Output file `%s' already exists. Use switch `%s' to force "
3656 makefile
->output_file
,
3657 makefile
->linkingStrategy
? "-F" : "-f");
3661 #undef COMMENT_PREFIX
3662 #define COMMENT_PREFIX
3664 /** run makefilegen commans for sub-projects */
3665 static void run_makefilegen_commands(struct string2_list
* run_command_list
)
3667 struct string2_list
* act_elem
= run_command_list
;
3669 struct string2_list
* next_elem
= act_elem
->next
;
3670 /* run commands if there were no ERRORs */
3671 if ((error_count
== 0) && act_elem
->str1
&& act_elem
->str2
) {
3673 char* sub_proj_effective_work_dir
= act_elem
->str1
;
3674 char* command
= act_elem
->str2
;
3675 char* orig_dir
= get_working_dir();
3676 rv
= set_working_dir(sub_proj_effective_work_dir
);
3677 if (rv
) ERROR("Could not set working dir to `%s'", sub_proj_effective_work_dir
);
3679 fprintf(stderr
, "Executing `%s' in working directory `%s'...\n",
3680 command
, sub_proj_effective_work_dir
);
3681 rv
= system(command
);
3682 if (rv
) ERROR("Execution failed with error code %d", rv
); // TODO: it's not clear what system()'s return codes can be in different situations and platforms
3684 rv
= set_working_dir(orig_dir
);
3685 if (rv
) ERROR("Could not restore working dir to `%s'", orig_dir
);
3688 Free(act_elem
->str1
);
3689 Free(act_elem
->str2
);
3691 act_elem
= next_elem
;
3695 /** create symlinks and delete list */
3696 static void generate_symlinks(struct string2_list
* create_symlink_list
)
3698 struct string2_list
* act_elem
= create_symlink_list
;
3700 struct string2_list
* next_elem
= act_elem
->next
;
3701 /* create symlinks if there were no ERRORs */
3702 if ((error_count
== 0) && act_elem
->str1
&& act_elem
->str2
) {
3703 int fail
= symlink(act_elem
->str1
, act_elem
->str2
);
3704 if (fail
) perror(act_elem
->str2
); /* complain but do not call ERROR() */
3706 Free(act_elem
->str1
);
3707 Free(act_elem
->str2
);
3709 act_elem
= next_elem
;
3713 /** Performs all tasks of Makefile generation based on the given list of
3714 * modules/files (taken from the command line) and options that represent
3715 * command line switches. */
3716 static void generate_makefile(size_t n_arguments
, char *arguments
[],
3717 size_t n_other_files
, const char *other_files
[], const char *output_file
,
3718 const char *ets_name
, char *project_name
, boolean gnu_make
, boolean single_mode
,
3719 boolean central_storage
, boolean absolute_paths
, boolean preprocess
,
3720 boolean dump_makefile_data
, boolean force_overwrite
, boolean use_runtime_2
,
3721 boolean dynamic
, boolean makedepend
, boolean coverage
,
3722 const char *code_splitting_mode
, const char *tcov_file_name
, struct string_list
* profiled_file_list
,
3723 boolean Lflag
, boolean Zflag
, boolean Hflag
, struct string_list
* sub_project_dirs
, struct string_list
* ttcn3_prep_includes
,
3724 struct string_list
* ttcn3_prep_defines
, struct string_list
* ttcn3_prep_undefines
, struct string_list
* prep_includes
,
3725 struct string_list
* prep_defines
, struct string_list
* prep_undefines
, boolean codesplittpd
, boolean quietly
, boolean disablesubtypecheck
,
3726 const char* cxxcompiler
, const char* optlevel
, const char* optflags
, boolean disableber
, boolean disableraw
, boolean disabletext
,
3727 boolean disablexer
, boolean disablejson
, boolean forcexerinasn
, boolean defaultasomit
, boolean gccmsgformat
,
3728 boolean linenumbersonlymsg
, boolean includesourceinfo
, boolean addsourcelineinfo
, boolean suppresswarnings
,
3729 boolean outparamboundness
, boolean omit_in_value_list
, boolean warnings_for_bad_variants
, boolean disable_predef_ext_folder
, struct string_list
* solspeclibraries
,
3730 struct string_list
* sol8speclibraries
, struct string_list
* linuxspeclibraries
, struct string_list
* freebsdspeclibraries
,
3731 struct string_list
* win32speclibraries
, const char* ttcn3preprocessor
, struct string_list
* linkerlibraries
,
3732 struct string_list
* additionalObjects
, struct string_list
* linkerlibsearchpath
, char* generatorCommandOutput
,
3733 struct string2_list
* target_placement_list
)
3737 struct makefile_struct makefile
;
3738 init_makefile_struct(&makefile
);
3740 makefile
.project_name
= project_name
;
3741 makefile
.central_storage
= central_storage
;
3742 makefile
.gnu_make
= gnu_make
;
3743 makefile
.preprocess
= preprocess
;
3744 makefile
.single_mode
= single_mode
;
3745 makefile
.force_overwrite
= force_overwrite
;
3746 makefile
.use_runtime_2
= use_runtime_2
;
3747 makefile
.dynamic
= dynamic
;
3748 makefile
.gcc_dep
= gnu_make
&& !makedepend
;
3749 makefile
.coverage
= coverage
;
3750 makefile
.library
= Lflag
;
3751 makefile
.linkingStrategy
= Zflag
;
3752 makefile
.hierarchical
= Hflag
;
3753 makefile
.sub_project_dirs
= sub_project_dirs
;
3754 makefile
.ttcn3_prep_includes
= ttcn3_prep_includes
;
3755 makefile
.ttcn3_prep_defines
= ttcn3_prep_defines
;
3756 makefile
.ttcn3_prep_undefines
= ttcn3_prep_undefines
;
3757 makefile
.prep_includes
= prep_includes
;
3758 makefile
.prep_defines
= prep_defines
;
3759 makefile
.prep_undefines
= prep_undefines
;
3760 makefile
.codesplittpd
= codesplittpd
;
3761 makefile
.quietly
= quietly
;
3762 makefile
.disablesubtypecheck
= disablesubtypecheck
;
3763 makefile
.cxxcompiler
= cxxcompiler
;
3764 makefile
.optlevel
= optlevel
;
3765 makefile
.optflags
= optflags
;
3766 makefile
.disableber
= disableber
;
3767 makefile
.disableraw
= disableraw
;
3768 makefile
.disabletext
= disabletext
;
3769 makefile
.disablexer
= disablexer
;
3770 makefile
.disablejson
= disablejson
;
3771 makefile
.forcexerinasn
= forcexerinasn
;
3772 makefile
.defaultasomit
= defaultasomit
;
3773 makefile
.gccmsgformat
= gccmsgformat
;
3774 makefile
.linenumbersonlymsg
= linenumbersonlymsg
;
3775 makefile
.includesourceinfo
= includesourceinfo
;
3776 makefile
.addsourcelineinfo
= addsourcelineinfo
;
3777 makefile
.suppresswarnings
= suppresswarnings
;
3778 makefile
.outparamboundness
= outparamboundness
;
3779 makefile
.omit_in_value_list
= omit_in_value_list
;
3780 makefile
.warnings_for_bad_variants
= warnings_for_bad_variants
;
3781 makefile
.disable_predef_ext_folder
= disable_predef_ext_folder
;
3782 makefile
.solspeclibraries
= solspeclibraries
;
3783 makefile
.sol8speclibraries
= sol8speclibraries
;
3784 makefile
.linuxspeclibraries
= linuxspeclibraries
;
3785 makefile
.freebsdspeclibraries
= freebsdspeclibraries
;
3786 makefile
.win32speclibraries
= win32speclibraries
;
3787 makefile
.ttcn3preprocessor
= ttcn3preprocessor
;
3788 makefile
.linkerlibraries
= linkerlibraries
;
3789 makefile
.additionalObjects
= additionalObjects
;
3790 makefile
.linkerlibsearchpath
= linkerlibsearchpath
;
3791 makefile
.generatorCommandOutput
= generatorCommandOutput
;
3792 makefile
.target_placement_list
= target_placement_list
;
3794 for (i
= 0; i
< n_arguments
; i
++) {
3795 char *file_name
= get_file_name_for_argument(arguments
[i
]);
3796 if (file_name
!= NULL
) {
3797 FILE *fp
= fopen(file_name
, "r");
3800 if (is_ttcn3_module(file_name
, fp
, &module_name
)) {
3801 if (is_asn1_module(file_name
, fp
, NULL
)) {
3802 ERROR("File `%s' looks so strange that it can be both ASN.1 and "
3803 "TTCN-3 module. Add it to the Makefile manually.", file_name
);
3806 add_ttcn3_module(&makefile
, file_name
, module_name
);
3808 } else if (is_asn1_module(file_name
, fp
, &module_name
)) {
3809 if (is_valid_asn1_filename(file_name
)) {
3810 add_asn1_module(&makefile
, file_name
, module_name
);
3812 ERROR("The file name (without suffix) shall be identical to the module name.\n"
3813 "If the name of the ASN.1 module contains a hyphen, the corresponding "
3814 "file name shall contain an underscore character instead.");
3817 add_user_file(&makefile
, file_name
);
3821 ERROR("Cannot open file `%s' for reading: %s", file_name
,
3826 } else if (get_path_status(arguments
[i
]) == PS_DIRECTORY
) {
3827 ERROR("Argument `%s' is a directory.", arguments
[i
]);
3829 ERROR("Cannot find any source file for argument `%s'.", arguments
[i
]);
3832 for (i
= 0; i
< n_other_files
; i
++) {
3833 char *file_name
= get_file_name_for_argument(other_files
[i
]);
3834 if (file_name
!= NULL
) {
3835 add_path_to_list(&makefile
.nOtherFiles
, &makefile
.OtherFiles
, file_name
,
3836 makefile
.working_dir
, TRUE
);
3838 } else if (get_path_status(other_files
[i
]) == PS_DIRECTORY
) {
3839 ERROR("Argument `%s' given as other file is a directory.",
3842 ERROR("Cannot find any other file for argument `%s'.", other_files
[i
]);
3846 if (ets_name
!= NULL
) {
3847 char *dir_name
= get_dir_name(ets_name
, makefile
.working_dir
);
3848 char *file_name
= get_file_from_path(ets_name
);
3849 makefile
.ets_name
= compose_path_name(dir_name
, file_name
);
3854 if (code_splitting_mode
!= NULL
) {
3855 makefile
.code_splitting_mode
= mputprintf(makefile
.code_splitting_mode
, "-U %s", code_splitting_mode
);
3858 if (tcov_file_name
!= NULL
) {
3859 makefile
.tcov_file_name
= mprintf(" -K %s", tcov_file_name
);
3862 if (profiled_file_list
!= NULL
) {
3863 makefile
.profiled_file_list
= profiled_file_list
;
3866 if (makefile
.nTTCN3Modules
>= 1) {
3867 if (makefile
.ets_name
== NULL
)
3868 makefile
.ets_name
= mcopystr(makefile
.TTCN3Modules
[0].module_name
);
3869 } else if (preprocess
&& (makefile
.nTTCN3PPModules
>= 1)) {
3870 if (makefile
.ets_name
== NULL
)
3871 makefile
.ets_name
= mcopystr(makefile
.TTCN3PPModules
[0].module_name
);
3872 } else if (makefile
.nASN1Modules
>= 1) {
3873 WARNING("No TTCN-3 module was given for the Makefile.");
3874 if (makefile
.ets_name
== NULL
)
3875 makefile
.ets_name
= mcopystr(makefile
.ASN1Modules
[0].module_name
);
3876 } else if (makefile
.nUserFiles
> 0) {
3877 WARNING("No TTCN-3 or ASN.1 module was given for the Makefile.");
3878 if (makefile
.ets_name
== NULL
)
3879 makefile
.ets_name
= mcopystr(makefile
.UserFiles
[0].file_prefix
);
3881 WARNING("No source files were given for the Makefile");
3884 if (output_file
!= NULL
) {
3885 if (get_path_status(output_file
) == PS_DIRECTORY
)
3886 makefile
.output_file
= mprintf("%s/Makefile", output_file
);
3887 else makefile
.output_file
= mcopystr(output_file
);
3888 } else makefile
.output_file
= mcopystr("Makefile");
3889 add_path_to_list(&makefile
.nOtherFiles
, &makefile
.OtherFiles
,
3890 makefile
.output_file
, makefile
.working_dir
, FALSE
);
3892 if (preprocess
) check_preprocessed_filename_collision(&makefile
);
3893 filter_out_generated_files(&makefile
);
3894 complete_user_files(&makefile
);
3895 if (!absolute_paths
) convert_dirs_to_relative(&makefile
);
3896 check_special_chars(&makefile
);
3897 if (central_storage
) collect_base_dirs(&makefile
);
3898 check_naming_convention(&makefile
);
3900 if (dump_makefile_data
) dump_makefile_struct(&makefile
, 0);
3902 if (error_count
== 0) print_makefile(&makefile
);
3903 free_makefile_struct(&makefile
);
3906 #ifdef COVERAGE_BUILD
3913 static void usage(void)
3915 fprintf(stderr
, "\n"
3916 "usage: %s [-abc" C_flag
"dDEfFglLmMprRstTVwWXZ] [-K file] [-z file ] [-P dir]"
3917 " [-U none|type] [-e ets_name] [-o dir|file]\n"
3918 " [-t project_descriptor.tpd [-b buildconfig]]\n"
3919 " [-O file] ... module_name ... testport_name ...\n"
3923 " -a: use absolute pathnames in the generated Makefile\n"
3924 " -c: use the pre-compiled files from central directories\n"
3925 #ifdef COVERAGE_BUILD
3926 " -C: enable coverage of generated C++ code\n"
3928 " -d: dump the data used for Makefile generation\n"
3929 " -e ets_name: name of the target executable\n"
3930 " -E: display only warnings for unrecognized encoding variants\n"
3931 " -f: force overwriting of the output Makefile\n"
3932 " -g: generate Makefile for use with GNU make\n"
3933 " -I path: Add path to the search paths when using TPD files\n"
3934 " -K file: enable selective code coverage\n"
3935 " -l: use dynamic linking\n"
3936 " -L: create makefile with library archive as the default target\n"
3937 " -m: always use makedepend for dependencies\n"
3938 " -M: allow 'omit' in template value lists (legacy behavior)\n"
3939 " -o dir|file: write the Makefile to the given directory or file\n"
3940 " -O file: add the given file to the Makefile as other file\n"
3941 " -p: generate Makefile with TTCN-3 preprocessing\n"
3942 " -R: use function test runtime (TITAN_RUNTIME_2)\n"
3943 " -s: generate Makefile for single mode\n"
3944 " -U none|type: split generated code\n"
3945 " -v: show version\n"
3946 " -w: suppress warnings\n"
3947 " -Y: Enforces legacy behaviour of the \"out\" function parameters (see refguide)\n"
3948 " -z file: enable profiling and code coverage for the TTCN-3 files in the argument\n"
3949 "Options for processing the Titan Project Descriptor file(s):\n"
3950 " -t tpd: read project descriptor file\n"
3951 " -b buildconfig: use the specified build config instead of the default\n"
3952 " -D: use current directory as working directory\n"
3953 " -V: disable validation of TPD file with schema\n"
3954 " -r: generate Makefile hierarchy for TPD hierarchy (recursive)\n"
3955 " -F: force overwriting of all generated Makefiles, use with -r\n"
3956 " -T: generate only top-level Makefile of the hierarchy, use with -r\n"
3957 " -P dir: prints out a file list found in a given TPD relative to the given directory\n"
3958 " -X: generate XML file that describes the TPD hierarchy, use with -r\n"
3959 " -W: prefix working directories with project name\n"
3960 " -Z: recursive Makefile generation from TPD using object files and dynamic libraries too\n"
3961 " -H: hierachical Makefile generation from TPD use with -Z\n"
3962 , program_name
, program_name
);
3965 #define SET_FLAG(x) if (x##flag) {\
3966 ERROR("Flag -" #x " was specified more than once.");\
3968 } else x##flag = TRUE
3970 void free_string_list(struct string_list
* act_elem
)
3973 struct string_list
* next_elem
= act_elem
->next
;
3974 Free(act_elem
->str
);
3976 act_elem
= next_elem
;
3980 void free_string2_list(struct string2_list
* act_elem
)
3983 struct string2_list
* next_elem
= act_elem
->next
;
3984 Free(act_elem
->str1
);
3985 Free(act_elem
->str2
);
3987 act_elem
= next_elem
;
3991 int main(int argc
, char *argv
[])
3994 aflag
= FALSE
, bflag
= FALSE
, cflag
= FALSE
, Cflag
= FALSE
,
3995 dflag
= FALSE
, eflag
= FALSE
, fflag
= FALSE
, gflag
= FALSE
,
3996 oflag
= FALSE
, Kflag
= FALSE
, lflag
= FALSE
, pflag
= FALSE
,
3997 Pflag
= FALSE
, Rflag
= FALSE
, sflag
= FALSE
, tflag
= FALSE
,
3998 wflag
= FALSE
, vflag
= FALSE
, mflag
= FALSE
, Uflag
= FALSE
,
3999 Lflag
= FALSE
, rflag
= FALSE
, Fflag
= FALSE
, Xflag
= FALSE
,
4000 Tflag
= FALSE
, Yflag
= FALSE
, csflag
= FALSE
, quflag
= FALSE
,
4001 dsflag
= FALSE
, dbflag
= FALSE
, drflag
= FALSE
, dtflag
= FALSE
,
4002 dxflag
= FALSE
, fxflag
= FALSE
, doflag
= FALSE
,
4003 gfflag
= FALSE
, lnflag
= FALSE
, isflag
= FALSE
, asflag
= FALSE
,
4004 swflag
= FALSE
, Vflag
= FALSE
, Dflag
= FALSE
, Wflag
= FALSE
,
4005 djflag
= FALSE
, Zflag
= FALSE
, Hflag
= FALSE
, Mflag
= FALSE
,
4006 diflag
= FALSE
, zflag
= FALSE
, Eflag
= FALSE
;
4007 boolean error_flag
= FALSE
;
4008 char *output_file
= NULL
;
4009 char *ets_name
= NULL
;
4010 char *project_name
= NULL
;
4011 size_t n_other_files
= 0;
4012 const char **other_files
= NULL
;
4013 const char *code_splitting_mode
= NULL
;
4014 const char *tpd_file_name
= NULL
;
4015 const char *tpd_build_config
= NULL
;
4016 const char *tcov_file_name
= NULL
;
4017 size_t n_search_paths
= 0;
4018 const char **search_paths
= NULL
;
4019 struct string_list
* profiled_file_list
= NULL
;
4020 const char *profiled_file_list_zflag
= NULL
;
4021 const char *file_list_path
= NULL
;
4022 enum tpd_result tpd_processed
= FALSE
;
4023 struct string_list
* sub_project_dirs
= NULL
;
4024 struct string2_list
* create_symlink_list
= NULL
;
4025 struct string_list
* ttcn3_prep_includes
= NULL
;
4026 struct string_list
* ttcn3_prep_defines
= NULL
;
4027 struct string_list
* ttcn3_prep_undefines
= NULL
;
4028 struct string_list
* prep_includes
= NULL
;
4029 struct string_list
* prep_defines
= NULL
;
4030 struct string_list
* prep_undefines
= NULL
;
4031 char *cxxcompiler
= NULL
;
4032 char *optlevel
= NULL
;
4033 char *optflags
= NULL
;
4034 struct string_list
* solspeclibraries
= NULL
;
4035 struct string_list
* sol8speclibraries
= NULL
;
4036 struct string_list
* linuxspeclibraries
= NULL
;
4037 struct string_list
* freebsdspeclibraries
= NULL
;
4038 struct string_list
* win32speclibraries
= NULL
;
4039 char *ttcn3prep
= NULL
;
4040 struct string_list
* linkerlibraries
= NULL
;
4041 struct string_list
* additionalObjects
= NULL
;
4042 struct string_list
* linkerlibsearchpath
= NULL
;
4043 char* generatorCommandOutput
= NULL
;
4044 struct string2_list
* target_placement_list
= NULL
;
4045 struct string2_list
* run_command_list
= NULL
;
4046 struct string2_list
* required_configs
= NULL
;
4049 license_struct lstr
;
4053 program_name
= argv
[0];
4056 fputs("Makefile Generator for the TTCN-3 Test Executor, version "
4057 PRODUCT_NUMBER
"\n", stderr
);
4059 return EXIT_FAILURE
;
4063 int c
= getopt(argc
, argv
, "O:ab:c" C_flag
"dDe:EfFgI:K:o:lLmMpP:rRst:TU:vVwWXYz:ZH");
4068 other_files
= (const char**)
4069 Realloc(other_files
, n_other_files
* sizeof(*other_files
));
4070 other_files
[n_other_files
- 1] = optarg
;
4074 search_paths
= (const char**)
4075 Realloc(search_paths
, n_search_paths
* sizeof(*search_paths
));
4076 search_paths
[n_search_paths
- 1] = optarg
;
4083 tpd_build_config
= optarg
;
4090 tcov_file_name
= optarg
;
4092 #ifdef COVERAGE_BUILD
4124 output_file
= optarg
;
4143 /* Optional arguments with `::' are GNU specific... */
4144 if (get_path_status(optarg
) == PS_DIRECTORY
) {
4145 file_list_path
= optarg
;
4147 ERROR("The -P flag requires a valid directory as its argument "
4148 "instead of `%s'", optarg
);
4163 tpd_file_name
= optarg
;
4173 code_splitting_mode
= optarg
;
4174 if (strcmp(optarg
, "none") != 0 &&
4175 strcmp(optarg
, "type") != 0)
4176 ERROR("Unrecognizable argument: '%s'. Valid options for -U switch are: "
4177 "'none', 'type'", optarg
);
4187 suppress_warnings
= TRUE
;
4197 profiled_file_list_zflag
= optarg
;
4208 /* Checking incompatible options */
4210 /* -v prints the version and exits, it's pointless to specify other flags */
4211 if ( aflag
|| bflag
|| cflag
|| Cflag
|| dflag
|| eflag
|| fflag
|| Fflag
|| gflag
4212 || mflag
|| oflag
|| lflag
|| pflag
|| Pflag
|| rflag
|| Rflag
|| sflag
4213 || tflag
|| Tflag
|| Vflag
|| wflag
|| Xflag
|| Kflag
|| Dflag
|| Wflag
|| Yflag
4214 || Zflag
|| Hflag
|| Mflag
|| zflag
|| Eflag
|| n_other_files
> 0 || n_search_paths
> 0)
4219 if (!gflag
) gflag
= TRUE
; // GNU make
4220 if (!cflag
) cflag
= TRUE
; // central sorage
4223 if ((bflag
|| Dflag
|| Pflag
|| Vflag
|| rflag
|| Wflag
|| Zflag
) && !tflag
) {
4224 ERROR("Using the '-b', '-D', '-P', '-V', '-r' 'Z' or '-W' option requires the use of the -t' option.");
4228 if (rflag
&& !cflag
) {
4229 ERROR("Using the '-r' option requires use of the '-c' option. Recursive makefile hierarchy uses the central directory feature.");
4233 if (Fflag
&& !rflag
) {
4234 ERROR("Using the '-F' option requires use of the '-r' option.");
4238 if (Xflag
&& !rflag
) {
4239 ERROR("Using the '-X' option requires use of the '-r' option.");
4243 if (Tflag
&& !rflag
) {
4244 ERROR("Using the '-T' option requires use of the '-r' option.");
4248 if (!Zflag
&& Hflag
) {
4249 ERROR("Using the '-H' option requires use of the '-Z' option.");
4253 if (Zflag
&& !Fflag
&& !fflag
) {
4254 ERROR("Using the '-Z' option requires use of the '-F' option.");
4258 if (lflag
&& !strncmp(get_platform_string(), "WIN32", 5)) {
4259 ERROR("Generating Makefile with dynamic linking enabled is not supported "
4260 "on Windows platform");
4264 if (n_search_paths
> 0 && !tflag
) {
4265 ERROR("Using the '-I' option requires use of the '-t' option.");
4269 for (size_t i
= 0; i
< n_search_paths
; i
++) {
4270 boolean is_abs_path
=
4271 #if defined WIN32 && defined MINGW
4272 /* On native Windows the absolute path name shall begin with
4273 * a drive letter, colon and backslash */
4274 (((search_paths
[i
][0] < 'A' || search_paths
[i
][0] > 'Z') &&
4275 (search_paths
[i
][0] < 'a' || search_paths
[i
][0] > 'z')) ||
4276 search_paths
[i
][1] != ':' || search_paths
[i
][2] != '\\');
4278 /* On UNIX-like systems the absolute path name shall begin with
4280 search_paths
[i
][0] != '/';
4283 ERROR("The path after the -I flag must be an absolute path.");
4290 return EXIT_FAILURE
;
4294 fputs("Makefile Generator for the TTCN-3 Test Executor\n"
4295 "Product number: " PRODUCT_NUMBER
"\n"
4296 "Build date: " __DATE__
" " __TIME__
"\n"
4297 "Compiled with: " C_COMPILER_VERSION
"\n\n"
4298 COPYRIGHT_STRING
"\n\n", stderr
);
4300 print_license_info();
4302 return EXIT_SUCCESS
;
4307 load_license(&lstr
);
4308 valid_license
= verify_license(&lstr
);
4310 if (!valid_license
) {
4311 free_license(&lstr
);
4314 if (!check_feature(&lstr
, FEATURE_TPGEN
)) {
4315 ERROR("The license key does not allow the generation of "
4316 "Makefile skeletons.");
4317 return EXIT_FAILURE
;
4319 free_license(&lstr
);
4323 char* abs_work_dir
= NULL
;
4324 FILE* prj_graph_fp
= NULL
;
4325 sub_project_dirs
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4326 sub_project_dirs
->str
= NULL
;
4327 sub_project_dirs
->next
= NULL
;
4328 ttcn3_prep_includes
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4329 ttcn3_prep_includes
->str
= NULL
;
4330 ttcn3_prep_includes
->next
= NULL
;
4331 ttcn3_prep_defines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4332 ttcn3_prep_defines
->str
= NULL
;
4333 ttcn3_prep_defines
->next
= NULL
;
4334 ttcn3_prep_undefines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4335 ttcn3_prep_undefines
->str
= NULL
;
4336 ttcn3_prep_undefines
->next
= NULL
;
4337 prep_includes
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4338 prep_includes
->str
= NULL
;
4339 prep_includes
->next
= NULL
;
4340 prep_defines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4341 prep_defines
->str
= NULL
;
4342 prep_defines
->next
= NULL
;
4343 prep_undefines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4344 prep_undefines
->str
= NULL
;
4345 prep_undefines
->next
= NULL
;
4346 solspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4347 solspeclibraries
->str
= NULL
;
4348 solspeclibraries
->next
= NULL
;
4349 sol8speclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4350 sol8speclibraries
->str
= NULL
;
4351 sol8speclibraries
->next
= NULL
;
4352 linuxspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4353 linuxspeclibraries
->str
= NULL
;
4354 linuxspeclibraries
->next
= NULL
;
4355 freebsdspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4356 freebsdspeclibraries
->str
= NULL
;
4357 freebsdspeclibraries
->next
= NULL
;
4358 win32speclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4359 win32speclibraries
->str
= NULL
;
4360 win32speclibraries
->next
= NULL
;
4361 linkerlibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4362 linkerlibraries
->str
= NULL
;
4363 linkerlibraries
->next
= NULL
;
4364 additionalObjects
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4365 additionalObjects
->str
= NULL
;
4366 additionalObjects
->next
= NULL
;
4367 linkerlibsearchpath
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4368 linkerlibsearchpath
->str
= NULL
;
4369 linkerlibsearchpath
->next
= NULL
;
4372 const char* prj_graph_filename
= "project_hierarchy_graph.xml";
4373 prj_graph_fp
= fopen(prj_graph_filename
, "w");
4374 if (prj_graph_fp
==NULL
) WARNING("Cannot open output file `%s' for writing: %s", prj_graph_filename
, strerror(errno
));
4375 if (prj_graph_fp
) fprintf(prj_graph_fp
, "<project_hierarchy_graph top_level_tpd=\"%s\">\n", tpd_file_name
);
4377 create_symlink_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4378 create_symlink_list
->str1
= NULL
;
4379 create_symlink_list
->str2
= NULL
;
4380 create_symlink_list
->next
= NULL
;
4381 target_placement_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4382 target_placement_list
->str1
= NULL
;
4383 target_placement_list
->str2
= NULL
;
4384 target_placement_list
->next
= NULL
;
4385 run_command_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4386 run_command_list
->str1
= NULL
;
4387 run_command_list
->str2
= NULL
;
4388 run_command_list
->next
= NULL
;
4389 required_configs
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4390 required_configs
->str1
= NULL
;
4391 required_configs
->str2
= NULL
;
4392 required_configs
->next
= NULL
;
4394 tpd_processed
= process_tpd(tpd_file_name
, tpd_build_config
, file_list_path
,
4395 &argc
, &argv
, &optind
, &ets_name
, &project_name
,
4396 &gflag
, &sflag
, &cflag
, &aflag
, &pflag
,
4397 &Rflag
, &lflag
, &mflag
, &Pflag
, &Lflag
, rflag
, Fflag
, Tflag
, output_file
, &abs_work_dir
, sub_project_dirs
, program_name
, prj_graph_fp
,
4398 create_symlink_list
,ttcn3_prep_includes
, ttcn3_prep_defines
,ttcn3_prep_undefines
, prep_includes
, prep_defines
, prep_undefines
, &csflag
,
4399 &quflag
, &dsflag
, &cxxcompiler
, &optlevel
, &optflags
, &dbflag
, &drflag
, &dtflag
, &dxflag
, &djflag
, &fxflag
, &doflag
, &gfflag
, &lnflag
, &isflag
,
4400 &asflag
, &swflag
, &Yflag
, &Mflag
, &Eflag
, &diflag
, solspeclibraries
, sol8speclibraries
, linuxspeclibraries
, freebsdspeclibraries
, win32speclibraries
, &ttcn3prep
,
4401 linkerlibraries
, additionalObjects
, linkerlibsearchpath
, Vflag
, Dflag
, &Zflag
, &Hflag
,
4402 &generatorCommandOutput
, target_placement_list
, Wflag
, run_command_list
, required_configs
, &profiled_file_list
, search_paths
, n_search_paths
);
4406 fprintf(prj_graph_fp
, "</project_hierarchy_graph>\n");
4407 fclose(prj_graph_fp
);
4409 if (tpd_processed
== TPD_FAILED
) {
4410 ERROR("Failed to process %s", tpd_file_name
);
4414 WARNING("Compiler option '-z' and its argument will be overwritten by "
4415 "the settings in the TPD");
4419 // use the argument given in the command line if there is no TPD
4420 profiled_file_list
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4421 profiled_file_list
->str
= mcopystr(profiled_file_list_zflag
);
4422 profiled_file_list
->next
= NULL
;
4426 run_makefilegen_commands(run_command_list
);
4427 generate_symlinks(create_symlink_list
);
4430 NOTIFY("Makefile generation from top-level TPD: %s", tpd_file_name
);
4431 if (!Fflag
&& fflag
)
4432 NOTIFY("Makefile generation from lower level TPD: %s", tpd_file_name
);
4434 generate_makefile(argc
- optind
, argv
+ optind
, n_other_files
, other_files
,
4435 output_file
, ets_name
, project_name
, gflag
, sflag
, cflag
, aflag
, pflag
, dflag
, fflag
||Fflag
,
4436 Rflag
, lflag
, mflag
, Cflag
, code_splitting_mode
, tcov_file_name
, profiled_file_list
,
4437 Lflag
, Zflag
, Hflag
, rflag
? sub_project_dirs
: NULL
, ttcn3_prep_includes
,
4438 ttcn3_prep_defines
, ttcn3_prep_undefines
, prep_includes
, prep_defines
, prep_undefines
, csflag
, quflag
, dsflag
, cxxcompiler
, optlevel
, optflags
, dbflag
,
4439 drflag
, dtflag
, dxflag
, djflag
, fxflag
, doflag
, gfflag
, lnflag
, isflag
, asflag
, swflag
, Yflag
, Mflag
, Eflag
, diflag
, solspeclibraries
,
4440 sol8speclibraries
, linuxspeclibraries
, freebsdspeclibraries
, win32speclibraries
, ttcn3prep
, linkerlibraries
, additionalObjects
,
4441 linkerlibsearchpath
, generatorCommandOutput
, target_placement_list
);
4444 free_string_list(sub_project_dirs
);
4445 free_string_list(ttcn3_prep_includes
);
4446 free_string_list(ttcn3_prep_defines
);
4447 free_string_list(ttcn3_prep_undefines
);
4448 free_string_list(prep_includes
);
4449 free_string_list(prep_defines
);
4450 free_string_list(prep_undefines
);
4451 free_string_list(solspeclibraries
);
4452 free_string_list(sol8speclibraries
);
4453 free_string_list(linuxspeclibraries
);
4454 free_string_list(freebsdspeclibraries
);
4455 free_string_list(win32speclibraries
);
4456 free_string_list(linkerlibraries
);
4457 free_string_list(additionalObjects
);
4458 free_string_list(linkerlibsearchpath
);
4459 free_string_list(profiled_file_list
);
4463 Free(generatorCommandOutput
);
4464 free_string2_list(target_placement_list
);
4465 free_string2_list(required_configs
);
4468 if (tpd_processed
== TPD_SUCCESS
) {
4470 if (!(eflag
&& ets_name
))
4480 /* Free(output_file); */
4481 for (E
= 0; E
< argc
; ++E
) Free(argv
[E
]);
4484 /* check_mem_leak(program_name); not needed when linked to new.cc */
4485 return error_count
> 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;