1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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
;
211 boolean linkingStrategy
;
212 boolean hierarchical
;
213 struct string_list
* sub_project_dirs
; /* not owned */
214 struct string_list
* ttcn3_prep_includes
; /* not owned */
215 struct string_list
* ttcn3_prep_defines
; /* not owned */
216 struct string_list
* ttcn3_prep_undefines
; /* not owned */
217 struct string_list
* prep_includes
; /* not owned */
218 struct string_list
* prep_defines
; /* not owned */
219 struct string_list
* prep_undefines
; /* not owned */
220 boolean codesplittpd
;
222 boolean disablesubtypecheck
;
223 const char *cxxcompiler
;
224 const char *optlevel
;
225 const char *optflags
;
231 boolean forcexerinasn
;
232 boolean defaultasomit
;
233 boolean gccmsgformat
;
234 boolean linenumbersonlymsg
;
235 boolean includesourceinfo
;
236 boolean addsourcelineinfo
;
237 boolean suppresswarnings
;
238 boolean outparamboundness
;
239 struct string_list
* solspeclibraries
; /* not owned */
240 struct string_list
* sol8speclibraries
; /* not owned */
241 struct string_list
* linuxspeclibraries
; /* not owned */
242 struct string_list
* freebsdspeclibraries
; /* not owned */
243 struct string_list
* win32speclibraries
; /* not owned */
244 const char *ttcn3preprocessor
;
245 struct string_list
* linkerlibraries
; /* not owned */
246 struct string_list
* additionalObjects
; /* not owned */
247 struct string_list
* linkerlibsearchpath
; /* not owned */
248 char* generatorCommandOutput
; /* not owned */
249 struct string2_list
* target_placement_list
; /* not owned */
252 /** Initializes structure \a makefile with empty lists and default settings. */
253 static void init_makefile_struct(struct makefile_struct
*makefile
)
255 makefile
->project_name
= NULL
;
256 makefile
->nTTCN3Modules
= 0;
257 makefile
->TTCN3Modules
= NULL
;
258 makefile
->preprocess
= FALSE
;
259 makefile
->nTTCN3PPModules
= 0;
260 makefile
->TTCN3PPModules
= NULL
;
261 makefile
->TTCN3ModulesRegular
= TRUE
;
262 makefile
->BaseTTCN3ModulesRegular
= TRUE
;
263 makefile
->nTTCN3IncludeFiles
= 0;
264 makefile
->TTCN3IncludeFiles
= NULL
;
265 makefile
->nASN1Modules
= 0;
266 makefile
->ASN1Modules
= NULL
;
267 makefile
->ASN1ModulesRegular
= TRUE
;
268 makefile
->BaseASN1ModulesRegular
= TRUE
;
269 makefile
->nUserFiles
= 0;
270 makefile
->UserFiles
= NULL
;
271 makefile
->UserHeadersRegular
= TRUE
;
272 makefile
->UserSourcesRegular
= TRUE
;
273 makefile
->BaseUserHeadersRegular
= TRUE
;
274 makefile
->BaseUserSourcesRegular
= TRUE
;
275 makefile
->nOtherFiles
= 0;
276 makefile
->OtherFiles
= NULL
;
277 makefile
->central_storage
= FALSE
;
278 makefile
->nBaseDirs
= 0;
279 makefile
->BaseDirs
= NULL
;
280 makefile
->working_dir
= get_working_dir();
281 makefile
->gnu_make
= FALSE
;
282 makefile
->single_mode
= FALSE
;
283 makefile
->ets_name
= NULL
;
284 makefile
->output_file
= NULL
;
285 makefile
->force_overwrite
= FALSE
;
286 makefile
->use_runtime_2
= FALSE
;
287 makefile
->dynamic
= FALSE
;
288 makefile
->gcc_dep
= FALSE
;
289 makefile
->code_splitting_mode
= NULL
;
290 makefile
->coverage
= FALSE
;
291 makefile
->tcov_file_name
= NULL
;
292 makefile
->library
= FALSE
;
293 makefile
->linkingStrategy
= FALSE
;
294 makefile
->hierarchical
= FALSE
;
295 makefile
->sub_project_dirs
= NULL
;
296 makefile
->ttcn3_prep_includes
= NULL
;
297 makefile
->prep_includes
= NULL
;
298 makefile
->prep_defines
= NULL
;
299 makefile
->outparamboundness
= FALSE
;
300 makefile
->solspeclibraries
= NULL
;
301 makefile
->sol8speclibraries
= NULL
;
302 makefile
->linuxspeclibraries
= NULL
;
303 makefile
->freebsdspeclibraries
= NULL
;
304 makefile
->win32speclibraries
= NULL
;
305 makefile
->linkerlibraries
= NULL
;
306 makefile
->additionalObjects
= NULL
;
307 makefile
->linkerlibsearchpath
= NULL
;
308 makefile
->generatorCommandOutput
= NULL
;
309 makefile
->target_placement_list
= NULL
;
312 /** Deallocates all memory associated with structure \a makefile. */
313 static void free_makefile_struct(const struct makefile_struct
*makefile
)
315 Free(makefile
->project_name
);
317 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
318 Free(makefile
->TTCN3Modules
[i
].dir_name
);
319 Free(makefile
->TTCN3Modules
[i
].file_name
);
320 Free(makefile
->TTCN3Modules
[i
].module_name
);
322 Free(makefile
->TTCN3Modules
);
323 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
324 Free(makefile
->TTCN3PPModules
[i
].dir_name
);
325 Free(makefile
->TTCN3PPModules
[i
].file_name
);
326 Free(makefile
->TTCN3PPModules
[i
].module_name
);
328 Free(makefile
->TTCN3PPModules
);
329 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
330 Free(makefile
->TTCN3IncludeFiles
[i
]);
331 Free(makefile
->TTCN3IncludeFiles
);
332 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
333 Free(makefile
->ASN1Modules
[i
].dir_name
);
334 Free(makefile
->ASN1Modules
[i
].file_name
);
335 Free(makefile
->ASN1Modules
[i
].module_name
);
337 Free(makefile
->ASN1Modules
);
338 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
339 Free(makefile
->UserFiles
[i
].dir_name
);
340 Free(makefile
->UserFiles
[i
].file_prefix
);
341 Free(makefile
->UserFiles
[i
].header_name
);
342 Free(makefile
->UserFiles
[i
].source_name
);
344 Free(makefile
->UserFiles
);
345 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) Free(makefile
->OtherFiles
[i
]);
346 Free(makefile
->OtherFiles
);
347 Free(makefile
->BaseDirs
);
348 Free(makefile
->working_dir
);
349 Free(makefile
->ets_name
);
350 Free(makefile
->output_file
);
351 Free(makefile
->code_splitting_mode
);
352 Free(makefile
->tcov_file_name
);
355 /** Displays the contents of structure \a makefile as debug messages. */
356 static void dump_makefile_struct(const struct makefile_struct
*makefile
,
360 DEBUG(level
, "Data used for Makefile generation:");
361 DEBUG(level
+ 1, "TTCN-3 project name: %s", makefile
->project_name
);
362 DEBUG(level
+ 1, "TTCN-3 modules: (%u pcs.)", makefile
->nTTCN3Modules
);
363 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
364 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
365 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
366 if (module
->dir_name
!= NULL
)
367 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
368 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
369 DEBUG(level
+ 3, "Follows the naming convention: %s",
370 module
->is_regular
? "yes" : "no");
372 DEBUG(level
+ 1, "TTCN-3 preprocessing: %s",
373 makefile
->preprocess
? "yes" : "no");
374 if (makefile
->preprocess
) {
375 DEBUG(level
+ 1, "TTCN-3 modules to be preprocessed: (%u pcs.)",
376 makefile
->nTTCN3PPModules
);
377 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
378 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
379 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
380 if (module
->dir_name
!= NULL
)
381 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
382 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
383 DEBUG(level
+ 3, "Follows the naming convention: %s",
384 module
->is_regular
? "yes" : "no");
386 DEBUG(level
+ 1, "TTCN-3 include files: (%u pcs.)",
387 makefile
->nTTCN3IncludeFiles
);
388 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
389 DEBUG(level
+ 2, "File name: %s", makefile
->TTCN3IncludeFiles
[i
]);
391 DEBUG(level
+ 1, "All local TTCN-3 modules follow the naming convention: %s",
392 makefile
->TTCN3ModulesRegular
? "yes" : "no");
393 if (makefile
->central_storage
) DEBUG(level
+ 1, "All TTCN-3 modules from other "
394 "directories follow the naming convention: %s",
395 makefile
->BaseTTCN3ModulesRegular
? "yes" : "no");
396 DEBUG(level
+ 1, "ASN.1 modules: (%u pcs.)", makefile
->nASN1Modules
);
397 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
398 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
399 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
400 if (module
->dir_name
!= NULL
)
401 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
402 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
403 DEBUG(level
+ 3, "Follows the naming convention: %s",
404 module
->is_regular
? "yes" : "no");
406 DEBUG(level
+ 1, "All local ASN.1 modules follow the naming convention: %s",
407 makefile
->ASN1ModulesRegular
? "yes" : "no");
408 if (makefile
->central_storage
) DEBUG(level
+ 1, "All ASN.1 modules from other "
409 "directories follow the naming convention: %s",
410 makefile
->BaseASN1ModulesRegular
? "yes" : "no");
411 DEBUG(level
+ 1, "User C/C++ modules: (%u pcs.)", makefile
->nUserFiles
);
412 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
413 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
414 DEBUG(level
+ 2, "File prefix: %s", user
->file_prefix
);
415 if (user
->dir_name
!= NULL
)
416 DEBUG(level
+ 3, "Directory: %s", user
->dir_name
);
417 if (user
->header_name
!= NULL
) {
418 DEBUG(level
+ 3, "Header file: %s", user
->header_name
);
419 DEBUG(level
+ 3, "Header file has .hh or .hpp suffix: %s",
420 user
->has_hh_suffix
? "yes" : "no");
422 if (user
->source_name
!= NULL
) {
423 DEBUG(level
+ 3, "Source file: %s", user
->source_name
);
424 DEBUG(level
+ 3, "Source file has .cc or .cpp suffix: %s",
425 user
->has_cc_suffix
? "yes" : "no");
426 DEBUG(level
+ 3, "Object file: %s.o", user
->file_prefix
);
429 DEBUG(level
+ 1, "All local C/C++ header files follow the naming "
430 "convention: %s", makefile
->UserHeadersRegular
? "yes" : "no");
431 DEBUG(level
+ 1, "All local C/C++ source files follow the naming "
432 "convention: %s", makefile
->UserSourcesRegular
? "yes" : "no");
433 if (makefile
->central_storage
) {
434 DEBUG(level
+ 1, "All C/C++ header files from other directories follow the "
435 "naming convention: %s", makefile
->BaseUserHeadersRegular
? "yes" : "no");
436 DEBUG(level
+ 1, "All C/C++ source files from other directories follow the "
437 "naming convention: %s", makefile
->BaseUserSourcesRegular
? "yes" : "no");
439 DEBUG(level
+ 1, "Other files: (%u pcs.)", makefile
->nOtherFiles
);
440 for (i
= 0; i
< makefile
->nOtherFiles
; i
++)
441 DEBUG(level
+ 2, "File name: %s", makefile
->OtherFiles
[i
]);
442 DEBUG(level
+ 1, "Use pre-compiled files from central storage: %s",
443 makefile
->central_storage
? "yes" : "no");
444 if (makefile
->central_storage
) {
445 DEBUG(level
+ 1, "Directories of pre-compiled files: (%u pcs.)",
446 makefile
->nBaseDirs
);
447 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
448 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
449 DEBUG(level
+ 2, "Directory: %s", base_dir
->dir_name
);
450 DEBUG(level
+ 3, "Has TTCN-3/ASN.1 modules: %s",
451 base_dir
->has_modules
? "yes" : "no");
454 DEBUG(level
+ 1, "Working directory: %s",
455 makefile
->working_dir
!= NULL
? makefile
->working_dir
: "<unknown>");
456 DEBUG(level
+ 1, "GNU make: %s", makefile
->gnu_make
? "yes" : "no");
457 DEBUG(level
+ 1, "Execution mode: %s",
458 makefile
->single_mode
? "single" : "parallel");
459 DEBUG(level
+ 1, "Name of executable: %s",
460 makefile
->ets_name
!= NULL
? makefile
->ets_name
: "<unknown>");
461 DEBUG(level
+ 1, "Output file: %s",
462 makefile
->output_file
!= NULL
? makefile
->output_file
: "<unknown>");
463 DEBUG(level
+ 1, "Force overwrite: %s",
464 makefile
->force_overwrite
? "yes" : "no");
465 DEBUG(level
+ 1, "Use function test runtime: %s",
466 makefile
->use_runtime_2
? "yes" : "no");
467 DEBUG(level
+ 1, "Use dynamic linking: %s",
468 makefile
->dynamic
? "yes" : "no");
469 DEBUG(level
+ 1, "Code splitting mode: %s",
470 makefile
->code_splitting_mode
!= NULL
?
471 makefile
->code_splitting_mode
: "<unknown>");
472 DEBUG(level
+ 1, "Code coverage file: %s",
473 makefile
->tcov_file_name
!= NULL
?
474 makefile
->tcov_file_name
: "<unknown>");
475 #ifdef COVERAGE_BUILD
476 DEBUG(level
+ 1, "Enable coverage: %s", makefile
->coverage
? "yes" : "no");
480 /** Returns the name of an existing file that is related to command line
481 * argument \a argument. Tries the given list of suffixes. NULL pointer is
482 * returned if no file was found. The returned string shall be deallocated
484 static char *get_file_name_for_argument(const char *argument
)
486 static const char * const suffix_list
[] = {
487 "", ".ttcnpp", ".ttcnin", ".ttcn", ".ttcn3", ".3mp", ".asn", ".asn1",
488 ".cc", ".c", ".cpp", ".hh", ".h",".hpp", ".cfg", ".prj", NULL
490 const char * const *suffix_ptr
;
491 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
492 char *file_name
= mputstr(mcopystr(argument
), *suffix_ptr
);
493 if (get_path_status(file_name
) == PS_FILE
) return file_name
;
499 /** Converts \a path_name to an absolute directory using \a working_dir.
500 * NULL pointer is returned if \a path_name does not contain a directory or
501 * the resulting absolute directory is identical to \a working_dir.
502 * The returned string shall be deallocated by the caller. */
503 static char *get_dir_name(const char *path_name
, const char *working_dir
)
505 char *dir_name
= get_dir_from_path(path_name
);
506 if (dir_name
!= NULL
) {
507 char *absolute_dir
= get_absolute_dir(dir_name
, working_dir
);
509 if (absolute_dir
== NULL
|| working_dir
== NULL
) {
510 /* an error occurred */
512 } else if (!strcmp(absolute_dir
, working_dir
)) {
513 /* the directory is identical to the working dir */
516 } else return absolute_dir
;
520 /** Returns whether \a dirname1 and \a dirname2 contain the same (canonized
521 * absolute) directories. NULL pointer is handled in a special way: it is
522 * identical only to itself. */
523 static boolean
is_same_directory(const char *dirname1
, const char *dirname2
)
525 if (dirname1
== NULL
) {
526 if (dirname2
== NULL
) return TRUE
;
529 if (dirname2
== NULL
) return FALSE
;
530 else if (strcmp(dirname1
, dirname2
)) return FALSE
;
535 /** Returns whether the file \a filename1 in directory \a dirname1 is identical
536 * to file \a filename2 in directory \a dirname2. Only the directory names can
538 static boolean
is_same_file(const char *dirname1
, const char *filename1
,
539 const char *dirname2
, const char *filename2
)
541 /* first examine the file names for efficiency reasons */
542 if (strcmp(filename1
, filename2
)) return FALSE
;
543 else return is_same_directory(dirname1
, dirname2
);
546 /** Determines whether the TTCN-3 or ASN.1 module identifiers \a module1 and
547 * \a module2 are the same. Characters '-' and '_' in module names are not
549 static boolean
is_same_module(const char *module1
, const char *module2
)
553 switch (module1
[i
]) {
555 if (module2
[i
] == '\0') return TRUE
;
559 if (module2
[i
] != '-' && module2
[i
] != '_') return FALSE
;
562 if (module1
[i
] != module2
[i
]) return FALSE
;
566 return FALSE
; /* to avoid warnings */
569 /** Determines the suffix (i.e. the character sequence following the last dot)
570 * of file or path name \a file_name. NULL pointer is returned if \a file_name
571 * does not contain any dot character or the last character of it is a dot.
572 * The suffix is not copied, the returned pointer points to the tail of
574 static const char *get_suffix(const char *file_name
)
576 size_t last_dot
= (size_t)-1;
578 for (i
= 0; file_name
[i
] != '\0'; i
++)
579 if (file_name
[i
] == '.') last_dot
= i
;
580 if (last_dot
== (size_t)-1 || file_name
[last_dot
+ 1] == '\0') return NULL
;
581 else return file_name
+ last_dot
+ 1;
584 /** Truncates the suffix (i.e. the last dot and the characters following it)
585 * from \a file_name and returns a copy of the prefix of \a file_name.
586 * If \a file_name does not have a suffix an exact copy of it is returned.
587 * The returned string shall be deallocated by the caller. */
588 static char *cut_suffix(const char *file_name
)
591 size_t last_dot
= (size_t)-1;
593 for (i
= 0; file_name
[i
] != '\0'; i
++)
594 if (file_name
[i
] == '.') last_dot
= i
;
595 ret_val
= mcopystr(file_name
);
596 if (last_dot
!= (size_t)-1) ret_val
= mtruncstr(ret_val
, last_dot
);
600 /** Determines the name of the preprocessed file from \a file_name.
601 * It is assumed that \a file_name has ttcnpp suffix.
602 * The returned string shall be deallocated by the caller. */
603 static char *get_preprocessed_file_name(const char *file_name
)
605 char *ret_val
= cut_suffix(file_name
);
606 ret_val
= mputstr(ret_val
, ".ttcn");
610 /** Check if any of the preprocessed ttcn file names with the preprocessed
611 * (TTCN-3) suffix is equal to any other file given in the \a makefile */
612 static void check_preprocessed_filename_collision(
613 struct makefile_struct
*makefile
)
616 if (makefile
->nTTCN3PPModules
== 0) {
617 WARNING("TTCN-3 preprocessing (option `-p') is enabled, but no TTCN-3 "
618 "files to be preprocessed were given for the Makefile.");
620 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
621 const struct module_struct
*pp_module
= makefile
->TTCN3PPModules
+ i
;
622 /* name of the intermediate preprocessed file */
623 char *preprocessed_name
= get_preprocessed_file_name(pp_module
->file_name
);
625 for (j
= 0; j
< makefile
->nTTCN3Modules
; j
++) {
626 struct module_struct
*module
= makefile
->TTCN3Modules
+ j
;
627 if (is_same_file(pp_module
->dir_name
, preprocessed_name
,
628 module
->dir_name
, module
->file_name
)) {
629 if (is_same_module(pp_module
->module_name
, module
->module_name
)) {
630 /* same file with the same module */
631 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
632 pp_module
->file_name
);
633 char *m_pathname
= compose_path_name(module
->dir_name
,
635 WARNING("File `%s' containing TTCN-3 module `%s' is generated by "
636 "the preprocessor from `%s'. Removing the file from the list of "
637 "normal TTCN-3 modules.", m_pathname
, module
->module_name
,
641 Free(module
->dir_name
);
642 Free(module
->file_name
);
643 Free(module
->module_name
);
644 makefile
->nTTCN3Modules
--;
645 memmove(module
, module
+ 1, (makefile
->nTTCN3Modules
- j
) *
646 sizeof(*makefile
->TTCN3Modules
));
647 makefile
->TTCN3Modules
=
648 (struct module_struct
*)Realloc(makefile
->TTCN3Modules
,
649 makefile
->nTTCN3Modules
* sizeof(*makefile
->TTCN3Modules
));
651 /* same file with different module */
652 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
653 pp_module
->file_name
);
654 char *m_pathname
= compose_path_name(module
->dir_name
,
656 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
657 "with file `%s' containing TTCN-3 module `%s'.", pp_pathname
,
658 pp_module
->module_name
, m_pathname
, module
->module_name
);
662 } else if (is_same_module(pp_module
->module_name
, module
->module_name
)) {
663 /* different file with the same module */
664 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
665 pp_module
->file_name
);
666 char *m_pathname
= compose_path_name(module
->dir_name
,
668 ERROR("Both files `%s' and `%s' contain TTCN-3 module `%s'.",
669 pp_pathname
, m_pathname
, pp_module
->module_name
);
674 for (j
= 0; j
< makefile
->nASN1Modules
; j
++) {
675 struct module_struct
*module
= makefile
->ASN1Modules
+ j
;
676 if (is_same_file(pp_module
->dir_name
, preprocessed_name
,
677 module
->dir_name
, module
->file_name
)) {
678 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
679 pp_module
->file_name
);
680 char *m_pathname
= compose_path_name(module
->dir_name
,
682 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
683 "with file `%s' containing ASN.1 module `%s'.", pp_pathname
,
684 pp_module
->module_name
, m_pathname
, module
->module_name
);
689 for (j
= 0; j
< makefile
->nOtherFiles
; j
++) {
690 char *dir_name
= get_dir_name(makefile
->OtherFiles
[j
],
691 makefile
->working_dir
);
692 char *file_name
= get_file_from_path(makefile
->OtherFiles
[j
]);
693 if (is_same_file(pp_module
->dir_name
, preprocessed_name
, dir_name
,
695 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
696 pp_module
->file_name
);
697 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
698 "with other file `%s'.", pp_pathname
, pp_module
->module_name
,
699 makefile
->OtherFiles
[j
]);
705 Free(preprocessed_name
);
709 /** Checks the name clash between existing module \a module and newly added
710 * module with parameters \a path_name, \a dir_name, \a file_name,
711 * \a module_name. Both the existing and the new module shall be of the same
712 * kind, parameter \a kind shall contain the respective string (either "ASN.1"
713 * or "TTCN-3"). If a clash is found the parameters of the new module except
714 * \a path_name are deallocated and TRUE is returned. Otherwise FALSE is
716 static boolean
check_module_clash_same(const struct module_struct
*module
,
717 const char *kind
, const char *path_name
, char *dir_name
, char *file_name
,
720 if (is_same_module(module_name
, module
->module_name
)) {
721 if (is_same_file(dir_name
, file_name
,
722 module
->dir_name
, module
->file_name
)) {
723 /* the same file was given twice: just issue a warning */
724 WARNING("File `%s' was given more than once for the Makefile.",
727 /* two different files contain the same module: this cannot be
728 * resolved as the generated C++ files will clash */
729 char *path_name1
= compose_path_name(module
->dir_name
,
731 char *path_name2
= compose_path_name(dir_name
, file_name
);
732 ERROR("Both files `%s' and `%s' contain %s module `%s'.",
733 path_name1
, path_name2
, kind
, module_name
);
744 /** Checks the name clash between existing module \a module and newly added
745 * module with parameters \a dir_name, \a file_name, \a module_name. The two
746 * modules shall be of different kinds (one is ASN.1, the other is TTCN-3).
747 * Parameters \a kind1 and \a kind2 shall contain the respective strings. If a
748 * clash is found the parameters of the new module are deallocated and TRUE is
749 * returned. Otherwise FALSE is returned. */
750 static boolean
check_module_clash_different(const struct module_struct
*module
,
751 const char *kind1
, char *dir_name
, char *file_name
, char *module_name
,
754 if (is_same_module(module_name
, module
->module_name
)) {
755 /* two different files contain the same module: this cannot be resolved
756 * as the generated C++ files will clash */
757 char *path_name1
= compose_path_name(module
->dir_name
, module
->file_name
);
758 char *path_name2
= compose_path_name(dir_name
, file_name
);
759 ERROR("File `%s' containing %s module `%s' and file `%s' containing "
760 "%s module `%s' cannot be used together in the same Makefile.",
761 path_name1
, kind1
, module
->module_name
, path_name2
, kind2
, module_name
);
771 /** Adds a TTCN-3 module to Makefile descriptor structure \a makefile.
772 * The name of the TTCN-3 source file is \a path_name, the module identifier
773 * is \a module_name. It is checked whether a file or module with the same name
774 * already exists in \a makefile and an appropriate warning or error is
776 static void add_ttcn3_module(struct makefile_struct
*makefile
,
777 const char *path_name
, char *module_name
)
779 struct module_struct
*module
;
780 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
781 char *file_name
= get_file_from_path(path_name
);
782 const char *suffix
= get_suffix(file_name
);
784 boolean is_preprocessed
= FALSE
;
786 if (suffix
!= NULL
) {
787 if (!strcmp(suffix
, "ttcnpp")) {
788 if (makefile
->preprocess
) is_preprocessed
= TRUE
;
789 else WARNING("The suffix of TTCN-3 file `%s' indicates that it should be "
790 "preprocessed, but TTCN-3 preprocessing is not enabled. The file "
791 "will be added to the list of normal TTCN-3 modules in the Makefile.",
793 } else if (!strcmp(suffix
, "ttcnin")) {
794 WARNING("The suffix of file `%s' indicates that it should be a "
795 "preprocessor include file, but it contains a TTCN-3 module named `%s'. "
796 "The file will be added to the list of normal TTCN-3 modules in the "
797 "Makefile.", path_name
, module_name
);
801 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
802 if (check_module_clash_different(makefile
->ASN1Modules
+ i
, "ASN.1",
803 dir_name
, file_name
, module_name
, "TTCN-3")) return;
805 /* never entered if suffix is NULL */
806 if (is_preprocessed
) {
808 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
809 if (check_module_clash_same(makefile
->TTCN3PPModules
+ i
, "TTCN-3",
810 path_name
, dir_name
, file_name
, module_name
)) return;
812 /* clashes with normal TTCN-3 modules will be checked (and maybe resolved)
813 * in \a check_preprocessed_filename_collision() */
814 /* add it to the list of TTCN-3 modules to be preprocessed */
815 makefile
->TTCN3PPModules
= (struct module_struct
*)
816 Realloc(makefile
->TTCN3PPModules
,
817 (makefile
->nTTCN3PPModules
+ 1) * sizeof(*makefile
->TTCN3PPModules
));
818 module
= makefile
->TTCN3PPModules
+ makefile
->nTTCN3PPModules
;
819 makefile
->nTTCN3PPModules
++;
820 module
->dir_name
= dir_name
;
821 module
->file_name
= file_name
;
822 module
->module_name
= module_name
;
823 file_prefix
= cut_suffix(file_name
);
824 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
825 else module
->is_regular
= FALSE
;
828 /* the file is not preprocessed */
829 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
830 if (check_module_clash_same(makefile
->TTCN3Modules
+ i
, "TTCN-3",
831 path_name
, dir_name
, file_name
, module_name
)) return;
833 /* clashes with preprocessed TTCN-3 modules will be checked (and maybe
834 * resolved) in \a check_preprocessed_filename_collision() */
835 /* add it to the list of normal TTCN-3 modules */
836 makefile
->TTCN3Modules
= (struct module_struct
*)
837 Realloc(makefile
->TTCN3Modules
,
838 (makefile
->nTTCN3Modules
+ 1) * sizeof(*makefile
->TTCN3Modules
));
839 module
= makefile
->TTCN3Modules
+ makefile
->nTTCN3Modules
;
840 makefile
->nTTCN3Modules
++;
841 module
->dir_name
= dir_name
;
842 module
->file_name
= file_name
;
843 module
->module_name
= module_name
;
844 if (suffix
!= NULL
&& !strcmp(suffix
, "ttcn")) {
845 char *file_prefix
= cut_suffix(file_name
);
846 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
847 else module
->is_regular
= FALSE
;
850 module
->is_regular
= FALSE
;
855 /** ASN.1 filename shall contain no hyphen */
856 static boolean
is_valid_asn1_filename(const char* file_name
)
858 if (0 == strchr(file_name
, '-')) {
864 /** Adds an ASN.1 module to Makefile descriptor structure \a makefile.
865 * The name of the ASN.1 source file is \a path_name, the module identifier
866 * is \a module_name. It is checked whether a file or module with the same name
867 * already exists in \a makefile and an appropriate warning or error is
869 static void add_asn1_module(struct makefile_struct
*makefile
,
870 const char *path_name
, char *module_name
)
872 struct module_struct
*module
;
873 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
874 char *file_name
= get_file_from_path(path_name
);
875 const char *suffix
= get_suffix(file_name
);
877 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
878 if (check_module_clash_same(makefile
->ASN1Modules
+ i
, "ASN.1", path_name
,
879 dir_name
, file_name
, module_name
)) return;
881 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
882 if (check_module_clash_different(makefile
->TTCN3Modules
+ i
, "TTCN-3",
883 dir_name
, file_name
, module_name
, "ASN.1")) return;
885 if (makefile
->preprocess
) {
886 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
887 if (check_module_clash_different(makefile
->TTCN3PPModules
+ i
, "TTCN-3",
888 dir_name
, file_name
, module_name
, "ASN.1")) return;
891 makefile
->ASN1Modules
= (struct module_struct
*)
892 Realloc(makefile
->ASN1Modules
,
893 (makefile
->nASN1Modules
+ 1) * sizeof(*makefile
->ASN1Modules
));
894 module
= makefile
->ASN1Modules
+ makefile
->nASN1Modules
;
895 makefile
->nASN1Modules
++;
896 module
->dir_name
= dir_name
;
897 module
->file_name
= file_name
;
898 module
->module_name
= module_name
;
899 if (suffix
!= NULL
&& !strcmp(suffix
, "asn")) {
900 char *file_prefix
= cut_suffix(file_name
);
901 /* replace all '_' with '-' in file name prefix */
902 for (i
= 0; file_prefix
[i
] != '\0'; i
++)
903 if (file_prefix
[i
] == '_') file_prefix
[i
] = '-';
904 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
905 else module
->is_regular
= FALSE
;
908 module
->is_regular
= FALSE
;
912 /** Adds the file named \a path_name to the list of files pointed by \a list_ptr
913 * and \a list_size. The suffix or contents of \a path_name are not examined,
914 * only duplicate entries are checked. In case of duplicate entries warning is
915 * reported only if argument \a report_warning is set to TRUE. */
916 static void add_path_to_list(size_t *list_size
, char ***list_ptr
,
917 const char *path_name
, const char *working_dir
, boolean report_warning
)
920 char *dir_name
= get_dir_name(path_name
, working_dir
);
921 char *file_name
= get_file_from_path(path_name
);
922 char *canonized_path_name
= compose_path_name(dir_name
, file_name
);
925 for (i
= 0; i
< *list_size
; i
++) {
926 if (!strcmp(canonized_path_name
, (*list_ptr
)[i
])) {
927 if (report_warning
) WARNING("File `%s' was given more than once for the "
928 "Makefile.", path_name
);
929 Free(canonized_path_name
);
933 *list_ptr
= (char**)Realloc(*list_ptr
, (*list_size
+ 1) * sizeof(**list_ptr
));
934 (*list_ptr
)[*list_size
] = canonized_path_name
;
938 /** Adds a C/C++ header or source file or an other file named \a path_name to
939 * Makefile descriptor structure \a makefile. The file is classified based on
940 * its suffix and not by content. If the file clashes with existing files or
941 * modules the appropriate warning or error is generated. */
942 static void add_user_file(struct makefile_struct
*makefile
,
943 const char *path_name
)
945 const char *suffix
= get_suffix(path_name
);
946 if (suffix
!= NULL
) {
947 if (!strcmp(suffix
, "ttcn") || !strcmp(suffix
, "ttcn3") ||
948 !strcmp(suffix
, "3mp") || !strcmp(suffix
, "ttcnpp")) {
949 /* The file content was already checked. Since it doesn't look like
950 * a valid TTCN-3 file, these suffixes are suspect */
951 WARNING("File `%s' does not contain a valid TTCN-3 module. "
952 "It will be added to the Makefile as other file.", path_name
);
954 else if (!strcmp(suffix
, "ttcnin")) {
955 /* this is a TTCN-3 include file */
956 if (makefile
->preprocess
) {
957 add_path_to_list(&makefile
->nTTCN3IncludeFiles
,
958 &makefile
->TTCN3IncludeFiles
, path_name
, makefile
->working_dir
, TRUE
);
962 WARNING("The suffix of file `%s' indicates that it is a TTCN-3 "
963 "include file, but TTCN-3 preprocessing is not enabled. The file "
964 "will be added to the Makefile as other file.", path_name
);
967 else if (!strcmp(suffix
, "asn") || !strcmp(suffix
, "asn1")) {
968 /* The file content was already checked. Since it doesn't look like
969 * a valid ASN.1 file, these suffixes are suspect */
970 WARNING("File `%s' does not contain a valid ASN.1 module. "
971 "It will be added to the Makefile as other file.", path_name
);
973 else if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "c") || !strcmp(suffix
, "cpp")) {
974 /* this is a source file */
975 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
976 char *file_name
= get_file_from_path(path_name
);
977 char *file_prefix
= cut_suffix(file_name
);
978 struct user_struct
*user
;
980 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
981 user
= makefile
->UserFiles
+ i
;
982 if (!strcmp(file_prefix
, user
->file_prefix
)) {
983 if (user
->source_name
!= NULL
) {
984 /* the source file is already present */
985 if (is_same_file(dir_name
, file_name
,
986 user
->dir_name
, user
->source_name
)) {
987 WARNING("File `%s' was given more than once for the Makefile.", path_name
);
990 char *path_name1
= compose_path_name(user
->dir_name
, user
->source_name
);
991 char *path_name2
= compose_path_name(dir_name
, file_name
);
992 ERROR("C/C++ source files `%s' and `%s' cannot be used together "
993 "in the same Makefile.", path_name1
, path_name2
);
999 /* a header file with the same prefix is already present */
1000 if (is_same_directory(dir_name
, user
->dir_name
)) {
1001 user
->source_name
= file_name
;
1003 if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "cpp"))
1004 user
->has_cc_suffix
= TRUE
;
1007 char *path_name1
= compose_path_name(dir_name
, file_name
);
1008 char *path_name2
= compose_path_name(user
->dir_name
, user
->header_name
);
1009 ERROR("C/C++ source file `%s' cannot be used together with "
1010 "header file `%s' in the same Makefile.", path_name1
,
1022 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1023 (makefile
->nUserFiles
+ 1) * sizeof(*makefile
->UserFiles
));
1024 user
= makefile
->UserFiles
+ makefile
->nUserFiles
;
1025 makefile
->nUserFiles
++;
1026 user
->dir_name
= dir_name
;
1027 user
->file_prefix
= file_prefix
;
1028 user
->header_name
= NULL
;
1029 user
->source_name
= file_name
;
1030 user
->has_hh_suffix
= FALSE
;
1031 if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "cpp")) user
->has_cc_suffix
= TRUE
;
1032 else user
->has_cc_suffix
= FALSE
;
1035 else if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "h")) {
1036 /* this is a header file */
1037 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
1038 char *file_name
= get_file_from_path(path_name
);
1039 char *file_prefix
= cut_suffix(file_name
);
1040 struct user_struct
*user
;
1042 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1043 user
= makefile
->UserFiles
+ i
;
1044 if (!strcmp(file_prefix
, user
->file_prefix
)) {
1045 if (user
->header_name
!= NULL
) {
1046 /* the header file is already present */
1047 if (is_same_file(dir_name
, file_name
, user
->dir_name
, user
->header_name
)) {
1048 WARNING("File `%s' was given more than once for the Makefile.", path_name
);
1051 char *path_name1
= compose_path_name(user
->dir_name
, user
->header_name
);
1052 char *path_name2
= compose_path_name(dir_name
, file_name
);
1053 ERROR("C/C++ header files `%s' and `%s' cannot be used together "
1054 "in the same Makefile.", path_name1
, path_name2
);
1060 /* a source file with the same prefix is already present */
1061 if (is_same_directory(dir_name
, user
->dir_name
)) {
1062 user
->header_name
= file_name
;
1064 if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "hpp"))
1065 user
->has_hh_suffix
= TRUE
;
1068 char *path_name1
= compose_path_name(dir_name
, file_name
);
1069 char *path_name2
= compose_path_name(user
->dir_name
, user
->source_name
);
1070 ERROR("C/C++ header file `%s' cannot be used together with "
1071 "source file `%s' in the same Makefile.", path_name1
, path_name2
);
1082 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1083 (makefile
->nUserFiles
+ 1) * sizeof(*makefile
->UserFiles
));
1084 user
= makefile
->UserFiles
+ makefile
->nUserFiles
;
1085 makefile
->nUserFiles
++;
1086 user
->dir_name
= dir_name
;
1087 user
->file_prefix
= file_prefix
;
1088 user
->header_name
= file_name
;
1089 user
->source_name
= NULL
;
1090 if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "hpp")) user
->has_hh_suffix
= TRUE
;
1091 else user
->has_hh_suffix
= FALSE
;
1092 user
->has_cc_suffix
= FALSE
;
1095 } /* end if (suffix != NULL) */
1096 /* treat the file as other file if it was not handled yet */
1097 add_path_to_list(&makefile
->nOtherFiles
, &makefile
->OtherFiles
, path_name
,
1098 makefile
->working_dir
, TRUE
);
1101 /** Removes the generated C++ header and/or source files of module \a module
1102 * from Makefile descriptor structure \a makefile. A warning is displayed if
1103 * such file is found. */
1104 static void drop_generated_files(struct makefile_struct
*makefile
,
1105 const struct module_struct
*module
)
1107 char *module_name
= mcopystr(module
->module_name
);
1109 /* transform all '-' characters in ASN.1 module name to '_' */
1110 for (i
= 0; module_name
[i
] != '\0'; i
++)
1111 if (module_name
[i
] == '-') module_name
[i
] = '_';
1112 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1113 struct user_struct
*user
= makefile
->UserFiles
+ i
;
1114 if (!strcmp(module_name
, user
->file_prefix
)) {
1115 char *m_pathname
= compose_path_name(module
->dir_name
, module
->file_name
);
1116 /** Note: if central storage is used the generated C++ files are placed
1117 * into the same directory as the TTCN-3/ASN.1 modules, otherwise the
1118 * files are generated into the working directory. */
1119 boolean is_same_dir
= is_same_directory(user
->dir_name
,
1120 makefile
->central_storage
? module
->dir_name
: NULL
);
1121 if (user
->header_name
!= NULL
) {
1122 char *u_pathname
= compose_path_name(user
->dir_name
,
1124 if (is_same_dir
&& user
->has_hh_suffix
) {
1125 WARNING("Header file `%s' is generated from module `%s' (file `%s'). "
1126 "Removing it from the list of user files.", u_pathname
,
1127 module
->module_name
, m_pathname
);
1129 ERROR("Header file `%s' cannot be used together with module `%s' "
1130 "(file `%s') in the same Makefile.", u_pathname
,
1131 module
->module_name
, m_pathname
);
1135 if (user
->source_name
!= NULL
) {
1136 char *u_pathname
= compose_path_name(user
->dir_name
,
1138 if (is_same_dir
&& user
->has_cc_suffix
) {
1139 WARNING("Source file `%s' is generated from module `%s' (file "
1140 "`%s'). Removing it from the list of user files.", u_pathname
,
1141 module
->module_name
, m_pathname
);
1143 ERROR("Source file `%s' cannot be used together with module "
1144 "`%s' (file `%s') in the same Makefile.", u_pathname
,
1145 module
->module_name
, m_pathname
);
1150 Free(user
->dir_name
);
1151 Free(user
->file_prefix
);
1152 Free(user
->header_name
);
1153 Free(user
->source_name
);
1154 makefile
->nUserFiles
--;
1155 memmove(user
, user
+ 1, (makefile
->nUserFiles
- i
) *
1156 sizeof(*makefile
->UserFiles
));
1157 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1158 makefile
->nUserFiles
* sizeof(*makefile
->UserFiles
));
1165 /** Drops all C++ header and source files of the Makefile descriptor structure
1166 * \a makefile that are generated from its TTCN-3 or ASN.1 modules. */
1167 static void filter_out_generated_files(struct makefile_struct
*makefile
)
1170 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1171 drop_generated_files(makefile
, makefile
->TTCN3Modules
+ i
);
1173 if (makefile
->preprocess
) {
1174 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1175 drop_generated_files(makefile
, makefile
->TTCN3PPModules
+ i
);
1178 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1179 drop_generated_files(makefile
, makefile
->ASN1Modules
+ i
);
1183 /** Completes the list of user C/C++ header and source files in \a makefile.
1184 * If only the source file was given the function looks for the corresponding
1185 * header file or vice versa. */
1186 static void complete_user_files(const struct makefile_struct
*makefile
)
1189 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1190 struct user_struct
*user
= makefile
->UserFiles
+ i
;
1191 if (user
->header_name
== NULL
) {
1192 static const char * const suffix_list
[] = { "hh", "h", "hpp", NULL
};
1193 const char * const *suffix_ptr
;
1194 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
1195 char *file_name
= mprintf("%s.%s", user
->file_prefix
, *suffix_ptr
);
1196 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1197 if (get_path_status(path_name
) == PS_FILE
) {
1199 user
->header_name
= file_name
;
1200 if (!strcmp(*suffix_ptr
, "hh") || !strcmp(*suffix_ptr
, "hpp"))
1201 user
->has_hh_suffix
= TRUE
;
1208 else if (user
->source_name
== NULL
) {
1209 static const char * const suffix_list
[] = { "cc", "c", "cpp", 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
->source_name
= file_name
;
1217 if (!strcmp(*suffix_ptr
, "cc") || !strcmp(*suffix_ptr
, "cpp"))
1218 user
->has_cc_suffix
= TRUE
;
1228 /** Converts the directory name pointed by \a dir_ptr to a relative pathname
1229 * based on \a working_dir. The original directory name is deallocated and
1230 * replaced with a new string. Nothing happens if \a dir_ptr points to NULL. */
1231 static void replace_dir_with_relative(char **dir_ptr
, const char *working_dir
)
1233 if (*dir_ptr
!= NULL
) {
1234 char *rel_dir
= get_relative_dir(*dir_ptr
, working_dir
);
1240 /** Converts the directory part of path name pointed by \a path_ptr to a relative
1241 * pathname based on \a working_dir. The original path name is deallocated and
1242 * replaced with a new string. */
1243 static void convert_path_to_relative(char **path_ptr
, const char *working_dir
)
1245 char *dir_name
= get_dir_name(*path_ptr
, working_dir
);
1246 if (dir_name
!= NULL
) {
1247 char *file_name
= get_file_from_path(*path_ptr
);
1248 replace_dir_with_relative(&dir_name
, working_dir
);
1250 *path_ptr
= compose_path_name(dir_name
, file_name
);
1256 /** Converts all directories used by the Makefile descriptor structure
1257 * \a makefile to relative pathnames based on the working directory stored in
1259 static void convert_dirs_to_relative(struct makefile_struct
*makefile
)
1262 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1263 replace_dir_with_relative(&makefile
->TTCN3Modules
[i
].dir_name
,
1264 makefile
->working_dir
);
1266 if (makefile
->preprocess
) {
1267 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1268 replace_dir_with_relative(&makefile
->TTCN3PPModules
[i
].dir_name
,
1269 makefile
->working_dir
);
1271 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++) {
1272 convert_path_to_relative(makefile
->TTCN3IncludeFiles
+ i
,
1273 makefile
->working_dir
);
1276 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1277 replace_dir_with_relative(&makefile
->ASN1Modules
[i
].dir_name
,
1278 makefile
->working_dir
);
1280 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1281 replace_dir_with_relative(&makefile
->UserFiles
[i
].dir_name
,
1282 makefile
->working_dir
);
1284 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) {
1285 convert_path_to_relative(makefile
->OtherFiles
+ i
, makefile
->working_dir
);
1287 if (makefile
->ets_name
!= NULL
)
1288 convert_path_to_relative(&makefile
->ets_name
, makefile
->working_dir
);
1291 /* Returns whether the string \a file_name contains special characters. */
1292 static boolean
has_special_chars(const char *file_name
)
1294 if (file_name
!= NULL
) {
1296 for (i
= 0; ; i
++) {
1297 int c
= (unsigned char)file_name
[i
];
1327 if (!isascii(c
) || !isprint(c
)) return TRUE
;
1335 /** Checks whether the path name composed of \a dir_name and \a file_name
1336 * contains special characters that are not allowed in the Makefile. Parameter
1337 * \a what contains the description of the corresponding file. */
1338 static void check_special_chars_in_path(const char *dir_name
,
1339 const char *file_name
, const char *what
)
1341 if (has_special_chars(dir_name
) || has_special_chars(file_name
)) {
1342 char *path_name
= compose_path_name(dir_name
, file_name
);
1343 ERROR("The name of %s `%s' contains special characters that cannot be "
1344 "handled properly by the `make' utility and/or the shell.", what
,
1350 /** Checks whether the directory names or file names that will be used in the
1351 * generated Makefile contain special characters that cannot be handled by the
1352 * "make" utility. */
1353 static void check_special_chars(const struct makefile_struct
*makefile
)
1356 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1357 check_special_chars_in_path(makefile
->TTCN3Modules
[i
].dir_name
,
1358 makefile
->TTCN3Modules
[i
].file_name
, "TTCN-3 file");
1360 if (makefile
->preprocess
) {
1361 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1362 check_special_chars_in_path(makefile
->TTCN3PPModules
[i
].dir_name
,
1363 makefile
->TTCN3PPModules
[i
].file_name
,
1364 "TTCN-3 file to be preprocessed");
1367 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1368 check_special_chars_in_path(makefile
->ASN1Modules
[i
].dir_name
,
1369 makefile
->ASN1Modules
[i
].file_name
, "ASN.1 file");
1371 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1372 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1373 if (user
->source_name
!= NULL
)
1374 check_special_chars_in_path(user
->dir_name
, user
->source_name
,
1375 "C/C++ source file");
1376 else check_special_chars_in_path(user
->dir_name
, user
->header_name
,
1377 "C/C++ header file");
1379 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) {
1380 check_special_chars_in_path(NULL
, makefile
->OtherFiles
[i
], "other file");
1384 /** Adds base directory \a dir_name to Makefile descriptor structure
1385 * \a makefile. Flag \a has_modules indicates whether \a dir_name contains
1386 * TTCN-3 and/or ASN.1 modules. The new directory is ignored if it is already
1387 * added to \a makefile. */
1388 static void add_base_dir(struct makefile_struct
*makefile
,
1389 const char *dir_name
, boolean has_modules
)
1391 struct base_dir_struct
*base_dir
;
1392 if (dir_name
!= NULL
) {
1394 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1395 base_dir
= makefile
->BaseDirs
+ i
;
1396 if (!strcmp(dir_name
, base_dir
->dir_name
)) {
1397 if (has_modules
) base_dir
->has_modules
= TRUE
;
1401 makefile
->BaseDirs
= (struct base_dir_struct
*)Realloc(makefile
->BaseDirs
,
1402 (makefile
->nBaseDirs
+ 1) * sizeof(*makefile
->BaseDirs
));
1403 base_dir
= makefile
->BaseDirs
+ makefile
->nBaseDirs
;
1404 makefile
->nBaseDirs
++;
1405 base_dir
->dir_name
= dir_name
;
1406 base_dir
->has_modules
= has_modules
;
1410 /** Collects all directories that are used in the Makefile descriptor structure
1411 * \a makefile in order to use pre-compiled files from them. */
1412 static void collect_base_dirs(struct makefile_struct
*makefile
)
1415 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1416 add_base_dir(makefile
, makefile
->TTCN3Modules
[i
].dir_name
, TRUE
);
1418 if (makefile
->preprocess
) {
1419 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1420 add_base_dir(makefile
, makefile
->TTCN3PPModules
[i
].dir_name
, TRUE
);
1423 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1424 add_base_dir(makefile
, makefile
->ASN1Modules
[i
].dir_name
, TRUE
);
1426 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1427 add_base_dir(makefile
, makefile
->UserFiles
[i
].dir_name
, FALSE
);
1429 if (makefile
->nBaseDirs
== 0) {
1430 WARNING("Usage of pre-compiled files from central storage (option `-c') "
1431 "is enabled, but all given files are located in the current working "
1436 /** Checks whether the TTCN-3, ASN.1 and C++ files follow the default naming
1437 * convention and sets the appropriate flags accordingly. */
1438 static void check_naming_convention(struct makefile_struct
*makefile
)
1440 /* initially set all flags to true */
1441 makefile
->TTCN3ModulesRegular
= TRUE
;
1442 makefile
->BaseTTCN3ModulesRegular
= TRUE
;
1443 makefile
->ASN1ModulesRegular
= TRUE
;
1444 makefile
->BaseASN1ModulesRegular
= TRUE
;
1445 makefile
->UserHeadersRegular
= TRUE
;
1446 makefile
->UserSourcesRegular
= TRUE
;
1447 makefile
->BaseUserHeadersRegular
= TRUE
;
1448 makefile
->BaseUserSourcesRegular
= TRUE
;
1449 if (makefile
->central_storage
) {
1450 /* this project (Makefile) will use pre-compiled files from other
1453 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1454 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1455 if (module
->dir_name
!= NULL
) {
1456 if (!module
->is_regular
) makefile
->BaseTTCN3ModulesRegular
= FALSE
;
1459 if (!module
->is_regular
) makefile
->TTCN3ModulesRegular
= FALSE
;
1461 if (!makefile
->TTCN3ModulesRegular
&& !makefile
->BaseTTCN3ModulesRegular
)
1464 /* ttcnpp files are ttcn files */
1465 if ((makefile
->TTCN3ModulesRegular
|| makefile
->BaseTTCN3ModulesRegular
) &&
1466 makefile
->preprocess
) {
1467 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1468 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1469 if (module
->dir_name
!= NULL
) {
1470 if (!module
->is_regular
) makefile
->BaseTTCN3ModulesRegular
= FALSE
;
1472 if (!module
->is_regular
) makefile
->TTCN3ModulesRegular
= FALSE
;
1474 if (!makefile
->TTCN3ModulesRegular
&& !makefile
->BaseTTCN3ModulesRegular
)
1478 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1479 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1480 if (module
->dir_name
!= NULL
) {
1481 if (!module
->is_regular
) makefile
->BaseASN1ModulesRegular
= FALSE
;
1484 if (!module
->is_regular
) makefile
->ASN1ModulesRegular
= FALSE
;
1486 if (!makefile
->ASN1ModulesRegular
&& !makefile
->BaseASN1ModulesRegular
)
1489 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1490 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1491 if (user
->dir_name
!= NULL
) {
1492 if (!user
->has_cc_suffix
)
1493 makefile
->BaseUserSourcesRegular
= FALSE
;
1494 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1495 makefile
->BaseUserHeadersRegular
= FALSE
;
1498 if (!user
->has_cc_suffix
)
1499 makefile
->UserSourcesRegular
= FALSE
;
1500 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1501 makefile
->UserHeadersRegular
= FALSE
;
1503 if (!makefile
->UserHeadersRegular
&& !makefile
->UserSourcesRegular
&&
1504 !makefile
->BaseUserHeadersRegular
&&
1505 !makefile
->BaseUserSourcesRegular
) break;
1508 /* this project (Makefile) will-be stand-alone */
1510 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1511 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1512 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1513 makefile
->TTCN3ModulesRegular
= FALSE
;
1517 if (makefile
->TTCN3ModulesRegular
&& makefile
->preprocess
) {
1518 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1519 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1520 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1521 makefile
->TTCN3ModulesRegular
= FALSE
;
1526 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1527 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1528 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1529 makefile
->ASN1ModulesRegular
= FALSE
;
1533 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1534 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1535 if (!user
->has_cc_suffix
)
1536 makefile
->UserSourcesRegular
= FALSE
;
1537 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1538 makefile
->UserHeadersRegular
= FALSE
;
1539 if (!makefile
->UserHeadersRegular
&& !makefile
->UserSourcesRegular
)
1545 /** Prints the name of the TTCN-3 or ASN.1 source file that belongs to module
1546 * \a module to file \a fp. */
1547 static void print_file_name(FILE *fp
, const struct module_struct
*module
)
1549 char *path_name
= compose_path_name(module
->dir_name
, module
->file_name
);
1550 fprintf(fp
, " %s", path_name
);
1554 /** Prints the name of the preprocessed TTCN-3 source file that belongs to
1555 * module \a module to file \a fp. */
1556 static void print_preprocessed_file_name(FILE *fp
,
1557 const struct module_struct
*module
)
1559 char *preprocessed_name
= get_preprocessed_file_name(module
->file_name
);
1560 char *path_name
= compose_path_name(module
->dir_name
, preprocessed_name
);
1561 fprintf(fp
, " %s", path_name
);
1563 Free(preprocessed_name
);
1566 /** Prints the name of the generated header, source or object file of module
1567 * \a module to file \a fp. The name of the directory is added only if
1568 * \a add_directory is TRUE. Parameter \a suffix shall be "hh", "cc", "hpp", "cpp" or "o". */
1569 static void print_generated_file_name(FILE *fp
,
1570 const struct module_struct
*module
, boolean add_directory
, const char *suffix
)
1572 char *file_name
= mcopystr(module
->module_name
);
1573 /* replace '-' with '_' */
1575 for (i
= 0; file_name
[i
] != '\0'; i
++)
1576 if (file_name
[i
] == '-') file_name
[i
] = '_';
1577 /* append the suffix */
1578 file_name
= mputprintf(file_name
, "%s", suffix
);
1579 /* add the directory name if necessary */
1580 if (add_directory
) {
1581 char *path_name
= compose_path_name(module
->dir_name
, file_name
);
1583 file_name
= path_name
;
1585 fprintf(fp
, " %s", file_name
);
1589 /** Prints the name of the user C/C++ header file of user module \a user if the
1590 * above file exists. */
1591 static void print_header_name(FILE *fp
, const struct user_struct
*user
)
1593 if (user
->header_name
!= NULL
) {
1594 char *path_name
= compose_path_name(user
->dir_name
, user
->header_name
);
1595 fprintf(fp
, " %s", path_name
);
1600 /** Prints the name of the user C/C++ source file of user module \a user if the
1601 * above file exists. */
1602 static void print_source_name(FILE *fp
, const struct user_struct
*user
)
1604 if (user
->source_name
!= NULL
) {
1605 char *path_name
= compose_path_name(user
->dir_name
, user
->source_name
);
1606 fprintf(fp
, " %s", path_name
);
1611 /** Prints the name of the user C/C++ object file of user module \a user if the
1612 * above file exists (i.e. the respective source file is present). */
1613 static void print_object_name(FILE *fp
, const struct user_struct
*user
)
1615 if (user
->source_name
!= NULL
) {
1616 char *file_name
= mprintf("%s.o", user
->file_prefix
);
1617 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1619 fprintf(fp
, " %s", path_name
);
1624 static void print_shared_object_name(FILE *fp
, const struct user_struct
*user
)
1626 if (user
->source_name
!= NULL
) {
1627 char *file_name
= mprintf("%s.so", user
->file_prefix
);
1628 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1630 fprintf(fp
, " %s", path_name
);
1634 /** Prints the splitted files' names for a given module. */
1635 static void print_splitted_file_names(FILE *fp
,
1636 const struct makefile_struct
*makefile
, const struct module_struct
*module
)
1638 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
1639 print_generated_file_name(fp
, module
, FALSE
, "_seq.cc");
1640 print_generated_file_name(fp
, module
, FALSE
, "_set.cc");
1641 print_generated_file_name(fp
, module
, FALSE
, "_seqof.cc");
1642 print_generated_file_name(fp
, module
, FALSE
, "_setof.cc");
1643 print_generated_file_name(fp
, module
, FALSE
, "_union.cc");
1647 static void fprint_extra_targets(FILE* fp
, struct string2_list
* target_placement_list
, const char* placement
)
1649 struct string2_list
* act_elem
= target_placement_list
;
1651 if (act_elem
->str1
&& act_elem
->str2
&& (strcmp(act_elem
->str2
,placement
)==0)) {
1652 fprintf(fp
, " %s", act_elem
->str1
);
1654 act_elem
= act_elem
->next
;
1658 #undef COMMENT_PREFIX
1659 #define COMMENT_PREFIX "# "
1661 /** Prints the Makefile based on structure \a makefile. */
1662 static void print_makefile(struct makefile_struct
*makefile
)
1664 boolean add_refd_prjs
= FALSE
;
1665 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
1666 add_refd_prjs
= hasSubProject(makefile
->project_name
);
1669 add_refd_prjs
= makefile
->sub_project_dirs
&& makefile
->sub_project_dirs
->str
;
1671 NOTIFY("Generating Makefile skeleton...");
1673 if (makefile
->force_overwrite
||
1674 get_path_status(makefile
->output_file
) == PS_NONEXISTENT
) {
1679 const char *rm_command
= makefile
->gnu_make
? "$(RM)" : "rm -f";
1681 boolean run_compiler
= (makefile
->nASN1Modules
> 0)
1682 || (makefile
->nTTCN3Modules
) || (makefile
->nTTCN3PPModules
> 0);
1684 expstring_t titan_dir
= 0;
1685 const char * last_slash
= strrchr(program_name
, '/');
1686 if (last_slash
!= NULL
) {
1687 size_t path_len
= last_slash
- program_name
;
1688 titan_dir
= mcopystr(program_name
);
1689 /* Chop off the program name, and the /bin before it (if any) */
1691 && memcmp(titan_dir
+ path_len
- 4, "/bin", 4) == 0) {
1692 titan_dir
= mtruncstr(titan_dir
, path_len
- 4);
1695 titan_dir
= mtruncstr(titan_dir
, path_len
);
1700 fp
= fopen(makefile
->output_file
, "w");
1702 ERROR("Cannot open output file `%s' for writing: %s",
1703 makefile
->output_file
, strerror(errno
));
1706 user_info
= get_user_info();
1707 fprintf(fp
, "# This Makefile was generated by the Makefile Generator\n"
1708 "# of the TTCN-3 Test Executor version " PRODUCT_NUMBER
"\n"
1710 COPYRIGHT_STRING
"\n\n"
1711 "# The following make commands are available:\n"
1712 "# - make, make all Builds the %s.\n"
1713 "# - make archive Archives all source files.\n"
1714 "# - make check Checks the semantics of TTCN-3 and ASN.1 "
1718 "# - make compile Translates TTCN-3 and ASN.1 modules to C++.\n"
1719 "# - make dep Creates/updates dependency list.\n"
1720 "# - make executable Builds the executable test suite.\n"
1721 "# - make library Builds the library archive.\n"
1722 "# - make objects Builds the object files without linking the "
1723 "executable.\n", user_info
,
1724 makefile
->library
? "library archive." : "executable test suite",
1725 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ?
1726 "# - make clean Removes generated files from project.\n" :
1727 "# - make clean Removes all generated files.\n",
1728 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ?
1729 "# - make clean-all Removes all generated files from the project hierarchy.\n" : "");
1731 if (makefile
->dynamic
)
1732 fprintf(fp
, "# - make shared_objects Builds the shared object files "
1733 "without linking the executable.\n");
1734 if (makefile
->preprocess
)
1735 fputs("# - make preprocess Preprocess TTCN-3 files.\n", fp
);
1736 if (makefile
->central_storage
) {
1737 fputs("# WARNING! This Makefile uses pre-compiled files from the "
1738 "following directories:\n", fp
);
1739 for (i
= 0; i
< makefile
->nBaseDirs
; i
++)
1740 fprintf(fp
, "# %s\n", makefile
->BaseDirs
[i
].dir_name
);
1741 fputs("# The executable tests will be consistent only if all directories "
1743 "# the same platform and the same version of TTCN-3 Test Executor "
1745 "# C++ compiler with the same command line switches.\n\n", fp
);
1747 if (makefile
->gnu_make
) {
1748 fputs("# WARNING! This Makefile can be used with GNU make only.\n"
1749 "# Other versions of make may report syntax errors in it.\n\n"
1751 "# Do NOT touch this line...\n"
1753 ".PHONY: all shared_objects executable library objects check clean dep archive", fp
);
1754 if (makefile
->preprocess
) fputs(" preprocess", fp
);
1755 if (add_refd_prjs
) {
1756 fprintf(fp
, "\\\n referenced-all referenced-shared_objects referenced-executable referenced-library referenced-objects referenced-check"
1757 "\\\n referenced-clean%s",
1758 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ?
1761 fprint_extra_targets(fp
, makefile
->target_placement_list
, "PHONY");
1763 if (makefile
->gcc_dep
) {
1764 fputs("\n\n.SUFFIXES: .d", fp
);
1769 if (makefile
->linkingStrategy
) {
1770 const char* tpd_name
= getTPDFileName(makefile
->project_name
);
1772 fputs("# Titan Project Descriptor file what this Makefile is generated from.\n", fp
);
1773 fprintf(fp
, "TPD = %s\n\n", tpd_name
);
1775 const char* root_dir
= getPathToRootDir(makefile
->project_name
);
1777 fputs("# Relative path to top directory at OS level.\n", fp
);
1778 fprintf(fp
, "ROOT_DIR = %s\n\n", root_dir
);
1782 if (add_refd_prjs
) {
1783 struct string_list
* act_elem
= NULL
;
1784 struct string_list
* head
= NULL
;
1785 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {// pair with free_string_list
1786 head
= act_elem
= getRefWorkingDirs(makefile
->project_name
);
1789 act_elem
= makefile
->sub_project_dirs
;
1791 if (!makefile
->linkingStrategy
)
1792 fputs("# This is the top level makefile of a Makefile hierarchy generated from\n", fp
);
1793 fputs("# Titan Project Descriptor hierarchy. List of referenced project\n"
1794 "# working directories (ordered by dependencies):\n", fp
);
1796 if (act_elem
->str
) {
1797 fprintf(fp
, "# %s\n", act_elem
->str
);
1799 act_elem
= act_elem
->next
;
1801 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) { // pair with getRefWorkingDirs
1802 free_string_list(head
);
1804 fputs("REFERENCED_PROJECT_DIRS = ", fp
);
1805 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
1806 head
= act_elem
= getRefWorkingDirs(makefile
->project_name
); // pair with free_string_list
1809 act_elem
= makefile
->sub_project_dirs
;
1812 if (act_elem
->str
) {
1813 fprintf(fp
, "%s ", act_elem
->str
);
1815 act_elem
= act_elem
->next
;
1818 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {// pair with getRefWorkingDirs
1819 free_string_list(head
);
1824 "# Set these variables...\n"
1826 "# The path of your TTCN-3 Test Executor installation:\n"
1827 "# Uncomment this line to override the environment variable.\n"
1829 "# TTCN3_DIR = %s\n"
1831 "# The value below points to the location of the TITAN version\n"
1832 "# that generated this makefile.\n" : ""
1833 , titan_dir
? titan_dir
: "");
1834 if (titan_dir
) Free(titan_dir
);
1836 if (makefile
->cxxcompiler
) {
1837 cxx
= makefile
->cxxcompiler
;
1842 fprintf(fp
, "\n# Your platform: (SOLARIS, SOLARIS8, LINUX, FREEBSD or "
1845 "# Your C++ compiler:\n"
1846 "# (if you change the platform, you may need to change the compiler)\n"
1847 "CXX = %s \n\n", get_platform_string(), cxx
);
1850 if (makefile
->preprocess
|| makefile
->ttcn3preprocessor
) {
1851 if (makefile
->ttcn3preprocessor
) {
1852 cpp
= makefile
->ttcn3preprocessor
;
1856 fprintf(fp
,"# C preprocessor used for TTCN-3 files:\n"
1857 "CPP = %s\n\n", cpp
);
1860 fputs("# Flags for the C++ preprocessor (and makedepend as well):\n"
1861 "CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)/include", fp
);
1863 if (makefile
->use_runtime_2
) fputs(" -DTITAN_RUNTIME_2", fp
);
1865 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1866 fprintf(fp
, " -I%s", makefile
->BaseDirs
[i
].dir_name
);
1869 if (makefile
->prep_includes
) {
1870 struct string_list
* act_elem
= makefile
->prep_includes
;
1872 if (act_elem
->str
) {
1873 fprintf(fp
, " -I%s", act_elem
->str
);
1875 act_elem
= act_elem
->next
;
1879 if (makefile
->prep_defines
) {
1880 struct string_list
* act_elem
= makefile
->prep_defines
;
1882 if (act_elem
->str
) {
1883 fprintf(fp
, " -D%s", act_elem
->str
);
1885 act_elem
= act_elem
->next
;
1889 if (makefile
->prep_undefines
) {
1890 struct string_list
* act_elem
= makefile
->prep_undefines
;
1892 if (act_elem
->str
) {
1893 fprintf(fp
, " -U%s", act_elem
->str
);
1895 act_elem
= act_elem
->next
;
1901 if (makefile
->gcc_dep
) {
1902 fprintf(fp
, "# Flags for dependency generation\n"
1903 "CXXDEPFLAGS = -%s\n\n", strstr(cxx
, "g++") ? "MM" : "xM1");
1906 if (makefile
->preprocess
|| makefile
->ttcn3_prep_includes
|| makefile
->ttcn3_prep_defines
) {
1907 fputs("# Flags for preprocessing TTCN-3 files:\n"
1908 "CPPFLAGS_TTCN3 =", fp
);
1910 if (makefile
->preprocess
) {
1911 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1912 fprintf(fp
, " -I%s", makefile
->BaseDirs
[i
].dir_name
);
1915 if (makefile
->ttcn3_prep_includes
) {
1916 struct string_list
* act_elem
= makefile
->ttcn3_prep_includes
;
1918 if (act_elem
->str
) {
1919 fprintf(fp
, " -I%s", act_elem
->str
);
1921 act_elem
= act_elem
->next
;
1924 if (makefile
->ttcn3_prep_defines
) {
1925 struct string_list
* act_elem
= makefile
->ttcn3_prep_defines
;
1927 if (act_elem
->str
) {
1928 fprintf(fp
, " -D%s", act_elem
->str
);
1930 act_elem
= act_elem
->next
;
1933 if (makefile
->ttcn3_prep_undefines
) {
1934 struct string_list
* act_elem
= makefile
->ttcn3_prep_undefines
;
1936 if (act_elem
->str
) {
1937 fprintf(fp
, " -U%s", act_elem
->str
);
1939 act_elem
= act_elem
->next
;
1945 /* code splitting: command line argument wins */
1946 if (makefile
->code_splitting_mode
== NULL
) {
1947 if (makefile
->codesplittpd
) {
1948 makefile
->code_splitting_mode
= mcopystr("-U type");
1952 fprintf(fp
, "# Flags for the C++ compiler:\n"
1953 "CXXFLAGS = %s%s %s %s\n\n"
1954 "# Flags for the linker:\n"
1955 "LDFLAGS = %s%s\n\n"
1956 "ifeq ($(PLATFORM), WIN32)\n"
1957 "# Silence linker warnings.\n"
1958 "LDFLAGS += -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc\n"
1960 "# Utility to create library files\n"
1963 "# Flags for the TTCN-3 and ASN.1 compiler:\n"
1964 "COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s %s\n\n"
1965 "# Execution mode: (either ttcn3 or ttcn3-parallel)\n"
1966 "TTCN3_LIB = ttcn3%s%s%s\n\n"
1968 "# The path of your OpenSSL installation:\n"
1969 "# If you do not have your own one, leave it unchanged.\n"
1970 "OPENSSL_DIR = $(TTCN3_DIR)\n\n"
1972 "# The path of your libxml2 installation:\n"
1973 "# If you do not have your own one, leave it unchanged.\n"
1974 "XMLDIR = $(TTCN3_DIR)\n\n"
1975 "# Directory to store the archived source files:\n",
1976 makefile
->dynamic
? "-Wall -fPIC" : "-Wall", /* CXXFLAGS */
1977 makefile
->coverage
? " -fprofile-arcs -ftest-coverage -g" : "", /* CXXFLAGS COVERAGE */
1978 makefile
->optlevel
? makefile
->optlevel
: "", /* CXXFLAGS optimization level */
1979 makefile
->optflags
? makefile
->optflags
: "", /* CXXFLAGS optimization level */
1980 makefile
->dynamic
? "-fPIC" : "", /* LDFLAGS */
1981 makefile
->coverage
? " -fprofile-arcs -ftest-coverage -g -lgcov" : "", /* LDFLAGS COVERAGE */
1982 /* COMPILER_FLAGS */
1983 makefile
->use_runtime_2
? " -L -R " : " -L ",
1984 (makefile
->code_splitting_mode
? makefile
->code_splitting_mode
: ""),
1985 (makefile
->quietly
? " -q" : ""),
1986 (makefile
->disablesubtypecheck
? " -y" : ""),
1987 (makefile
->disableber
? " -b" : ""),
1988 (makefile
->disableraw
? " -r" : ""),
1989 (makefile
->disabletext
? " -x" : ""),
1990 (makefile
->disablexer
? " -X" : ""),
1991 (makefile
->disablejson
? " -j" : ""),
1992 (makefile
->forcexerinasn
? " -a" : ""),
1993 (makefile
->defaultasomit
? " -d" : ""),
1994 (makefile
->gccmsgformat
? " -g" : ""),
1995 (makefile
->linenumbersonlymsg
? " -i" : ""),
1996 (makefile
->includesourceinfo
? " -l" : ""),
1997 /*(makefile->addsourcelineinfo ? " -L" : ""),*/
1998 (makefile
->suppresswarnings
? " -w" : ""),
1999 (makefile
->outparamboundness
? " -Y" : ""),
2000 (makefile
->tcov_file_name
? makefile
->tcov_file_name
: ""),
2001 /* end of COMPILER FLAGS */
2002 (makefile
->use_runtime_2
? "-rt2" : ""), /* TTCN3_LIB */
2003 (makefile
->single_mode
? "" : "-parallel"),
2004 (makefile
->dynamic
? "-dynamic": "")
2006 if (!makefile
->gnu_make
) {
2007 fputs("# Note: you can set any directory except ./archive\n", fp
);
2009 fputs("ARCHIVE_DIR = backup\n\n"
2011 "# You may change these variables. Add your files if necessary...\n"
2013 "# TTCN-3 modules of this project:\n"
2014 "TTCN3_MODULES =", fp
);
2015 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2016 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2017 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2018 /* If the file is in the current directory or
2019 * is not in the current directory but central directory is not used,
2020 * it goes into TTCN3_MODULES */
2021 print_file_name(fp
, module
);
2023 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_MODULES");
2024 if (makefile
->preprocess
) {
2026 "# TTCN-3 modules to preprocess:\n"
2027 "TTCN3_PP_MODULES =", fp
);
2028 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2029 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2030 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2031 print_file_name(fp
, module
);
2033 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_PP_MODULES");
2035 if (makefile
->central_storage
) {
2037 "# TTCN-3 modules used from central project(s):\n"
2038 "BASE_TTCN3_MODULES =", fp
);
2039 if (!makefile
->linkingStrategy
) {
2040 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2041 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2042 /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
2043 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
2045 if (makefile
->preprocess
) {
2047 "# TTCN-3 modules to preprocess used from central project(s):\n"
2048 "BASE_TTCN3_PP_MODULES =", fp
);
2049 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2050 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2051 if (module
->dir_name
!= NULL
&& !isTtcnPPFileInLibrary(module
->file_name
))
2052 print_file_name(fp
, module
);
2056 else { // new linking strategy
2057 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2058 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2059 /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
2060 if (module
->dir_name
!= NULL
&& !isTtcn3ModuleInLibrary(module
->module_name
))
2061 print_file_name(fp
, module
);
2064 "# TTCN-3 library linked modules used from central project(s):\n"
2065 "BASE2_TTCN3_MODULES =", fp
);
2066 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2067 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2068 /* Central storage used AND file is not in the current directory => it goes into BASE_TTCN3_MODULES */
2069 if (module
->dir_name
!= NULL
&& isTtcn3ModuleInLibrary(module
->module_name
))
2070 print_file_name(fp
, module
);
2072 if (makefile
->preprocess
) {
2074 "# TTCN-3 modules to preprocess used from central project(s):\n"
2075 "BASE_TTCN3_PP_MODULES =", fp
);
2076 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2077 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2078 if (module
->dir_name
!= NULL
&& !isTtcnPPFileInLibrary(module
->file_name
))
2079 print_file_name(fp
, module
);
2082 "# TTCN-3 library linked modules to preprocess used from central project(s):\n"
2083 "BASE2_TTCN3_PP_MODULES =", fp
);
2084 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2085 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2086 if (module
->dir_name
!= NULL
&& isTtcnPPFileInLibrary(module
->file_name
))
2087 print_file_name(fp
, module
);
2092 if (makefile
->preprocess
) {
2094 "# Files to include in TTCN-3 preprocessed modules:\n"
2095 "TTCN3_INCLUDES =", fp
);
2096 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
2097 fprintf(fp
, " %s", makefile
->TTCN3IncludeFiles
[i
]);
2098 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_INCLUDES");
2101 "# ASN.1 modules of this project:\n"
2102 "ASN1_MODULES =", fp
);
2103 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2104 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2105 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2106 print_file_name(fp
, module
);
2108 fprint_extra_targets(fp
, makefile
->target_placement_list
, "ASN1_MODULES");
2109 if (makefile
->central_storage
) {
2111 "# ASN.1 modules used from central project(s):\n"
2112 "BASE_ASN1_MODULES =", fp
);
2113 if (!makefile
->linkingStrategy
) {
2114 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2115 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2116 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
2120 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2121 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2122 if (module
->dir_name
!= NULL
&& !isAsn1ModuleInLibrary(module
->module_name
))
2123 print_file_name(fp
, module
);
2126 "# ASN.1 library linked modules used from central project(s):\n"
2127 "BASE2_ASN1_MODULES =", fp
);
2128 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2129 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2130 if (module
->dir_name
!= NULL
&& isAsn1ModuleInLibrary(module
->module_name
))
2131 print_file_name(fp
, module
);
2135 if (makefile
->preprocess
) {
2137 "# TTCN-3 source files generated by the C preprocessor:\n"
2138 "PREPROCESSED_TTCN3_MODULES =", fp
);
2139 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2140 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2141 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2142 print_preprocessed_file_name(fp
, module
);
2144 if (makefile
->central_storage
) {
2146 "# TTCN-3 files generated by the CPP used from central project(s):\n"
2147 "BASE_PREPROCESSED_TTCN3_MODULES =", fp
);
2148 if (!makefile
->linkingStrategy
) {
2149 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2150 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2151 if (module
->dir_name
!= NULL
)
2152 print_preprocessed_file_name(fp
, module
);
2155 else { // new linking strategy
2156 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2157 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2158 if (module
->dir_name
!= NULL
&& !isTtcnPPFileInLibrary(module
->file_name
))
2159 print_preprocessed_file_name(fp
, module
);
2162 "# TTCN-3 library linked files generated by the CPP used from central project(s):\n"
2163 "BASE2_PREPROCESSED_TTCN3_MODULES =", fp
);
2164 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2165 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2166 if (module
->dir_name
!= NULL
&& isTtcnPPFileInLibrary(module
->file_name
))
2167 print_preprocessed_file_name(fp
, module
);
2173 "# C++ source & header files generated from the TTCN-3 & ASN.1 "
2176 "GENERATED_SOURCES =", fp
);
2177 if (makefile
->gnu_make
&& makefile
->TTCN3ModulesRegular
) {
2178 fputs(" $(TTCN3_MODULES:.ttcn=.cc)", fp
);
2179 if (makefile
->code_splitting_mode
) {
2180 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2181 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2182 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2183 print_splitted_file_names(fp
, makefile
, module
);
2186 if (makefile
->preprocess
) {
2187 fputs(" $(TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2188 if (makefile
->code_splitting_mode
) {
2189 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2190 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2191 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2192 print_splitted_file_names(fp
, makefile
, module
);
2197 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2198 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2199 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2200 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2201 if (makefile
->code_splitting_mode
)
2202 print_splitted_file_names(fp
, makefile
, module
);
2205 if (makefile
->preprocess
) {
2206 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2207 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2208 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2209 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2210 if (makefile
->code_splitting_mode
)
2211 print_splitted_file_names(fp
, makefile
, module
);
2216 if (makefile
->gnu_make
&& makefile
->ASN1ModulesRegular
) {
2217 fputs(" $(ASN1_MODULES:.asn=.cc)", fp
);
2218 if (makefile
->code_splitting_mode
) {
2219 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2220 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2221 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2222 print_splitted_file_names(fp
, makefile
, module
);
2227 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2228 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2229 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2230 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2231 if (makefile
->code_splitting_mode
)
2232 print_splitted_file_names(fp
, makefile
, module
);
2237 fputs("\nGENERATED_HEADERS =", fp
);
2238 if (makefile
->gnu_make
) {
2239 fputs(" $(GENERATED_SOURCES:.cc=.hh)", fp
);
2242 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2243 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2244 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2245 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2247 if (makefile
->preprocess
) {
2248 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2249 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2250 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2251 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2254 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2255 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2256 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2257 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2260 if (makefile
->central_storage
) {
2262 "# C++ source & header files generated from the TTCN-3 & ASN.1 "
2264 "# central project(s):\n"
2265 "BASE_GENERATED_SOURCES =", fp
);
2266 if (makefile
->gnu_make
&& makefile
->BaseTTCN3ModulesRegular
) {
2267 fputs(" $(BASE_TTCN3_MODULES:.ttcn=.cc)", fp
);
2268 if (makefile
->code_splitting_mode
) {
2269 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2270 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2271 if (module
->dir_name
!= NULL
) {
2272 print_splitted_file_names(fp
, makefile
, module
);
2276 if (makefile
->preprocess
) {
2277 fputs(" $(BASE_TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2278 if (makefile
->code_splitting_mode
) {
2279 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2280 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2281 if (module
->dir_name
!= NULL
) {
2282 print_splitted_file_names(fp
, makefile
, module
);
2288 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2289 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2290 if (module
->dir_name
!= NULL
) {
2291 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2292 if (makefile
->code_splitting_mode
)
2293 print_splitted_file_names(fp
, makefile
, module
);
2296 if (makefile
->preprocess
) {
2297 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2298 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2299 if (module
->dir_name
!= NULL
) {
2300 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2301 if (makefile
->code_splitting_mode
)
2302 print_splitted_file_names(fp
, makefile
, module
);
2307 if (makefile
->gnu_make
&& makefile
->BaseASN1ModulesRegular
) {
2308 fputs(" $(BASE_ASN1_MODULES:.asn=.cc)", fp
);
2309 if (makefile
->code_splitting_mode
) {
2310 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2311 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2312 if (module
->dir_name
!= NULL
) {
2313 print_splitted_file_names(fp
, makefile
, module
);
2318 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2319 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2320 if (module
->dir_name
!= NULL
) {
2321 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2322 if (makefile
->code_splitting_mode
)
2323 print_splitted_file_names(fp
, makefile
, module
);
2327 fputs("\nBASE_GENERATED_HEADERS =", fp
);
2328 if (makefile
->gnu_make
) {
2329 fputs(" $(BASE_GENERATED_SOURCES:.cc=.hh)", fp
);
2331 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2332 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2333 if (module
->dir_name
!= NULL
)
2334 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2336 if (makefile
->preprocess
) {
2337 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2338 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2339 if (module
->dir_name
!= NULL
)
2340 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2343 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2344 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2345 if (module
->dir_name
!= NULL
)
2346 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2351 if (makefile
->linkingStrategy
) {
2353 "# C++ source & header files generated from the TTCN-3 "
2354 " library linked modules of\n"
2355 "# central project(s):\n"
2356 "BASE2_GENERATED_SOURCES =", fp
);
2357 if (makefile
->gnu_make
&& makefile
->BaseTTCN3ModulesRegular
) {
2358 fputs(" $(BASE2_TTCN3_MODULES:.ttcn=.cc)", fp
);
2359 fputs(" $(BASE2_ASN1_MODULES:.asn=.cc)", fp
);
2360 if (makefile
->preprocess
)
2361 fputs(" $(BASE2_TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2364 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2365 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2366 if (module
->dir_name
!= NULL
&& isTtcn3ModuleInLibrary(module
->module_name
)) {
2367 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2370 if (makefile
->preprocess
) {
2371 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2372 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2373 if (module
->dir_name
!= NULL
&& isTtcnPPFileInLibrary(module
->file_name
)) {
2374 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2380 fputs("\nBASE2_GENERATED_HEADERS =", fp
);
2381 if (makefile
->gnu_make
) {
2382 fputs(" $(BASE2_GENERATED_SOURCES:.cc=.hh)", fp
);
2385 ERROR("the usage of 'Z' flag requires GNU make");
2389 "# C/C++ Source & header files of Test Ports, external functions "
2391 "# other modules:\n"
2392 "USER_SOURCES =", fp
);
2393 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2394 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2395 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2396 print_source_name(fp
, user
);
2398 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_SOURCES");
2399 fputs("\nUSER_HEADERS =", fp
);
2400 if (makefile
->gnu_make
&& makefile
->UserHeadersRegular
) {
2401 fputs(" $(USER_SOURCES:.cc=.hh)", fp
);
2403 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2404 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2405 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2406 print_header_name(fp
, user
);
2409 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_HEADERS");
2410 if (makefile
->central_storage
) {
2412 "# C/C++ Source & header files of Test Ports, external functions "
2414 "# other modules used from central project(s):\n"
2415 "BASE_USER_SOURCES =", fp
);
2416 if (!makefile
->linkingStrategy
) {
2417 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2418 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2419 if (user
->dir_name
!= NULL
) {
2420 print_source_name(fp
, user
);
2423 fputs("\nBASE_USER_HEADERS =", fp
);
2424 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2425 fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp
);
2428 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2429 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2430 if (user
->dir_name
!= NULL
)
2431 print_header_name(fp
, user
);
2436 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2437 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2438 if (user
->dir_name
!= NULL
&& !isSourceFileInLibrary(user
->source_name
)) {
2439 print_source_name(fp
, user
);
2442 fputs("\nBASE_USER_HEADERS =", fp
);
2443 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2444 fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp
);
2447 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2448 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2449 if (user
->dir_name
!= NULL
&& !isHeaderFileInLibrary(user
->header_name
))
2450 print_header_name(fp
, user
);
2455 "# C/C++ Source & header files of Test Ports, external functions "
2457 "# other modules used from library linked central project(s):\n"
2458 "BASE2_USER_SOURCES =", fp
);
2459 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2460 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2461 if (user
->dir_name
!= NULL
&& isSourceFileInLibrary(user
->source_name
)) {
2462 print_source_name(fp
, user
);
2465 fputs("\nBASE2_USER_HEADERS =", fp
);
2466 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2467 fputs(" $(BASE2_USER_SOURCES:.cc=.hh)", fp
);
2470 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2471 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2472 if (user
->dir_name
!= NULL
&& isHeaderFileInLibrary(user
->header_name
))
2473 print_header_name(fp
, user
);
2478 if (makefile
->dynamic
) {
2480 "# Shared object files of this project:\n"
2481 "SHARED_OBJECTS =", fp
);
2482 if (makefile
->gnu_make
) {
2483 fputs(" $(GENERATED_SOURCES:.cc=.so)", fp
);
2485 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2486 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2487 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2488 print_generated_file_name(fp
, module
, FALSE
, ".so");
2489 if (makefile
->code_splitting_mode
!= NULL
)
2490 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2491 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2492 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2493 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2494 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2495 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2499 if (makefile
->preprocess
) {
2500 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2501 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2502 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2503 print_generated_file_name(fp
, module
, FALSE
, ".so");
2504 if (makefile
->code_splitting_mode
!= NULL
)
2505 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2506 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2507 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2508 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2509 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2510 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2515 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2516 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2517 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2518 print_generated_file_name(fp
, module
, FALSE
, ".so");
2519 if (makefile
->code_splitting_mode
!= NULL
)
2520 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2521 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2522 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2523 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2524 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2525 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2530 if (makefile
->gnu_make
&& makefile
->UserSourcesRegular
) {
2531 fputs(" $(USER_SOURCES:.cc=.so)", fp
);
2533 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2534 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2535 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2536 print_shared_object_name(fp
, user
);
2542 "# Object files of this project that are needed for the executable "
2544 "OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)\n\n" /* never := */
2545 "GENERATED_OBJECTS =", fp
);
2546 if (makefile
->gnu_make
) {
2547 fputs(" $(GENERATED_SOURCES:.cc=.o)", fp
);
2549 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2550 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2551 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2552 print_generated_file_name(fp
, module
, FALSE
, ".o");
2553 if (makefile
->code_splitting_mode
!= NULL
)
2554 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2555 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2556 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2557 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2558 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2559 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2563 if (makefile
->preprocess
) {
2564 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2565 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2566 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2567 print_generated_file_name(fp
, module
, FALSE
, ".o");
2568 if (makefile
->code_splitting_mode
!= NULL
)
2569 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2570 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2571 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2572 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2573 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2574 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2579 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2580 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2581 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2582 print_generated_file_name(fp
, module
, FALSE
, ".o");
2583 if (makefile
->code_splitting_mode
!= NULL
)
2584 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2585 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2586 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2587 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2588 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2589 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2595 fputs("\n\nUSER_OBJECTS =", fp
);
2596 if (makefile
->gnu_make
&& makefile
->UserSourcesRegular
) {
2597 fputs(" $(USER_SOURCES:.cc=.o)", fp
);
2599 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2600 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2601 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2602 print_object_name(fp
, user
);
2605 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_OBJECTS");
2607 if (makefile
->gcc_dep
) {
2608 /* GNU Make processes included makefiles in reverse order. By putting
2609 * user sources first, their .d will be generated last, after the
2610 * GENERATED_SOURCES (and GENERATED_HEADERS) have been created.
2611 * This avoid spurious errors during incremental dependency generation */
2612 fputs("\n\nDEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d)", fp
);
2615 if (makefile
->central_storage
) {
2616 if (makefile
->dynamic
) {
2618 "# Shared object files of central project(s):\n"
2619 "BASE_SHARED_OBJECTS =", fp
);
2620 if (!makefile
->linkingStrategy
) {
2621 if (makefile
->gnu_make
) {
2622 fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp
);
2625 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2626 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2627 if (module
->dir_name
!= NULL
)
2628 print_generated_file_name(fp
, module
, TRUE
, ".so");
2630 if (makefile
->preprocess
) {
2631 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2632 const struct module_struct
*module
=
2633 makefile
->TTCN3PPModules
+ i
;
2634 if (module
->dir_name
!= NULL
)
2635 print_generated_file_name(fp
, module
, TRUE
, ".so");
2638 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2639 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2640 if (module
->dir_name
!= NULL
)
2641 print_generated_file_name(fp
, module
, TRUE
, ".so");
2644 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2645 fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp
);
2648 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2649 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2650 if (user
->dir_name
!= NULL
)
2651 print_shared_object_name(fp
, user
);
2655 else { // new linkingStrategy
2656 if (makefile
->gnu_make
) {
2657 fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp
);
2660 ERROR("the usage of 'Z' flag requires GNU make");
2662 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2663 fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp
);
2666 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2667 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2668 if (user
->dir_name
!= NULL
&& !isSourceFileInLibrary(user
->source_name
))
2669 print_shared_object_name(fp
, user
);
2675 "# Object files of central project(s) that are needed for the "
2676 "executable test suite:\n"
2677 "BASE_OBJECTS =", fp
);
2678 if (!makefile
->linkingStrategy
) {
2679 if (makefile
->gnu_make
) {
2680 fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp
);
2683 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2684 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2685 if (module
->dir_name
!= NULL
)
2686 print_generated_file_name(fp
, module
, TRUE
, ".o");
2688 if (makefile
->preprocess
) {
2689 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2690 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2691 if (module
->dir_name
!= NULL
)
2692 print_generated_file_name(fp
, module
, TRUE
, ".o");
2695 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2696 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2697 if (module
->dir_name
!= NULL
)
2698 print_generated_file_name(fp
, module
, TRUE
, ".o");
2701 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2702 fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp
);
2705 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2706 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2707 if (user
->dir_name
!= NULL
)
2708 print_object_name(fp
, user
);
2712 else { // new linkingStrategy
2713 if (makefile
->gnu_make
) {
2714 fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp
);
2717 ERROR("the usage of 'Z' flag requires GNU make");
2719 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2720 fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp
);
2723 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2724 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2725 if (user
->dir_name
!= NULL
&& !isSourceFileInLibrary(user
->source_name
))
2726 print_object_name(fp
, user
);
2731 if (makefile
->linkingStrategy
) {
2733 "# Object files of library linked central project(s) that are needed for the "
2734 "executable test suite:\n"
2735 "BASE2_OBJECTS =", fp
);
2736 if (makefile
->gnu_make
) {
2737 if (makefile
->dynamic
)
2738 fputs(" $(BASE2_GENERATED_SOURCES:.cc=.so)", fp
);
2740 fputs(" $(BASE2_GENERATED_SOURCES:.cc=.o)", fp
);
2742 else ERROR("the usage of 'Z' flag requires GNU make");
2744 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2745 if (makefile
->dynamic
)
2746 fputs(" $(BASE2_USER_SOURCES:.cc=.so)", fp
);
2748 fputs(" $(BASE2_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
&& isSourceFileInLibrary(user
->source_name
)) {
2754 if (makefile
->dynamic
)
2755 print_shared_object_name(fp
, user
);
2757 print_object_name(fp
, user
);
2761 if (makefile
->hierarchical
) {
2763 "#Libraries of referenced project(s) that are needed for the "
2764 "executable or library target:\n"
2765 "BASE2_LIBRARY =", fp
);
2766 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
2767 struct string2_list
* act_elem
= head
;
2769 if (act_elem
->str2
) {
2771 fprintf(fp
, "%s/lib%s.%s", act_elem
->str1
, act_elem
->str2
,
2772 isDynamicLibrary(act_elem
->str2
) ? "so" : "a");
2774 act_elem
= act_elem
->next
;
2776 free_string2_list(head
);
2781 "# Other files of the project (Makefile, configuration files, etc.)\n"
2782 "# that will be added to the archived source files:\n"
2783 "OTHER_FILES =", fp
);
2784 for (i
= 0; i
< makefile
->nOtherFiles
; i
++)
2785 fprintf(fp
, " %s", makefile
->OtherFiles
[i
]);
2786 fprint_extra_targets(fp
, makefile
->target_placement_list
, "OTHER_FILES");
2788 if (makefile
->ets_name
) {
2789 const char *ets_suffix
= NULL
;
2790 /* EXECUTABLE variable */
2792 "# The name of the executable test suite:\n"
2793 "EXECUTABLE = %s", makefile
->ets_name
);
2796 /* add the .exe suffix unless it is already present */
2797 ets_suffix
= get_suffix(makefile
->ets_name
);
2798 if (ets_suffix
== NULL
|| strcmp(ets_suffix
, "exe"))
2803 if (makefile
->linkingStrategy
) {
2805 fputs("DYNAMIC_LIBRARY = lib$(EXECUTABLE).so\n", fp
);
2806 fputs("STATIC_LIBRARY = lib$(EXECUTABLE).a\n", fp
);
2808 char* name_prefix
= cut_suffix(makefile
->ets_name
);
2809 fprintf(fp
, "DYNAMIC_LIBRARY = lib%s.so\n", name_prefix
);
2810 fprintf(fp
, "STATIC_LIBRARY = lib%s.a\n", name_prefix
);
2814 /* LIBRARY variable */
2815 ets_suffix
= get_suffix(makefile
->ets_name
);
2816 if (ets_suffix
!= NULL
&& !strcmp(ets_suffix
, "exe")) {
2817 char* name_prefix
= cut_suffix(makefile
->ets_name
);
2818 fprintf(fp
, "\n\nLIBRARY = %s%s%s\n", "lib", name_prefix
? name_prefix
: "library",
2819 makefile
->dynamic
? ".so" : ".a");
2824 fprintf(fp
, "\n\nLIBRARY = lib$(EXECUTABLE)%s\n",
2825 makefile
->dynamic
? ".so" : ".a");
2827 fprintf(fp
, "\n\nLIBRARY = lib%s%s\n",
2828 makefile
->ets_name
, makefile
->dynamic
? ".so" : ".a");
2834 "# The name of the executable test suite:\n"
2838 if (!makefile
->linkingStrategy
|| !buildObjects(makefile
->project_name
, add_refd_prjs
)) {
2840 "TARGET = $(%s)", makefile
->library
? "LIBRARY" : "EXECUTABLE");
2843 if (makefile
->dynamic
) {
2845 "TARGET = $(SHARED_OBJECTS)", fp
);
2849 "TARGET = $(OBJECTS)", fp
);
2854 "# Do not modify these unless you know what you are doing...\n"
2855 "# Platform specific additional libraries:\n"
2858 fputs("SOLARIS_LIBS = -lsocket -lnsl -lxml2", fp
);
2860 fputs(" -lresolv", fp
);
2862 if (makefile
->solspeclibraries
) {
2863 struct string_list
* act_elem
= makefile
->solspeclibraries
;
2865 if (act_elem
->str
) {
2866 fprintf(fp
, " -l%s", act_elem
->str
);
2868 act_elem
= act_elem
->next
;
2873 fputs("SOLARIS8_LIBS = -lsocket -lnsl -lxml2", fp
);
2875 fputs(" -lresolv", fp
);
2877 if (makefile
->sol8speclibraries
) {
2878 struct string_list
* act_elem
= makefile
->sol8speclibraries
;
2880 if (act_elem
->str
) {
2881 fprintf(fp
, " -l%s", act_elem
->str
);
2883 act_elem
= act_elem
->next
;
2888 fputs("LINUX_LIBS = -lxml2", fp
);
2890 fputs(" -lpthread -lrt", fp
);
2892 if (makefile
->linuxspeclibraries
) {
2893 struct string_list
* act_elem
= makefile
->linuxspeclibraries
;
2895 if (act_elem
->str
) {
2896 fprintf(fp
, " -l%s", act_elem
->str
);
2898 act_elem
= act_elem
->next
;
2903 fputs("FREEBSD_LIBS = -lxml2", fp
);
2904 if (makefile
->freebsdspeclibraries
) {
2905 struct string_list
* act_elem
= makefile
->freebsdspeclibraries
;
2907 if (act_elem
->str
) {
2908 fprintf(fp
, " -l%s", act_elem
->str
);
2910 act_elem
= act_elem
->next
;
2915 fputs("WIN32_LIBS = -lxml2", fp
);
2916 if (makefile
->win32speclibraries
) {
2917 struct string_list
* act_elem
= makefile
->win32speclibraries
;
2919 if (act_elem
->str
) {
2920 fprintf(fp
, " -l%s", act_elem
->str
);
2922 act_elem
= act_elem
->next
;
2928 "# Rules for building the executable...\n"
2930 fprintf(fp
, "all:%s $(TARGET) ;\n\n", add_refd_prjs
?" referenced-all":"");
2932 if (makefile
->dynamic
) {
2933 fprintf(fp
, "shared_objects:%s $(SHARED_OBJECTS) ;\n\n", add_refd_prjs
?" referenced-shared_objects":"");
2937 "executable:%s $(EXECUTABLE) ;\n\n"
2938 "library:%s $(LIBRARY) ;\n\n"
2939 "objects:%s $(OBJECTS) compile;\n\n", add_refd_prjs
?" referenced-executable":"", add_refd_prjs
?" referenced-library":"", add_refd_prjs
?" referenced-objects":"");
2941 /* target $(EXECUTABLE) */
2942 if (makefile
->dynamic
&& makefile
->library
) {
2943 /* There is no need to create the .so for all the source files */
2944 fputs("$(EXECUTABLE): $(LIBRARY)\n"
2945 "\tif $(CXX) $(LDFLAGS) -o $@ $(LIBRARY)", fp
);
2948 fprintf(fp
, "$(EXECUTABLE): %s", makefile
->dynamic
? "$(SHARED_OBJECTS)" : "$(OBJECTS)");
2949 if (!makefile
->linkingStrategy
) { // use the old linking method
2950 if (makefile
->central_storage
) {
2951 if (makefile
->dynamic
) {
2952 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
2954 fputs(" $(BASE_OBJECTS)", fp
);
2959 if (!makefile
->library
) {
2960 if (makefile
->dynamic
) {
2961 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
2964 fputs(" $(BASE_OBJECTS)", fp
);
2966 if (makefile
->hierarchical
) {
2967 fputs(" $(BASE2_LIBRARY)", fp
);
2972 "\tif $(CXX) $(LDFLAGS) -o $@ %s",
2973 #if defined (SOLARIS) || defined (SOLARIS8)
2976 makefile
->dynamic
? "-Wl,--no-as-needed " : ""); /* start writing the link step */
2978 if (makefile
->gnu_make
) fputs("$^", fp
);
2980 if (makefile
->dynamic
) {
2981 fputs("$(SHARED_OBJECTS)", fp
);
2982 if (makefile
->central_storage
)
2983 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
2986 fputs("$(OBJECTS)", fp
);
2987 if (makefile
->central_storage
)
2988 fputs(" $(BASE_OBJECTS)", fp
);
2993 if (makefile
->additionalObjects
) {
2994 struct string_list
* act_elem
= makefile
->additionalObjects
;
2996 if (act_elem
->str
) {
2997 fprintf(fp
, " %s", act_elem
->str
);
2999 act_elem
= act_elem
->next
;
3004 "\t-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB)"
3006 "\t-L$(OPENSSL_DIR)/lib -lcrypto");
3007 if (!makefile
->linkingStrategy
) {
3008 if (makefile
->linkerlibraries
) {
3009 struct string_list
* act_elem
= makefile
->linkerlibraries
;
3011 if (act_elem
->str
) {
3012 fprintf(fp
, " -l%s", act_elem
->str
);
3014 act_elem
= act_elem
->next
;
3017 if (makefile
->linkerlibsearchpath
) {
3018 struct string_list
* act_elem
= makefile
->linkerlibsearchpath
;
3020 if (act_elem
->str
) {
3021 fprintf(fp
, " -L%s", act_elem
->str
);
3023 act_elem
= act_elem
->next
;
3027 "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
3028 "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
3030 else { // new linking strategy
3031 fputs (" \\\n", fp
);
3032 if (makefile
->linkerlibraries
&& !makefile
->library
) {
3033 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
3034 struct string2_list
* act_elem
= head
;
3036 if (act_elem
->str1
&& act_elem
->str2
) {
3037 fprintf(fp
, "\t-L%s -Wl,-rpath=%s -l%s \\\n", act_elem
->str1
, act_elem
->str1
, act_elem
->str2
);
3039 act_elem
= act_elem
->next
;
3041 free_string2_list(head
);
3043 struct string_list
* act_head
= getExternalLibPathes(makefile
->project_name
);
3044 struct string_list
* act_ext_elem
= act_head
;
3045 while (act_ext_elem
) {
3046 if (act_ext_elem
->str
) {
3047 fprintf(fp
, "\t-L%s \\\n", act_ext_elem
->str
);
3049 act_ext_elem
= act_ext_elem
->next
;
3051 free_string_list(act_head
);
3052 act_head
= getExternalLibs(makefile
->project_name
);
3053 act_ext_elem
= act_head
;
3054 while (act_ext_elem
) {
3055 if (act_ext_elem
->str
) {
3056 fprintf(fp
, "\t-l%s \\\n", act_ext_elem
->str
);
3058 act_ext_elem
= act_ext_elem
->next
;
3060 free_string_list(act_head
);
3063 "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
3064 "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
3066 /* If the compiler will not be run because there are no TTCN(PP) or ASN.1
3067 * files, create the "compile" marker file which is checked by the
3068 * superior makefile if using this project as central storage */
3069 if (!run_compiler
) fputs("\ttouch compile\n", fp
);
3070 /* End of target $(EXECUTABLE) */
3072 /* target $(LIBRARY) */
3073 if (makefile
->dynamic
) {
3075 "$(LIBRARY): $(OBJECTS)%s\n"
3076 "\t$(CXX) -shared -o $@ $(OBJECTS)",
3077 makefile
->hierarchical
? " $(BASE2_LIBRARY)" : "");
3078 if (makefile
->central_storage
&& !makefile
->linkingStrategy
) {
3079 fputs(" $(BASE_SHARED_OBJECTS) ;\n"
3080 "\tln -s $@ $(subst lib, ,$@) > /dev/null 2>&1 ;", fp
);
3082 if (makefile
->linkingStrategy
) {
3083 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
3084 struct string2_list
* act_elem
= head
;
3085 // If the project is Executable on Top Level the linker can link the *.a and *.so together
3086 while (act_elem
&& !isTopLevelExecutable(makefile
->project_name
)) {
3087 if (act_elem
->str1
&& act_elem
->str2
&& isDynamicLibrary(act_elem
->str2
)) {
3089 fprintf(fp
, "\t-L%s -Wl,-rpath=%s -l%s", act_elem
->str1
, act_elem
->str1
, act_elem
->str2
);
3092 const char* mainLibName
= getLibFromProject(makefile
->project_name
);
3093 ERROR("Library archive 'lib%s.a' cannot be linked to dynamic library 'lib%s.so' "
3095 act_elem
->str2
, mainLibName
? mainLibName
: "", makefile
->project_name
);
3096 free_string2_list(head
);
3099 act_elem
= act_elem
->next
;
3101 free_string2_list(head
);
3102 struct string_list
* act_head
= getExternalLibPathes(makefile
->project_name
);
3103 struct string_list
* act_ext_elem
= act_head
;
3104 while (act_ext_elem
) {
3105 if (act_ext_elem
->str
) {
3107 fprintf(fp
, "\t-L%s", act_ext_elem
->str
);
3109 act_ext_elem
= act_ext_elem
->next
;
3111 free_string_list(act_head
);
3112 act_head
= getExternalLibs(makefile
->project_name
);
3113 act_ext_elem
= act_head
;
3114 while (act_ext_elem
) {
3115 if (act_ext_elem
->str
) {
3117 fprintf(fp
, "\t-l%s", act_ext_elem
->str
);
3119 act_ext_elem
= act_ext_elem
->next
;
3121 free_string_list(act_head
);
3124 else { // static linking
3126 "$(LIBRARY): $(OBJECTS)%s\n"
3127 "\t$(AR) -r%s $(ARFLAGS) $(LIBRARY) $(OBJECTS)",
3128 makefile
->hierarchical
? " $(BASE2_LIBRARY)" : "",
3129 makefile
->linkingStrategy
? "cT" : "");
3130 if (makefile
->central_storage
&& !makefile
->linkingStrategy
) {
3131 fputs(" $(BASE_OBJECTS)", fp
);
3133 if (makefile
->linkingStrategy
) {
3134 if ( makefile
->library
) {
3135 struct string2_list
* head
= getLinkerLibs(makefile
->project_name
);
3136 struct string2_list
* act_elem
= head
;
3138 if (act_elem
->str2
&& !isDynamicLibrary(act_elem
->str2
)) {
3140 fprintf(fp
, "\t%s/lib%s.a", act_elem
->str1
, act_elem
->str2
);
3143 const char* mainLibName
= getLibFromProject(makefile
->project_name
);
3144 if (act_elem
->str2
) {
3145 ERROR("Dynamic library 'lib%s.so' cannot be linked to static library 'lib%s.a' "
3147 act_elem
->str2
, mainLibName
? mainLibName
: "", makefile
->project_name
);
3151 struct string_list
* ext_libs
= getExternalLibs(makefile
->project_name
);
3152 if (ext_libs
&& ext_libs
->str
) {
3153 ERROR("Third party dynamic library '%s' cannot be linked to static library 'lib%s.a' "
3154 "in project '%s' ", ext_libs
->str
,
3155 mainLibName
? mainLibName
: "", makefile
->project_name
);
3156 free_string_list(ext_libs
);
3159 free_string_list(ext_libs
);
3162 act_elem
= act_elem
->next
;
3164 free_string2_list(head
);
3166 struct string_list
* act_head
= getExternalLibs(makefile
->project_name
);
3167 struct string_list
* act_ext_elem
= act_head
;
3168 while (act_ext_elem
) {
3169 if (act_ext_elem
->str
&& hasExternalLibrary(act_ext_elem
->str
, makefile
->project_name
)) {
3171 fprintf(fp
, "\tlib%s.a", act_ext_elem
->str
);
3172 ERROR("linking static 3d party or sytem library 'lib%s.a' to "
3173 "project library 'lib%s.a' is not supported ",
3174 act_ext_elem
->str
, makefile
->ets_name
);
3177 act_ext_elem
= act_ext_elem
->next
;
3179 free_string_list(act_head
);
3183 fputs("\n\n.cc.o .c.o:\n"
3184 "\t$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<\n\n", fp
);
3186 if (makefile
->gcc_dep
) {
3187 fputs(".cc.d .c.d:\n"
3188 "\t@echo Creating dependency file for '$<'; set -e; \\\n"
3189 "\t$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \\\n"
3190 "\t| sed 's/\\($*\\)\\.o[ :]*/\\1.o $@ : /g' > $@; \\\n"
3191 "\t[ -s $@ ] || rm -f $@\n\n", fp
);
3192 /* "set -e" causes bash to exit the script if any statement
3193 * returns nonzero (failure).
3194 * The sed line transforms the first line of the dependency from
3195 * "x.o: x.cc" to "x.o x.d: x.cc", making the dependency file depend
3196 * on the source and headers.
3197 * [ -s x.d ] checks that the generated dependency is not empty;
3198 * otherwise it gets deleted.
3202 if (makefile
->dynamic
) {
3204 "\t$(CXX) -shared -o $@ $<\n\n", fp
);
3207 if (makefile
->preprocess
) {
3208 fputs("%.ttcn: %.ttcnpp $(TTCN3_INCLUDES)\n"
3209 "\t$(CPP) -x c -nostdinc $(CPPFLAGS_TTCN3) $< $@\n\n"
3210 "preprocess: $(PREPROCESSED_TTCN3_MODULES) ;\n\n", fp
);
3213 if (makefile
->central_storage
) {
3214 boolean is_first
= TRUE
;
3215 fprintf(fp
, "$(GENERATED_SOURCES) $(GENERATED_HEADERS):%s compile-all compile ",
3216 makefile
->hierarchical
? " update" : "");
3218 if (add_refd_prjs
) fputs("referenced-dep", fp
);
3219 /* These extra compile dependencies for the generated .cc are here to
3220 * check if all the referenced projects are up to date.
3221 * If the referenced projects are built too then they are not needed
3222 * (and cause problems as the included .d depends on the .cc).
3224 if (!add_refd_prjs
) for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
3225 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
3226 if (base_dir
->has_modules
) {
3232 fprintf(fp
, "%s/compile", base_dir
->dir_name
);
3235 if (makefile
->preprocess
) {
3237 "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
3239 "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3240 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
3242 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n"
3243 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ",
3244 rm_command
, add_refd_prjs
?" referenced-check":"",
3245 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3246 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3247 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3248 if (makefile
->gnu_make
) {
3249 if (add_refd_prjs
) // referenced-check cannot be compiled it is not a ttcn modul
3250 fprintf(fp
, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3251 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
3253 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n",
3254 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3255 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3256 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3262 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
3263 "\t$(PREPROCESSED_TTCN3_MODULES) "
3264 "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
3265 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp
);
3267 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
3269 "update: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
3270 "\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) $(BASE2_PREPROCESSED_TTCN3_MODULES)\n"
3271 "ifneq ($(wildcard $(GENERATED_SOURCES)), ) \n"
3272 "ifeq ($(wildcard $?), ) \n"
3273 "\ttouch compile-all; \n"
3274 "\ttouch update; \n"
3279 "compile: $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) "
3281 "\t@echo \"compiling \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
3282 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3283 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3284 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) %s\\\n"
3285 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s - $?\n"
3287 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3288 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3289 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES)":"");
3291 "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
3293 "\t$(MAKE) preprocess\n"
3294 "\t@echo \"compiling all \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
3295 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3296 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3297 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) %s"
3299 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3300 "\t- $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)\n"
3301 "\ttouch $@ compile\n\n",
3302 makefile
->linkingStrategy
? "\\\n\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) "
3303 "$(BASE2_PREPROCESSED_TTCN3_MODULES) \n":"\n",
3304 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3305 makefile
->linkingStrategy
? "$(BASE2_PREPROCESSED_TTCN3_MODULES) ":"",
3306 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3310 "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n", rm_command
);
3312 "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3313 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n"
3314 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ",
3315 add_refd_prjs
?" referenced-check":"",
3316 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3317 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3318 if (makefile
->gnu_make
) {
3319 if (add_refd_prjs
) // referenced-check cannot be compiled it is not a ttcn modul
3320 fprintf(fp
, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3321 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\n",
3322 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) ":"",
3323 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) ":"");
3329 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
3330 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp
);
3333 if (makefile
->linkingStrategy
&& makefile
->hierarchical
) {
3335 "update: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
3336 "\t$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES) $(BASE2_PREPROCESSED_TTCN3_MODULES)\n"
3337 "ifneq ($(wildcard $(GENERATED_SOURCES)), ) \n"
3338 "ifeq ($(wildcard $?), ) \n"
3339 "\ttouch compile-all; \n"
3340 "\ttouch update; \n"
3346 "compile: $(TTCN3_MODULES) $(ASN1_MODULES)\n"
3347 "\t@echo \"compiling \"'$(patsubst %%.tpd, %%, $(TPD))';\n"
3348 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3349 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3350 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3353 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) " : "",
3354 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) " : "");
3356 "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES) %s\n",
3357 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) $(BASE2_ASN1_MODULES)" : "");
3358 fputs("\t@echo \"compiling all \"'$(patsubst %.tpd, %, $(TPD))';\n", fp
);
3359 fprintf(fp
,"\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
3360 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n"
3361 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3362 "\t- $(TTCN3_MODULES) $(ASN1_MODULES)\n"
3363 "\ttouch $@ compile\n\n",
3364 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) " : "",
3365 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) " : "");
3367 if (!makefile
->hierarchical
)
3368 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
3369 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
3370 if (base_dir
->has_modules
) {
3372 fprintf(fp
, "%s/compile:", base_dir
->dir_name
);
3373 for (j
= 0; j
< makefile
->nTTCN3Modules
; j
++) {
3374 const struct module_struct
*module
= makefile
->TTCN3Modules
+ j
;
3375 if (module
->dir_name
!= NULL
&&
3376 !strcmp(base_dir
->dir_name
, module
->dir_name
))
3377 print_file_name(fp
, module
);
3379 for (j
= 0; j
< makefile
->nTTCN3PPModules
; j
++) {
3380 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ j
;
3381 if (module
->dir_name
!= NULL
&&
3382 !strcmp(base_dir
->dir_name
, module
->dir_name
))
3383 print_file_name(fp
, module
);
3385 for (j
= 0; j
< makefile
->nASN1Modules
; j
++) {
3386 const struct module_struct
*module
= makefile
->ASN1Modules
+ j
;
3387 if (module
->dir_name
!= NULL
&&
3388 !strcmp(base_dir
->dir_name
, module
->dir_name
))
3389 print_file_name(fp
, module
);
3392 "\t@echo 'Central directory %s is not up-to-date!'\n"
3393 "\t@exit 2\n\n", base_dir
->dir_name
);
3397 else { /* not central storage */
3398 fprintf(fp
, "$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile\n"
3399 "\t@if [ ! -f $@ ]; then %s compile; $(MAKE) compile; fi\n\n"
3400 "check: $(TTCN3_MODULES) ", rm_command
);
3401 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3402 fputs("$(ASN1_MODULES)\n"
3403 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", fp
);
3404 if (makefile
->gnu_make
) fputs("$^", fp
);
3407 "\t$(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)",
3411 "compile: $(TTCN3_MODULES) ", fp
);
3412 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3413 fputs("$(ASN1_MODULES)\n"
3414 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) ", fp
);
3415 if (makefile
->gnu_make
) fputs("$^", fp
);
3418 "\t$(TTCN3_MODULES) ", fp
);
3419 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3420 fputs("$(ASN1_MODULES)", fp
);
3427 if (makefile
->linkingStrategy
) {
3428 fprintf(fp
, "clean:%s\n", (add_refd_prjs
&& !makefile
->hierarchical
) ?
3429 " referenced-clean" : "");
3430 if (makefile
->dynamic
&& (makefile
->central_storage
|| makefile
->linkingStrategy
)) {
3431 fprintf(fp
,"\tfind . -type l -name \"*.so\" -exec unlink {} \\;\n");
3433 fprintf(fp
, "\t%s $(EXECUTABLE) $(DYNAMIC_LIBRARY) $(STATIC_LIBRARY) "
3434 "$(OBJECTS) $(GENERATED_HEADERS) \\\n"
3435 "\t$(GENERATED_SOURCES) ", rm_command
);
3436 if (makefile
->dynamic
) fputs("$(SHARED_OBJECTS) ", fp
);
3437 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3438 fputs("compile", fp
);
3439 if (makefile
->central_storage
) fputs(" compile-all", fp
);
3440 if (makefile
->gcc_dep
) fputs(" $(DEPFILES)", fp
);
3442 "\ttags *.log%s%s\n\n",
3443 add_refd_prjs
?" referenced*":"",
3444 makefile
->hierarchical
? " update":"");
3447 fprintf(fp
, "clean:%s\n"
3448 "\t-%s $(EXECUTABLE) $(LIBRARY) $(OBJECTS) $(GENERATED_HEADERS) \\\n"
3449 "\t$(GENERATED_SOURCES) ", add_refd_prjs
?" referenced-clean":"", rm_command
);
3450 if (makefile
->dynamic
) fputs("$(SHARED_OBJECTS) ", fp
);
3451 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
3452 fputs("compile", fp
);
3453 if (makefile
->central_storage
) fputs(" compile-all", fp
);
3454 if (makefile
->gcc_dep
) fputs(" $(DEPFILES)", fp
);
3457 add_refd_prjs
?" referenced*":"");
3461 if (makefile
->linkingStrategy
&& makefile
->hierarchical
)
3462 fprintf(fp
, "clean-all: %s clean\n", add_refd_prjs
? "referenced-clean-all":"");
3465 fputs("\n\ndep: $(GENERATED_SOURCES) $(USER_SOURCES)",fp
);
3466 if (add_refd_prjs
) {
3467 fprintf(fp
, "\n\t%s referenced-dep", rm_command
);
3469 else fputs(" ;",fp
);
3471 if (makefile
->gcc_dep
) {
3473 "ifeq ($(findstring n,$(MAKEFLAGS)),)\n"
3474 "ifeq ($(filter clean%s check compile archive diag%s,$(MAKECMDGOALS)),)\n"
3475 "-include $(DEPFILES)\n"
3478 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ? " clean-all" : "",
3479 (makefile
->preprocess
? " preprocess" : ""));
3480 /* Don't include .d files when cleaning etc.; make will try to build them
3481 * and this involves running the Titan compiler. Same for preprocess.
3482 * The check target would be pointless if running the compiler
3483 * without generating code was always preceded by running the compiler
3484 * _and_ generating C++ code. */
3486 else { /* old-style dep with makedepend. Do not check compiler version. */
3487 fputs("\n\tmakedepend $(CPPFLAGS) -DMAKEDEPEND_RUN ", fp
);
3488 if (makefile
->gnu_make
) fputs("$^", fp
);
3489 else fputs("$(GENERATED_SOURCES) $(USER_SOURCES)", fp
);
3492 if (makefile
->linkingStrategy
) {
3495 "\t@perl $(TTCN3_DIR)/bin/ttcn3_archive.pl\n\n", fp
);
3500 "\tmkdir -p $(ARCHIVE_DIR)\n"
3501 "\ttar -cvhf - ", fp
);
3502 if (makefile
->central_storage
) {
3503 fprintf(fp
, "$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) %s\\\n",
3504 makefile
->linkingStrategy
? "$(BASE2_TTCN3_MODULES) " : "");
3505 if (makefile
->preprocess
) {
3506 fprintf(fp
, "\t$(TTCN3_PP_MODULES) $(BASE_TTCN3_PP_MODULES) "
3507 "%s $(TTCN3_INCLUDES) \\\n",
3508 makefile
->linkingStrategy
? "$(BASE2_TTCN3_PP_MODULES)" : "");
3510 fprintf(fp
, "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) %s\\\n"
3511 "\t$(USER_HEADERS) $(BASE_USER_HEADERS) %s\\\n"
3512 "\t$(USER_SOURCES) $(BASE_USER_SOURCES) %s",
3513 makefile
->linkingStrategy
? "$(BASE2_ASN1_MODULES) " : "",
3514 makefile
->linkingStrategy
? "$(BASE2_USER_HEADERS) " : "",
3515 makefile
->linkingStrategy
? "$(BASE2_USER_SOURCES)" : "");
3518 fputs("$(TTCN3_MODULES) ", fp
);
3519 if (makefile
->preprocess
) {
3520 fputs("$(TTCN3_PP_MODULES) \\\n"
3521 "\t$(TTCN3_INCLUDES) ", fp
);
3523 fputs("$(ASN1_MODULES) \\\n"
3524 "\t$(USER_HEADERS) $(USER_SOURCES)", fp
);
3526 fputs(" $(OTHER_FILES) \\\n"
3527 "\t| gzip >$(ARCHIVE_DIR)/`basename $(TARGET) .exe`-"
3528 "`date '+%y%m%d-%H%M'`.tgz\n\n", fp
);
3531 fprintf(fp
, "diag:\n"
3532 "\t$(TTCN3_DIR)/bin/compiler -v 2>&1\n"
3533 "\t$(TTCN3_DIR)/bin/mctr_cli -v 2>&1\n"
3534 "\t$(CXX) -v 2>&1\n"
3536 "\t@echo TTCN3_DIR=$(TTCN3_DIR)\n"
3537 "\t@echo OPENSSL_DIR=$(OPENSSL_DIR)\n"
3538 "\t@echo XMLDIR=$(XMLDIR)\n"
3539 "\t@echo PLATFORM=$(PLATFORM)\n\n",
3540 makefile
->dynamic
? "" : "\t$(AR) -V 2>&1\n");
3542 if (add_refd_prjs
) {
3543 fprintf(fp
, "referenced-all referenced-shared_objects referenced-executable referenced-library \\\n"
3544 "referenced-objects referenced-check \\\n"
3545 "referenced-clean%s:\n"
3546 "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
3547 "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
3549 (makefile
->linkingStrategy
&& makefile
->hierarchical
) ? "-all" : "");
3550 fputs("referenced-dep:\n"
3551 "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
3552 "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
3554 "\ttouch $@\n\n", fp
);
3557 if (makefile
->generatorCommandOutput
) {
3558 fputs("### Project specific rules generated by user written script:\n\n", fp
);
3559 fputs(makefile
->generatorCommandOutput
, fp
);
3560 fputs("\n### End of project specific rules.\n\n", fp
);
3564 "# Add your rules here if necessary...\n"
3567 if (strcmp(makefile
->output_file
, "Makefile")) {
3568 NOTIFY("Makefile skeleton was written to `%s'.", makefile
->output_file
);
3570 NOTIFY("Makefile skeleton was generated.");
3574 ERROR("Output file `%s' already exists. Use switch `%s' to force "
3576 makefile
->output_file
,
3577 makefile
->linkingStrategy
? "-F" : "-f");
3581 #undef COMMENT_PREFIX
3582 #define COMMENT_PREFIX
3584 /** run makefilegen commans for sub-projects */
3585 static void run_makefilegen_commands(struct string2_list
* run_command_list
)
3587 struct string2_list
* act_elem
= run_command_list
;
3589 struct string2_list
* next_elem
= act_elem
->next
;
3590 /* run commands if there were no ERRORs */
3591 if ((error_count
== 0) && act_elem
->str1
&& act_elem
->str2
) {
3593 char* sub_proj_effective_work_dir
= act_elem
->str1
;
3594 char* command
= act_elem
->str2
;
3595 char* orig_dir
= get_working_dir();
3596 rv
= set_working_dir(sub_proj_effective_work_dir
);
3597 if (rv
) ERROR("Could not set working dir to `%s'", sub_proj_effective_work_dir
);
3599 fprintf(stderr
, "Executing `%s' in working directory `%s'...\n",
3600 command
, sub_proj_effective_work_dir
);
3601 rv
= system(command
);
3602 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
3604 rv
= set_working_dir(orig_dir
);
3605 if (rv
) ERROR("Could not restore working dir to `%s'", orig_dir
);
3608 Free(act_elem
->str1
);
3609 Free(act_elem
->str2
);
3611 act_elem
= next_elem
;
3615 /** create symlinks and delete list */
3616 static void generate_symlinks(struct string2_list
* create_symlink_list
)
3618 struct string2_list
* act_elem
= create_symlink_list
;
3620 struct string2_list
* next_elem
= act_elem
->next
;
3621 /* create symlinks if there were no ERRORs */
3622 if ((error_count
== 0) && act_elem
->str1
&& act_elem
->str2
) {
3623 int fail
= symlink(act_elem
->str1
, act_elem
->str2
);
3624 if (fail
) perror(act_elem
->str2
); /* complain but do not call ERROR() */
3626 Free(act_elem
->str1
);
3627 Free(act_elem
->str2
);
3629 act_elem
= next_elem
;
3633 /** Performs all tasks of Makefile generation based on the given list of
3634 * modules/files (taken from the command line) and options that represent
3635 * command line switches. */
3636 static void generate_makefile(size_t n_arguments
, char *arguments
[],
3637 size_t n_other_files
, const char *other_files
[], const char *output_file
,
3638 const char *ets_name
, char *project_name
, boolean gnu_make
, boolean single_mode
,
3639 boolean central_storage
, boolean absolute_paths
, boolean preprocess
,
3640 boolean dump_makefile_data
, boolean force_overwrite
, boolean use_runtime_2
,
3641 boolean dynamic
, boolean makedepend
, boolean coverage
,
3642 const char *code_splitting_mode
, const char *tcov_file_name
,
3643 boolean Lflag
, boolean Zflag
, boolean Hflag
, struct string_list
* sub_project_dirs
, struct string_list
* ttcn3_prep_includes
,
3644 struct string_list
* ttcn3_prep_defines
, struct string_list
* ttcn3_prep_undefines
, struct string_list
* prep_includes
,
3645 struct string_list
* prep_defines
, struct string_list
* prep_undefines
, boolean codesplittpd
, boolean quietly
, boolean disablesubtypecheck
,
3646 const char* cxxcompiler
, const char* optlevel
, const char* optflags
, boolean disableber
, boolean disableraw
, boolean disabletext
,
3647 boolean disablexer
, boolean disablejson
, boolean forcexerinasn
, boolean defaultasomit
, boolean gccmsgformat
,
3648 boolean linenumbersonlymsg
, boolean includesourceinfo
, boolean addsourcelineinfo
, boolean suppresswarnings
,
3649 boolean outparamboundness
, struct string_list
* solspeclibraries
, struct string_list
* sol8speclibraries
,
3650 struct string_list
* linuxspeclibraries
, struct string_list
* freebsdspeclibraries
,
3651 struct string_list
* win32speclibraries
, const char* ttcn3preprocessor
, struct string_list
* linkerlibraries
,
3652 struct string_list
* additionalObjects
, struct string_list
* linkerlibsearchpath
, char* generatorCommandOutput
,
3653 struct string2_list
* target_placement_list
)
3657 struct makefile_struct makefile
;
3658 init_makefile_struct(&makefile
);
3660 makefile
.project_name
= project_name
;
3661 makefile
.central_storage
= central_storage
;
3662 makefile
.gnu_make
= gnu_make
;
3663 makefile
.preprocess
= preprocess
;
3664 makefile
.single_mode
= single_mode
;
3665 makefile
.force_overwrite
= force_overwrite
;
3666 makefile
.use_runtime_2
= use_runtime_2
;
3667 makefile
.dynamic
= dynamic
;
3668 makefile
.gcc_dep
= gnu_make
&& !makedepend
;
3669 makefile
.coverage
= coverage
;
3670 makefile
.library
= Lflag
;
3671 makefile
.linkingStrategy
= Zflag
;
3672 makefile
.hierarchical
= Hflag
;
3673 makefile
.sub_project_dirs
= sub_project_dirs
;
3674 makefile
.ttcn3_prep_includes
= ttcn3_prep_includes
;
3675 makefile
.ttcn3_prep_defines
= ttcn3_prep_defines
;
3676 makefile
.ttcn3_prep_undefines
= ttcn3_prep_undefines
;
3677 makefile
.prep_includes
= prep_includes
;
3678 makefile
.prep_defines
= prep_defines
;
3679 makefile
.prep_undefines
= prep_undefines
;
3680 makefile
.codesplittpd
= codesplittpd
;
3681 makefile
.quietly
= quietly
;
3682 makefile
.disablesubtypecheck
= disablesubtypecheck
;
3683 makefile
.cxxcompiler
= cxxcompiler
;
3684 makefile
.optlevel
= optlevel
;
3685 makefile
.optflags
= optflags
;
3686 makefile
.disableber
= disableber
;
3687 makefile
.disableraw
= disableraw
;
3688 makefile
.disabletext
= disabletext
;
3689 makefile
.disablexer
= disablexer
;
3690 makefile
.disablejson
= disablejson
;
3691 makefile
.forcexerinasn
= forcexerinasn
;
3692 makefile
.defaultasomit
= defaultasomit
;
3693 makefile
.gccmsgformat
= gccmsgformat
;
3694 makefile
.linenumbersonlymsg
= linenumbersonlymsg
;
3695 makefile
.includesourceinfo
= includesourceinfo
;
3696 makefile
.addsourcelineinfo
= addsourcelineinfo
;
3697 makefile
.suppresswarnings
= suppresswarnings
;
3698 makefile
.outparamboundness
= outparamboundness
;
3699 makefile
.solspeclibraries
= solspeclibraries
;
3700 makefile
.sol8speclibraries
= sol8speclibraries
;
3701 makefile
.linuxspeclibraries
= linuxspeclibraries
;
3702 makefile
.freebsdspeclibraries
= freebsdspeclibraries
;
3703 makefile
.win32speclibraries
= win32speclibraries
;
3704 makefile
.ttcn3preprocessor
= ttcn3preprocessor
;
3705 makefile
.linkerlibraries
= linkerlibraries
;
3706 makefile
.additionalObjects
= additionalObjects
;
3707 makefile
.linkerlibsearchpath
= linkerlibsearchpath
;
3708 makefile
.generatorCommandOutput
= generatorCommandOutput
;
3709 makefile
.target_placement_list
= target_placement_list
;
3711 for (i
= 0; i
< n_arguments
; i
++) {
3712 char *file_name
= get_file_name_for_argument(arguments
[i
]);
3713 if (file_name
!= NULL
) {
3714 FILE *fp
= fopen(file_name
, "r");
3717 if (is_ttcn3_module(file_name
, fp
, &module_name
)) {
3718 if (is_asn1_module(file_name
, fp
, NULL
)) {
3719 ERROR("File `%s' looks so strange that it can be both ASN.1 and "
3720 "TTCN-3 module. Add it to the Makefile manually.", file_name
);
3723 add_ttcn3_module(&makefile
, file_name
, module_name
);
3725 } else if (is_asn1_module(file_name
, fp
, &module_name
)) {
3726 if (is_valid_asn1_filename(file_name
)) {
3727 add_asn1_module(&makefile
, file_name
, module_name
);
3729 ERROR("The file name (without suffix) shall be identical to the module name.\n"
3730 "If the name of the ASN.1 module contains a hyphen, the corresponding "
3731 "file name shall contain an underscore character instead.");
3734 add_user_file(&makefile
, file_name
);
3738 ERROR("Cannot open file `%s' for reading: %s", file_name
,
3743 } else if (get_path_status(arguments
[i
]) == PS_DIRECTORY
) {
3744 ERROR("Argument `%s' is a directory.", arguments
[i
]);
3746 ERROR("Cannot find any source file for argument `%s'.", arguments
[i
]);
3749 for (i
= 0; i
< n_other_files
; i
++) {
3750 char *file_name
= get_file_name_for_argument(other_files
[i
]);
3751 if (file_name
!= NULL
) {
3752 add_path_to_list(&makefile
.nOtherFiles
, &makefile
.OtherFiles
, file_name
,
3753 makefile
.working_dir
, TRUE
);
3755 } else if (get_path_status(other_files
[i
]) == PS_DIRECTORY
) {
3756 ERROR("Argument `%s' given as other file is a directory.",
3759 ERROR("Cannot find any other file for argument `%s'.", other_files
[i
]);
3763 if (ets_name
!= NULL
) {
3764 char *dir_name
= get_dir_name(ets_name
, makefile
.working_dir
);
3765 char *file_name
= get_file_from_path(ets_name
);
3766 makefile
.ets_name
= compose_path_name(dir_name
, file_name
);
3771 if (code_splitting_mode
!= NULL
) {
3772 makefile
.code_splitting_mode
= mputprintf(makefile
.code_splitting_mode
, "-U %s", code_splitting_mode
);
3775 if (tcov_file_name
!= NULL
) {
3776 makefile
.tcov_file_name
= mputprintf(makefile
.tcov_file_name
, "-K %s", tcov_file_name
);
3779 if (makefile
.nTTCN3Modules
>= 1) {
3780 if (makefile
.ets_name
== NULL
)
3781 makefile
.ets_name
= mcopystr(makefile
.TTCN3Modules
[0].module_name
);
3782 } else if (preprocess
&& (makefile
.nTTCN3PPModules
>= 1)) {
3783 if (makefile
.ets_name
== NULL
)
3784 makefile
.ets_name
= mcopystr(makefile
.TTCN3PPModules
[0].module_name
);
3785 } else if (makefile
.nASN1Modules
>= 1) {
3786 WARNING("No TTCN-3 module was given for the Makefile.");
3787 if (makefile
.ets_name
== NULL
)
3788 makefile
.ets_name
= mcopystr(makefile
.ASN1Modules
[0].module_name
);
3789 } else if (makefile
.nUserFiles
> 0) {
3790 WARNING("No TTCN-3 or ASN.1 module was given for the Makefile.");
3791 if (makefile
.ets_name
== NULL
)
3792 makefile
.ets_name
= mcopystr(makefile
.UserFiles
[0].file_prefix
);
3794 WARNING("No source files were given for the Makefile");
3797 if (output_file
!= NULL
) {
3798 if (get_path_status(output_file
) == PS_DIRECTORY
)
3799 makefile
.output_file
= mprintf("%s/Makefile", output_file
);
3800 else makefile
.output_file
= mcopystr(output_file
);
3801 } else makefile
.output_file
= mcopystr("Makefile");
3802 add_path_to_list(&makefile
.nOtherFiles
, &makefile
.OtherFiles
,
3803 makefile
.output_file
, makefile
.working_dir
, FALSE
);
3805 if (preprocess
) check_preprocessed_filename_collision(&makefile
);
3806 filter_out_generated_files(&makefile
);
3807 complete_user_files(&makefile
);
3808 if (!absolute_paths
) convert_dirs_to_relative(&makefile
);
3809 check_special_chars(&makefile
);
3810 if (central_storage
) collect_base_dirs(&makefile
);
3811 check_naming_convention(&makefile
);
3813 if (dump_makefile_data
) dump_makefile_struct(&makefile
, 0);
3815 if (error_count
== 0) print_makefile(&makefile
);
3816 free_makefile_struct(&makefile
);
3819 #ifdef COVERAGE_BUILD
3826 static void usage(void)
3828 fprintf(stderr
, "\n"
3829 "usage: %s [-abc" C_flag
"dDfFglLmprRstTVwWXZ] [-K file] [-P dir]"
3830 " [-U none|type] [-e ets_name] [-o dir|file]\n"
3831 " [-t project_descriptor.tpd [-b buildconfig]]\n"
3832 " [-O file] ... module_name ... testport_name ...\n"
3836 " -a: use absolute pathnames in the generated Makefile\n"
3837 " -c: use the pre-compiled files from central directories\n"
3838 #ifdef COVERAGE_BUILD
3839 " -C: enable coverage of generated C++ code\n"
3841 " -d: dump the data used for Makefile generation\n"
3842 " -e ets_name: name of the target executable\n"
3843 " -f: force overwriting of the output Makefile\n"
3844 " -g: generate Makefile for use with GNU make\n"
3845 " -l: use dynamic linking\n"
3846 " -L: create makefile with library archive as the default target\n"
3847 " -m: always use makedepend for dependencies\n"
3848 " -K file: enable selective code coverage\n"
3849 " -o dir|file: write the Makefile to the given directory or file\n"
3850 " -O file: add the given file to the Makefile as other file\n"
3851 " -p: generate Makefile with TTCN-3 preprocessing\n"
3852 " -R: use function test runtime (TITAN_RUNTIME_2)\n"
3853 " -s: generate Makefile for single mode\n"
3854 " -U none|type: split generated code\n"
3855 " -v: show version\n"
3856 " -w: suppress warnings\n"
3857 " -Y: Enforces legacy behaviour of the \"out\" function parameters (see refguide)\n"
3858 "Options for processing the Titan Project Descriptor file(s):\n"
3859 " -t tpd: read project descriptor file\n"
3860 " -b buildconfig: use the specified build config instead of the default\n"
3861 " -D: use current directory as working directory\n"
3862 " -V: disable validation of TPD file with schema\n"
3863 " -r: generate Makefile hierarchy for TPD hierarchy (recursive)\n"
3864 " -F: force overwriting of all generated Makefiles, use with -r\n"
3865 " -T: generate only top-level Makefile of the hierarchy, use with -r\n"
3866 " -P dir: prints out a file list found in a given TPD relative to the given directory\n"
3867 " -X: generate XML file that describes the TPD hierarchy, use with -r\n"
3868 " -W: prefix working directories with project name\n"
3869 " -Z: recursive Makefile generation from TPD using object files and dynamic libraries too\n"
3870 " -H: hierachical Makefile generation from TPD use with -Z\n"
3871 , program_name
, program_name
);
3874 #define SET_FLAG(x) if (x##flag) {\
3875 ERROR("Flag -" #x " was specified more than once.");\
3877 } else x##flag = TRUE
3879 void free_string_list(struct string_list
* act_elem
)
3882 struct string_list
* next_elem
= act_elem
->next
;
3883 Free(act_elem
->str
);
3885 act_elem
= next_elem
;
3889 void free_string2_list(struct string2_list
* act_elem
)
3892 struct string2_list
* next_elem
= act_elem
->next
;
3893 Free(act_elem
->str1
);
3894 Free(act_elem
->str2
);
3896 act_elem
= next_elem
;
3900 int main(int argc
, char *argv
[])
3903 aflag
= FALSE
, bflag
= FALSE
, cflag
= FALSE
, Cflag
= FALSE
,
3904 dflag
= FALSE
, eflag
= FALSE
, fflag
= FALSE
, gflag
= FALSE
,
3905 oflag
= FALSE
, Kflag
= FALSE
, lflag
= FALSE
, pflag
= FALSE
,
3906 Pflag
= FALSE
, Rflag
= FALSE
, sflag
= FALSE
, tflag
= FALSE
,
3907 wflag
= FALSE
, vflag
= FALSE
, mflag
= FALSE
, Uflag
= FALSE
,
3908 Lflag
= FALSE
, rflag
= FALSE
, Fflag
= FALSE
, Xflag
= FALSE
,
3909 Tflag
= FALSE
, Yflag
= FALSE
, csflag
= FALSE
, quflag
= FALSE
,
3910 dsflag
= FALSE
, dbflag
= FALSE
, drflag
= FALSE
, dtflag
= FALSE
,
3911 dxflag
= FALSE
, fxflag
= FALSE
, doflag
= FALSE
,
3912 gfflag
= FALSE
, lnflag
= FALSE
, isflag
= FALSE
, asflag
= FALSE
,
3913 swflag
= FALSE
, Vflag
= FALSE
, Dflag
= FALSE
, Wflag
= FALSE
,
3914 djflag
= FALSE
, Zflag
= FALSE
, Hflag
= FALSE
;
3915 boolean error_flag
= FALSE
;
3916 char *output_file
= NULL
;
3917 char *ets_name
= NULL
;
3918 char *project_name
= NULL
;
3919 size_t n_other_files
= 0;
3920 const char **other_files
= NULL
;
3921 const char *code_splitting_mode
= NULL
;
3922 const char *tpd_file_name
= NULL
;
3923 const char *tpd_build_config
= NULL
;
3924 const char *tcov_file_name
= NULL
;
3925 const char *file_list_path
= NULL
;
3926 enum tpd_result tpd_processed
= FALSE
;
3927 struct string_list
* sub_project_dirs
= NULL
;
3928 struct string2_list
* create_symlink_list
= NULL
;
3929 struct string_list
* ttcn3_prep_includes
= NULL
;
3930 struct string_list
* ttcn3_prep_defines
= NULL
;
3931 struct string_list
* ttcn3_prep_undefines
= NULL
;
3932 struct string_list
* prep_includes
= NULL
;
3933 struct string_list
* prep_defines
= NULL
;
3934 struct string_list
* prep_undefines
= NULL
;
3935 char *cxxcompiler
= NULL
;
3936 char *optlevel
= NULL
;
3937 char *optflags
= NULL
;
3938 struct string_list
* solspeclibraries
= NULL
;
3939 struct string_list
* sol8speclibraries
= NULL
;
3940 struct string_list
* linuxspeclibraries
= NULL
;
3941 struct string_list
* freebsdspeclibraries
= NULL
;
3942 struct string_list
* win32speclibraries
= NULL
;
3943 char *ttcn3prep
= NULL
;
3944 struct string_list
* linkerlibraries
= NULL
;
3945 struct string_list
* additionalObjects
= NULL
;
3946 struct string_list
* linkerlibsearchpath
= NULL
;
3947 char* generatorCommandOutput
= NULL
;
3948 struct string2_list
* target_placement_list
= NULL
;
3949 struct string2_list
* run_command_list
= NULL
;
3950 struct string2_list
* required_configs
= NULL
;
3953 license_struct lstr
;
3957 program_name
= argv
[0];
3960 fputs("Makefile Generator for the TTCN-3 Test Executor, version "
3961 PRODUCT_NUMBER
"\n", stderr
);
3963 return EXIT_FAILURE
;
3967 int c
= getopt(argc
, argv
, "O:ab:c" C_flag
"dDe:fFgK:o:lLmpP:rRst:TU:vVwWXYZH");
3972 other_files
= (const char**)
3973 Realloc(other_files
, n_other_files
* sizeof(*other_files
));
3974 other_files
[n_other_files
- 1] = optarg
;
3981 tpd_build_config
= optarg
;
3988 tcov_file_name
= optarg
;
3990 #ifdef COVERAGE_BUILD
4019 output_file
= optarg
;
4035 /* Optional arguments with `::' are GNU specific... */
4036 if (get_path_status(optarg
) == PS_DIRECTORY
) {
4037 file_list_path
= optarg
;
4039 ERROR("The -P flag requires a valid directory as its argument "
4040 "instead of `%s'", optarg
);
4055 tpd_file_name
= optarg
;
4065 code_splitting_mode
= optarg
;
4066 if (strcmp(optarg
, "none") != 0 &&
4067 strcmp(optarg
, "type") != 0)
4068 ERROR("Unrecognizable argument: '%s'. Valid options for -U switch are: "
4069 "'none', 'type'", optarg
);
4079 suppress_warnings
= TRUE
;
4096 /* Checking incompatible options */
4098 /* -v prints the version and exits, it's pointless to specify other flags */
4099 if ( aflag
|| bflag
|| cflag
|| Cflag
|| dflag
|| eflag
|| fflag
|| Fflag
|| gflag
4100 || mflag
|| oflag
|| lflag
|| pflag
|| Pflag
|| rflag
|| Rflag
|| sflag
4101 || tflag
|| Tflag
|| Vflag
|| wflag
|| Xflag
|| Kflag
|| Dflag
|| Wflag
|| Yflag
4102 || Zflag
|| Hflag
|| n_other_files
> 0)
4107 if (!gflag
) gflag
= TRUE
; // GNU make
4108 if (!cflag
) cflag
= TRUE
; // central sorage
4111 if ((bflag
|| Dflag
|| Pflag
|| Vflag
|| rflag
|| Wflag
|| Zflag
) && !tflag
) {
4112 ERROR("Using the '-b', '-D', '-P', '-V', '-r' 'Z' or '-W' option requires the use of the -t' option.");
4116 if (rflag
&& !cflag
) {
4117 ERROR("Using the '-r' option requires use of the '-c' option. Recursive makefile hierarchy uses the central directory feature.");
4121 if (Fflag
&& !rflag
) {
4122 ERROR("Using the '-F' option requires use of the '-r' option.");
4126 if (Xflag
&& !rflag
) {
4127 ERROR("Using the '-X' option requires use of the '-r' option.");
4131 if (Tflag
&& !rflag
) {
4132 ERROR("Using the '-T' option requires use of the '-r' option.");
4136 if (!Zflag
&& Hflag
) {
4137 ERROR("Using the '-H' option requires use of the '-Z' option.");
4141 if (Zflag
&& !Fflag
&& !fflag
) {
4142 ERROR("Using the '-Z' option requires use of the '-F' option.");
4146 if (lflag
&& !strncmp(get_platform_string(), "WIN32", 5)) {
4147 ERROR("Generating Makefile with dynamic linking enabled is not supported "
4148 "on Windows platform");
4154 return EXIT_FAILURE
;
4158 fputs("Makefile Generator for the TTCN-3 Test Executor\n"
4159 "Product number: " PRODUCT_NUMBER
"\n"
4160 "Build date: " __DATE__
" " __TIME__
"\n"
4161 "Compiled with: " C_COMPILER_VERSION
"\n\n"
4162 COPYRIGHT_STRING
"\n\n", stderr
);
4164 print_license_info();
4166 return EXIT_SUCCESS
;
4171 load_license(&lstr
);
4172 valid_license
= verify_license(&lstr
);
4174 if (!valid_license
) {
4175 free_license(&lstr
);
4178 if (!check_feature(&lstr
, FEATURE_TPGEN
)) {
4179 ERROR("The license key does not allow the generation of "
4180 "Makefile skeletons.");
4181 return EXIT_FAILURE
;
4183 free_license(&lstr
);
4187 char* abs_work_dir
= NULL
;
4188 FILE* prj_graph_fp
= NULL
;
4189 sub_project_dirs
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4190 sub_project_dirs
->str
= NULL
;
4191 sub_project_dirs
->next
= NULL
;
4192 ttcn3_prep_includes
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4193 ttcn3_prep_includes
->str
= NULL
;
4194 ttcn3_prep_includes
->next
= NULL
;
4195 ttcn3_prep_defines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4196 ttcn3_prep_defines
->str
= NULL
;
4197 ttcn3_prep_defines
->next
= NULL
;
4198 ttcn3_prep_undefines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4199 ttcn3_prep_undefines
->str
= NULL
;
4200 ttcn3_prep_undefines
->next
= NULL
;
4201 prep_includes
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4202 prep_includes
->str
= NULL
;
4203 prep_includes
->next
= NULL
;
4204 prep_defines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4205 prep_defines
->str
= NULL
;
4206 prep_defines
->next
= NULL
;
4207 prep_undefines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4208 prep_undefines
->str
= NULL
;
4209 prep_undefines
->next
= NULL
;
4210 solspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4211 solspeclibraries
->str
= NULL
;
4212 solspeclibraries
->next
= NULL
;
4213 sol8speclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4214 sol8speclibraries
->str
= NULL
;
4215 sol8speclibraries
->next
= NULL
;
4216 linuxspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4217 linuxspeclibraries
->str
= NULL
;
4218 linuxspeclibraries
->next
= NULL
;
4219 freebsdspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4220 freebsdspeclibraries
->str
= NULL
;
4221 freebsdspeclibraries
->next
= NULL
;
4222 win32speclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4223 win32speclibraries
->str
= NULL
;
4224 win32speclibraries
->next
= NULL
;
4225 linkerlibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4226 linkerlibraries
->str
= NULL
;
4227 linkerlibraries
->next
= NULL
;
4228 additionalObjects
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4229 additionalObjects
->str
= NULL
;
4230 additionalObjects
->next
= NULL
;
4231 linkerlibsearchpath
= (struct string_list
*)Malloc(sizeof(struct string_list
));
4232 linkerlibsearchpath
->str
= NULL
;
4233 linkerlibsearchpath
->next
= NULL
;
4236 const char* prj_graph_filename
= "project_hierarchy_graph.xml";
4237 prj_graph_fp
= fopen(prj_graph_filename
, "w");
4238 if (prj_graph_fp
==NULL
) WARNING("Cannot open output file `%s' for writing: %s", prj_graph_filename
, strerror(errno
));
4239 if (prj_graph_fp
) fprintf(prj_graph_fp
, "<project_hierarchy_graph top_level_tpd=\"%s\">\n", tpd_file_name
);
4241 create_symlink_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4242 create_symlink_list
->str1
= NULL
;
4243 create_symlink_list
->str2
= NULL
;
4244 create_symlink_list
->next
= NULL
;
4245 target_placement_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4246 target_placement_list
->str1
= NULL
;
4247 target_placement_list
->str2
= NULL
;
4248 target_placement_list
->next
= NULL
;
4249 run_command_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4250 run_command_list
->str1
= NULL
;
4251 run_command_list
->str2
= NULL
;
4252 run_command_list
->next
= NULL
;
4253 required_configs
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
4254 required_configs
->str1
= NULL
;
4255 required_configs
->str2
= NULL
;
4256 required_configs
->next
= NULL
;
4258 tpd_processed
= process_tpd(tpd_file_name
, tpd_build_config
, file_list_path
,
4259 &argc
, &argv
, &optind
, &ets_name
, &project_name
,
4260 &gflag
, &sflag
, &cflag
, &aflag
, &pflag
,
4261 &Rflag
, &lflag
, &mflag
, &Pflag
, &Lflag
, rflag
, Fflag
, Tflag
, output_file
, &abs_work_dir
, sub_project_dirs
, program_name
, prj_graph_fp
,
4262 create_symlink_list
,ttcn3_prep_includes
, ttcn3_prep_defines
,ttcn3_prep_undefines
, prep_includes
, prep_defines
, prep_undefines
, &csflag
,
4263 &quflag
, &dsflag
, &cxxcompiler
, &optlevel
, &optflags
, &dbflag
, &drflag
, &dtflag
, &dxflag
, &djflag
, &fxflag
, &doflag
, &gfflag
, &lnflag
, &isflag
,
4264 &asflag
, &swflag
, &Yflag
, solspeclibraries
, sol8speclibraries
, linuxspeclibraries
, freebsdspeclibraries
, win32speclibraries
, &ttcn3prep
,
4265 linkerlibraries
, additionalObjects
, linkerlibsearchpath
, Vflag
, Dflag
, &Zflag
, &Hflag
,
4266 &generatorCommandOutput
, target_placement_list
, Wflag
, run_command_list
, required_configs
);
4270 fprintf(prj_graph_fp
, "</project_hierarchy_graph>\n");
4271 fclose(prj_graph_fp
);
4273 if (tpd_processed
== TPD_FAILED
) {
4274 ERROR("Failed to process %s", tpd_file_name
);
4280 run_makefilegen_commands(run_command_list
);
4281 generate_symlinks(create_symlink_list
);
4284 NOTIFY("Makefile generation from top-level TPD: %s", tpd_file_name
);
4285 if (!Fflag
&& fflag
)
4286 NOTIFY("Makefile generation from lower level TPD: %s", tpd_file_name
);
4288 generate_makefile(argc
- optind
, argv
+ optind
, n_other_files
, other_files
,
4289 output_file
, ets_name
, project_name
, gflag
, sflag
, cflag
, aflag
, pflag
, dflag
, fflag
||Fflag
,
4290 Rflag
, lflag
, mflag
, Cflag
, code_splitting_mode
, tcov_file_name
, Lflag
, Zflag
, Hflag
, rflag
? sub_project_dirs
: NULL
, ttcn3_prep_includes
,
4291 ttcn3_prep_defines
, ttcn3_prep_undefines
, prep_includes
, prep_defines
, prep_undefines
, csflag
, quflag
, dsflag
, cxxcompiler
, optlevel
, optflags
, dbflag
,
4292 drflag
, dtflag
, dxflag
, djflag
, fxflag
, doflag
, gfflag
, lnflag
, isflag
, asflag
, swflag
, Yflag
, solspeclibraries
,
4293 sol8speclibraries
, linuxspeclibraries
, freebsdspeclibraries
, win32speclibraries
, ttcn3prep
, linkerlibraries
, additionalObjects
,
4294 linkerlibsearchpath
, generatorCommandOutput
, target_placement_list
);
4297 free_string_list(sub_project_dirs
);
4298 free_string_list(ttcn3_prep_includes
);
4299 free_string_list(ttcn3_prep_defines
);
4300 free_string_list(ttcn3_prep_undefines
);
4301 free_string_list(prep_includes
);
4302 free_string_list(prep_defines
);
4303 free_string_list(prep_undefines
);
4304 free_string_list(solspeclibraries
);
4305 free_string_list(sol8speclibraries
);
4306 free_string_list(linuxspeclibraries
);
4307 free_string_list(freebsdspeclibraries
);
4308 free_string_list(win32speclibraries
);
4309 free_string_list(linkerlibraries
);
4310 free_string_list(additionalObjects
);
4311 free_string_list(linkerlibsearchpath
);
4313 Free(generatorCommandOutput
);
4314 free_string2_list(target_placement_list
);
4315 free_string2_list(required_configs
);
4318 if (tpd_processed
== TPD_SUCCESS
) {
4320 if (!(eflag
&& ets_name
))
4330 /* Free(output_file); */
4331 for (E
= 0; E
< argc
; ++E
) Free(argv
[E
]);
4334 /* check_mem_leak(program_name); not needed when linked to new.cc */
4335 return error_count
> 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;