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
;
36 void ERROR(const char *fmt
, ...)
39 fprintf(stderr
, "%s: error: ", program_name
);
40 va_start(parameters
, fmt
);
41 vfprintf(stderr
, fmt
, parameters
);
43 fprintf(stderr
, "\n");
48 void WARNING(const char *fmt
, ...)
51 if (suppress_warnings
) return;
52 fprintf(stderr
, "%s: warning: ", program_name
);
53 va_start(parameters
, fmt
);
54 vfprintf(stderr
, fmt
, parameters
);
60 void NOTIFY(const char *fmt
, ...)
63 va_start(parameters
, fmt
);
64 vfprintf(stderr
, fmt
, parameters
);
70 void DEBUG(unsigned level
, const char *fmt
, ...)
73 fprintf(stderr
, "%*s", 2 * level
, "");
74 va_start(parameters
, fmt
);
75 vfprintf(stderr
, fmt
, parameters
);
81 void path_error(const char *fmt
, ...)
86 err_msg
= mprintf_va_list(fmt
, ap
);
93 #if defined SOLARIS || defined SOLARIS8
94 /** Automatic detection of Solaris version based on uname() system call.
95 * Distinguishing is needed because some socket functions use socklen_t
96 * (which is an alias for unsigned int) as length arguments on Solaris 8.
97 * On Solaris 2.6 the argument type is simply int and no socklen_t or other
99 * Note: It was discovered later that Solaris 7 (which is used rarely within
100 * Ericsson) already uses socklen_t thus the SOLARIS8 platform identifier is a
102 static const char *get_platform_string(void)
106 if (uname(&name
) < 0) {
107 WARNING("System call uname() failed: %s", strerror(errno
));
111 if (sscanf(name
.release
, "%d.%d", &major
, &minor
) == 2 && major
== 5) {
112 if (minor
<= 6) return "SOLARIS";
113 else return "SOLARIS8";
115 ERROR("Invalid OS release: %s", name
.release
);
120 #define get_platform_string() "LINUX"
121 #elif defined FREEBSD
122 #define get_platform_string() "FREEBSD"
124 #define get_platform_string() "WIN32"
125 #elif defined INTERIX
126 #define get_platform_string() "INTERIX"
128 #error Platform was not set.
131 /** structure for describing TTCN-3 and ASN.1 modules */
132 struct module_struct
{
133 char *dir_name
; /* directory of the TTCN-3 or ASN.1 file, it is NULL if the
134 file is in the current working directory */
135 char *file_name
; /* name of the TTCN-3 or ASN.1 file */
136 char *module_name
; /* name of the TTCN-3 or ASN.1 module */
137 boolean is_regular
; /* indicates whether the name of the source file follows
138 the default naming convention */
141 /** structure for describing test ports and other C/C++ modules */
143 char *dir_name
; /* directory of the C/C++ source files, it is NULL if the
144 files are in the current working directory */
145 char *file_prefix
; /* the common prefix of the header and source file */
146 char *header_name
; /* name of the C/C++ header file, which has .hh or .h or .hpp
147 suffix, it is NULL if there is no header file */
148 char *source_name
; /* name of the C/C++ source file, which has .cc or .c or .cpp
149 suffix, it is NULL if there is no source file */
150 boolean has_hh_suffix
; /* indicates whether the header file is present and
151 has .hh or .hpp suffix */
152 boolean has_cc_suffix
; /* indicates whether the source file is present and
153 has .cc or .cpp suffix */
156 /** structure for directories that pre-compiled files are taken from */
157 struct base_dir_struct
{
158 const char *dir_name
; /* name of the directory */
159 boolean has_modules
; /* indicates whether there are TTCN-3/ASN.1 modules in
160 the directory (it is set to FALSE if dir_name
161 contains user C/C++ files only */
164 /** data structure that describes the information needed for the Makefile */
165 struct makefile_struct
{
166 size_t nTTCN3Modules
;
167 struct module_struct
*TTCN3Modules
;
170 size_t nTTCN3PPModules
;
171 struct module_struct
*TTCN3PPModules
;
173 boolean TTCN3ModulesRegular
;
174 boolean BaseTTCN3ModulesRegular
;
175 size_t nTTCN3IncludeFiles
;
176 char **TTCN3IncludeFiles
;
179 struct module_struct
*ASN1Modules
;
180 boolean ASN1ModulesRegular
;
181 boolean BaseASN1ModulesRegular
;
184 struct user_struct
*UserFiles
;
185 boolean UserHeadersRegular
;
186 boolean UserSourcesRegular
;
187 boolean BaseUserHeadersRegular
;
188 boolean BaseUserSourcesRegular
;
193 boolean central_storage
;
195 struct base_dir_struct
*BaseDirs
;
201 boolean force_overwrite
;
202 boolean use_runtime_2
;
205 char *code_splitting_mode
;
207 char *tcov_file_name
;
209 struct string_list
* sub_project_dirs
; /* not owned */
210 struct string_list
* ttcn3_prep_includes
; /* not owned */
211 struct string_list
* ttcn3_prep_defines
; /* not owned */
212 struct string_list
* prep_includes
; /* not owned */
213 struct string_list
* prep_defines
; /* not owned */
214 boolean codesplittpd
;
216 boolean disablesubtypecheck
;
217 const char *cxxcompiler
;
218 const char *optlevel
;
219 const char *optflags
;
225 boolean forcexerinasn
;
226 boolean defaultasomit
;
227 boolean gccmsgformat
;
228 boolean linenumbersonlymsg
;
229 boolean includesourceinfo
;
230 boolean addsourcelineinfo
;
231 boolean suppresswarnings
;
232 boolean outparamboundness
;
233 struct string_list
* solspeclibraries
; /* not owned */
234 struct string_list
* sol8speclibraries
; /* not owned */
235 struct string_list
* linuxspeclibraries
; /* not owned */
236 struct string_list
* freebsdspeclibraries
; /* not owned */
237 struct string_list
* win32speclibraries
; /* not owned */
238 const char *ttcn3preprocessor
;
239 struct string_list
* linkerlibraries
; /* not owned */
240 struct string_list
* additionalObjects
; /* not owned */
241 struct string_list
* linkerlibsearchpath
; /* not owned */
242 char* generatorCommandOutput
; /* not owned */
243 struct string2_list
* target_placement_list
; /* not owned */
246 /** Initializes structure \a makefile with empty lists and default settings. */
247 static void init_makefile_struct(struct makefile_struct
*makefile
)
249 makefile
->nTTCN3Modules
= 0;
250 makefile
->TTCN3Modules
= NULL
;
251 makefile
->preprocess
= FALSE
;
252 makefile
->nTTCN3PPModules
= 0;
253 makefile
->TTCN3PPModules
= NULL
;
254 makefile
->TTCN3ModulesRegular
= TRUE
;
255 makefile
->BaseTTCN3ModulesRegular
= TRUE
;
256 makefile
->nTTCN3IncludeFiles
= 0;
257 makefile
->TTCN3IncludeFiles
= NULL
;
258 makefile
->nASN1Modules
= 0;
259 makefile
->ASN1Modules
= NULL
;
260 makefile
->ASN1ModulesRegular
= TRUE
;
261 makefile
->BaseASN1ModulesRegular
= TRUE
;
262 makefile
->nUserFiles
= 0;
263 makefile
->UserFiles
= NULL
;
264 makefile
->UserHeadersRegular
= TRUE
;
265 makefile
->UserSourcesRegular
= TRUE
;
266 makefile
->BaseUserHeadersRegular
= TRUE
;
267 makefile
->BaseUserSourcesRegular
= TRUE
;
268 makefile
->nOtherFiles
= 0;
269 makefile
->OtherFiles
= NULL
;
270 makefile
->central_storage
= FALSE
;
271 makefile
->nBaseDirs
= 0;
272 makefile
->BaseDirs
= NULL
;
273 makefile
->working_dir
= get_working_dir();
274 makefile
->gnu_make
= FALSE
;
275 makefile
->single_mode
= FALSE
;
276 makefile
->ets_name
= NULL
;
277 makefile
->output_file
= NULL
;
278 makefile
->force_overwrite
= FALSE
;
279 makefile
->use_runtime_2
= FALSE
;
280 makefile
->dynamic
= FALSE
;
281 makefile
->gcc_dep
= FALSE
;
282 makefile
->code_splitting_mode
= NULL
;
283 makefile
->coverage
= FALSE
;
284 makefile
->tcov_file_name
= NULL
;
285 makefile
->library
= FALSE
;
286 makefile
->sub_project_dirs
= NULL
;
287 makefile
->ttcn3_prep_includes
= NULL
;
288 makefile
->prep_includes
= NULL
;
289 makefile
->prep_defines
= NULL
;
290 makefile
->outparamboundness
= FALSE
;
291 makefile
->solspeclibraries
= NULL
;
292 makefile
->sol8speclibraries
= NULL
;
293 makefile
->linuxspeclibraries
= NULL
;
294 makefile
->freebsdspeclibraries
= NULL
;
295 makefile
->win32speclibraries
= NULL
;
296 makefile
->linkerlibraries
= NULL
;
297 makefile
->additionalObjects
= NULL
;
298 makefile
->linkerlibsearchpath
= NULL
;
299 makefile
->generatorCommandOutput
= NULL
;
300 makefile
->target_placement_list
= NULL
;
303 /** Deallocates all memory associated with structure \a makefile. */
304 static void free_makefile_struct(const struct makefile_struct
*makefile
)
307 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
308 Free(makefile
->TTCN3Modules
[i
].dir_name
);
309 Free(makefile
->TTCN3Modules
[i
].file_name
);
310 Free(makefile
->TTCN3Modules
[i
].module_name
);
312 Free(makefile
->TTCN3Modules
);
313 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
314 Free(makefile
->TTCN3PPModules
[i
].dir_name
);
315 Free(makefile
->TTCN3PPModules
[i
].file_name
);
316 Free(makefile
->TTCN3PPModules
[i
].module_name
);
318 Free(makefile
->TTCN3PPModules
);
319 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
320 Free(makefile
->TTCN3IncludeFiles
[i
]);
321 Free(makefile
->TTCN3IncludeFiles
);
322 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
323 Free(makefile
->ASN1Modules
[i
].dir_name
);
324 Free(makefile
->ASN1Modules
[i
].file_name
);
325 Free(makefile
->ASN1Modules
[i
].module_name
);
327 Free(makefile
->ASN1Modules
);
328 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
329 Free(makefile
->UserFiles
[i
].dir_name
);
330 Free(makefile
->UserFiles
[i
].file_prefix
);
331 Free(makefile
->UserFiles
[i
].header_name
);
332 Free(makefile
->UserFiles
[i
].source_name
);
334 Free(makefile
->UserFiles
);
335 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) Free(makefile
->OtherFiles
[i
]);
336 Free(makefile
->OtherFiles
);
337 Free(makefile
->BaseDirs
);
338 Free(makefile
->working_dir
);
339 Free(makefile
->ets_name
);
340 Free(makefile
->output_file
);
341 Free(makefile
->code_splitting_mode
);
342 Free(makefile
->tcov_file_name
);
345 /** Displays the contents of structure \a makefile as debug messages. */
346 static void dump_makefile_struct(const struct makefile_struct
*makefile
,
350 DEBUG(level
, "Data used for Makefile generation:");
351 DEBUG(level
+ 1, "TTCN-3 modules: (%u pcs.)", makefile
->nTTCN3Modules
);
352 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
353 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
354 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
355 if (module
->dir_name
!= NULL
)
356 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
357 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
358 DEBUG(level
+ 3, "Follows the naming convention: %s",
359 module
->is_regular
? "yes" : "no");
361 DEBUG(level
+ 1, "TTCN-3 preprocessing: %s",
362 makefile
->preprocess
? "yes" : "no");
363 if (makefile
->preprocess
) {
364 DEBUG(level
+ 1, "TTCN-3 modules to be preprocessed: (%u pcs.)",
365 makefile
->nTTCN3PPModules
);
366 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
367 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
368 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
369 if (module
->dir_name
!= NULL
)
370 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
371 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
372 DEBUG(level
+ 3, "Follows the naming convention: %s",
373 module
->is_regular
? "yes" : "no");
375 DEBUG(level
+ 1, "TTCN-3 include files: (%u pcs.)",
376 makefile
->nTTCN3IncludeFiles
);
377 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
378 DEBUG(level
+ 2, "File name: %s", makefile
->TTCN3IncludeFiles
[i
]);
380 DEBUG(level
+ 1, "All local TTCN-3 modules follow the naming convention: %s",
381 makefile
->TTCN3ModulesRegular
? "yes" : "no");
382 if (makefile
->central_storage
) DEBUG(level
+ 1, "All TTCN-3 modules from other "
383 "directories follow the naming convention: %s",
384 makefile
->BaseTTCN3ModulesRegular
? "yes" : "no");
385 DEBUG(level
+ 1, "ASN.1 modules: (%u pcs.)", makefile
->nASN1Modules
);
386 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
387 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
388 DEBUG(level
+ 2, "Module name: %s", module
->module_name
);
389 if (module
->dir_name
!= NULL
)
390 DEBUG(level
+ 3, "Directory: %s", module
->dir_name
);
391 DEBUG(level
+ 3, "File name: %s", module
->file_name
);
392 DEBUG(level
+ 3, "Follows the naming convention: %s",
393 module
->is_regular
? "yes" : "no");
395 DEBUG(level
+ 1, "All local ASN.1 modules follow the naming convention: %s",
396 makefile
->ASN1ModulesRegular
? "yes" : "no");
397 if (makefile
->central_storage
) DEBUG(level
+ 1, "All ASN.1 modules from other "
398 "directories follow the naming convention: %s",
399 makefile
->BaseASN1ModulesRegular
? "yes" : "no");
400 DEBUG(level
+ 1, "User C/C++ modules: (%u pcs.)", makefile
->nUserFiles
);
401 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
402 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
403 DEBUG(level
+ 2, "File prefix: %s", user
->file_prefix
);
404 if (user
->dir_name
!= NULL
)
405 DEBUG(level
+ 3, "Directory: %s", user
->dir_name
);
406 if (user
->header_name
!= NULL
) {
407 DEBUG(level
+ 3, "Header file: %s", user
->header_name
);
408 DEBUG(level
+ 3, "Header file has .hh or .hpp suffix: %s",
409 user
->has_hh_suffix
? "yes" : "no");
411 if (user
->source_name
!= NULL
) {
412 DEBUG(level
+ 3, "Source file: %s", user
->source_name
);
413 DEBUG(level
+ 3, "Source file has .cc or .cpp suffix: %s",
414 user
->has_cc_suffix
? "yes" : "no");
415 DEBUG(level
+ 3, "Object file: %s.o", user
->file_prefix
);
418 DEBUG(level
+ 1, "All local C/C++ header files follow the naming "
419 "convention: %s", makefile
->UserHeadersRegular
? "yes" : "no");
420 DEBUG(level
+ 1, "All local C/C++ source files follow the naming "
421 "convention: %s", makefile
->UserSourcesRegular
? "yes" : "no");
422 if (makefile
->central_storage
) {
423 DEBUG(level
+ 1, "All C/C++ header files from other directories follow the "
424 "naming convention: %s", makefile
->BaseUserHeadersRegular
? "yes" : "no");
425 DEBUG(level
+ 1, "All C/C++ source files from other directories follow the "
426 "naming convention: %s", makefile
->BaseUserSourcesRegular
? "yes" : "no");
428 DEBUG(level
+ 1, "Other files: (%u pcs.)", makefile
->nOtherFiles
);
429 for (i
= 0; i
< makefile
->nOtherFiles
; i
++)
430 DEBUG(level
+ 2, "File name: %s", makefile
->OtherFiles
[i
]);
431 DEBUG(level
+ 1, "Use pre-compiled files from central storage: %s",
432 makefile
->central_storage
? "yes" : "no");
433 if (makefile
->central_storage
) {
434 DEBUG(level
+ 1, "Directories of pre-compiled files: (%u pcs.)",
435 makefile
->nBaseDirs
);
436 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
437 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
438 DEBUG(level
+ 2, "Directory: %s", base_dir
->dir_name
);
439 DEBUG(level
+ 3, "Has TTCN-3/ASN.1 modules: %s",
440 base_dir
->has_modules
? "yes" : "no");
443 DEBUG(level
+ 1, "Working directory: %s",
444 makefile
->working_dir
!= NULL
? makefile
->working_dir
: "<unknown>");
445 DEBUG(level
+ 1, "GNU make: %s", makefile
->gnu_make
? "yes" : "no");
446 DEBUG(level
+ 1, "Execution mode: %s",
447 makefile
->single_mode
? "single" : "parallel");
448 DEBUG(level
+ 1, "Name of executable: %s",
449 makefile
->ets_name
!= NULL
? makefile
->ets_name
: "<unknown>");
450 DEBUG(level
+ 1, "Output file: %s",
451 makefile
->output_file
!= NULL
? makefile
->output_file
: "<unknown>");
452 DEBUG(level
+ 1, "Force overwrite: %s",
453 makefile
->force_overwrite
? "yes" : "no");
454 DEBUG(level
+ 1, "Use function test runtime: %s",
455 makefile
->use_runtime_2
? "yes" : "no");
456 DEBUG(level
+ 1, "Use dynamic linking: %s",
457 makefile
->dynamic
? "yes" : "no");
458 DEBUG(level
+ 1, "Code splitting mode: %s",
459 makefile
->code_splitting_mode
!= NULL
?
460 makefile
->code_splitting_mode
: "<unknown>");
461 DEBUG(level
+ 1, "Code coverage file: %s",
462 makefile
->tcov_file_name
!= NULL
?
463 makefile
->tcov_file_name
: "<unknown>");
464 #ifdef COVERAGE_BUILD
465 DEBUG(level
+ 1, "Enable coverage: %s", makefile
->coverage
? "yes" : "no");
469 /** Returns the name of an existing file that is related to command line
470 * argument \a argument. Tries the given list of suffixes. NULL pointer is
471 * returned if no file was found. The returned string shall be deallocated
473 static char *get_file_name_for_argument(const char *argument
)
475 static const char * const suffix_list
[] = {
476 "", ".ttcnpp", ".ttcnin", ".ttcn", ".ttcn3", ".3mp", ".asn", ".asn1",
477 ".cc", ".c", ".cpp", ".hh", ".h",".hpp", ".cfg", ".prj", NULL
479 const char * const *suffix_ptr
;
480 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
481 char *file_name
= mputstr(mcopystr(argument
), *suffix_ptr
);
482 if (get_path_status(file_name
) == PS_FILE
) return file_name
;
488 /** Converts \a path_name to an absolute directory using \a working_dir.
489 * NULL pointer is returned if \a path_name does not contain a directory or
490 * the resulting absolute directory is identical to \a working_dir.
491 * The returned string shall be deallocated by the caller. */
492 static char *get_dir_name(const char *path_name
, const char *working_dir
)
494 char *dir_name
= get_dir_from_path(path_name
);
495 if (dir_name
!= NULL
) {
496 char *absolute_dir
= get_absolute_dir(dir_name
, working_dir
);
498 if (absolute_dir
== NULL
|| working_dir
== NULL
) {
499 /* an error occurred */
501 } else if (!strcmp(absolute_dir
, working_dir
)) {
502 /* the directory is identical to the working dir */
505 } else return absolute_dir
;
509 /** Returns whether \a dirname1 and \a dirname2 contain the same (canonized
510 * absolute) directories. NULL pointer is handled in a special way: it is
511 * identical only to itself. */
512 static boolean
is_same_directory(const char *dirname1
, const char *dirname2
)
514 if (dirname1
== NULL
) {
515 if (dirname2
== NULL
) return TRUE
;
518 if (dirname2
== NULL
) return FALSE
;
519 else if (strcmp(dirname1
, dirname2
)) return FALSE
;
524 /** Returns whether the file \a filename1 in directory \a dirname1 is identical
525 * to file \a filename2 in directory \a dirname2. Only the directory names can
527 static boolean
is_same_file(const char *dirname1
, const char *filename1
,
528 const char *dirname2
, const char *filename2
)
530 /* first examine the file names for efficiency reasons */
531 if (strcmp(filename1
, filename2
)) return FALSE
;
532 else return is_same_directory(dirname1
, dirname2
);
535 /** Determines whether the TTCN-3 or ASN.1 module identifiers \a module1 and
536 * \a module2 are the same. Characters '-' and '_' in module names are not
538 static boolean
is_same_module(const char *module1
, const char *module2
)
542 switch (module1
[i
]) {
544 if (module2
[i
] == '\0') return TRUE
;
548 if (module2
[i
] != '-' && module2
[i
] != '_') return FALSE
;
551 if (module1
[i
] != module2
[i
]) return FALSE
;
555 return FALSE
; /* to avoid warnings */
558 /** Determines the suffix (i.e. the character sequence following the last dot)
559 * of file or path name \a file_name. NULL pointer is returned if \a file_name
560 * does not contain any dot character or the last character of it is a dot.
561 * The suffix is not copied, the returned pointer points to the tail of
563 static const char *get_suffix(const char *file_name
)
565 size_t last_dot
= (size_t)-1;
567 for (i
= 0; file_name
[i
] != '\0'; i
++)
568 if (file_name
[i
] == '.') last_dot
= i
;
569 if (last_dot
== (size_t)-1 || file_name
[last_dot
+ 1] == '\0') return NULL
;
570 else return file_name
+ last_dot
+ 1;
573 /** Truncates the suffix (i.e. the last dot and the characters following it)
574 * from \a file_name and returns a copy of the prefix of \a file_name.
575 * If \a file_name does not have a suffix an exact copy of it is returned.
576 * The returned string shall be deallocated by the caller. */
577 static char *cut_suffix(const char *file_name
)
580 size_t last_dot
= (size_t)-1;
582 for (i
= 0; file_name
[i
] != '\0'; i
++)
583 if (file_name
[i
] == '.') last_dot
= i
;
584 ret_val
= mcopystr(file_name
);
585 if (last_dot
!= (size_t)-1) ret_val
= mtruncstr(ret_val
, last_dot
);
589 /** Determines the name of the preprocessed file from \a file_name.
590 * It is assumed that \a file_name has ttcnpp suffix.
591 * The returned string shall be deallocated by the caller. */
592 static char *get_preprocessed_file_name(const char *file_name
)
594 char *ret_val
= cut_suffix(file_name
);
595 ret_val
= mputstr(ret_val
, ".ttcn");
599 /** Check if any of the preprocessed ttcn file names with the preprocessed
600 * (TTCN-3) suffix is equal to any other file given in the \a makefile */
601 static void check_preprocessed_filename_collision(
602 struct makefile_struct
*makefile
)
605 if (makefile
->nTTCN3PPModules
== 0) {
606 WARNING("TTCN-3 preprocessing (option `-p') is enabled, but no TTCN-3 "
607 "files to be preprocessed were given for the Makefile.");
609 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
610 const struct module_struct
*pp_module
= makefile
->TTCN3PPModules
+ i
;
611 /* name of the intermediate preprocessed file */
612 char *preprocessed_name
= get_preprocessed_file_name(pp_module
->file_name
);
614 for (j
= 0; j
< makefile
->nTTCN3Modules
; j
++) {
615 struct module_struct
*module
= makefile
->TTCN3Modules
+ j
;
616 if (is_same_file(pp_module
->dir_name
, preprocessed_name
,
617 module
->dir_name
, module
->file_name
)) {
618 if (is_same_module(pp_module
->module_name
, module
->module_name
)) {
619 /* same file with the same module */
620 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
621 pp_module
->file_name
);
622 char *m_pathname
= compose_path_name(module
->dir_name
,
624 WARNING("File `%s' containing TTCN-3 module `%s' is generated by "
625 "the preprocessor from `%s'. Removing the file from the list of "
626 "normal TTCN-3 modules.", m_pathname
, module
->module_name
,
630 Free(module
->dir_name
);
631 Free(module
->file_name
);
632 Free(module
->module_name
);
633 makefile
->nTTCN3Modules
--;
634 memmove(module
, module
+ 1, (makefile
->nTTCN3Modules
- j
) *
635 sizeof(*makefile
->TTCN3Modules
));
636 makefile
->TTCN3Modules
=
637 (struct module_struct
*)Realloc(makefile
->TTCN3Modules
,
638 makefile
->nTTCN3Modules
* sizeof(*makefile
->TTCN3Modules
));
640 /* same file with different module */
641 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
642 pp_module
->file_name
);
643 char *m_pathname
= compose_path_name(module
->dir_name
,
645 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
646 "with file `%s' containing TTCN-3 module `%s'.", pp_pathname
,
647 pp_module
->module_name
, m_pathname
, module
->module_name
);
651 } else if (is_same_module(pp_module
->module_name
, module
->module_name
)) {
652 /* different file with the same module */
653 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
654 pp_module
->file_name
);
655 char *m_pathname
= compose_path_name(module
->dir_name
,
657 ERROR("Both files `%s' and `%s' contain TTCN-3 module `%s'.",
658 pp_pathname
, m_pathname
, pp_module
->module_name
);
663 for (j
= 0; j
< makefile
->nASN1Modules
; j
++) {
664 struct module_struct
*module
= makefile
->ASN1Modules
+ j
;
665 if (is_same_file(pp_module
->dir_name
, preprocessed_name
,
666 module
->dir_name
, module
->file_name
)) {
667 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
668 pp_module
->file_name
);
669 char *m_pathname
= compose_path_name(module
->dir_name
,
671 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
672 "with file `%s' containing ASN.1 module `%s'.", pp_pathname
,
673 pp_module
->module_name
, m_pathname
, module
->module_name
);
678 for (j
= 0; j
< makefile
->nOtherFiles
; j
++) {
679 char *dir_name
= get_dir_name(makefile
->OtherFiles
[j
],
680 makefile
->working_dir
);
681 char *file_name
= get_file_from_path(makefile
->OtherFiles
[j
]);
682 if (is_same_file(pp_module
->dir_name
, preprocessed_name
, dir_name
,
684 char *pp_pathname
= compose_path_name(pp_module
->dir_name
,
685 pp_module
->file_name
);
686 ERROR("Preprocessed intermediate file of `%s' (module `%s') clashes "
687 "with other file `%s'.", pp_pathname
, pp_module
->module_name
,
688 makefile
->OtherFiles
[j
]);
694 Free(preprocessed_name
);
698 /** Checks the name clash between existing module \a module and newly added
699 * module with parameters \a path_name, \a dir_name, \a file_name,
700 * \a module_name. Both the existing and the new module shall be of the same
701 * kind, parameter \a kind shall contain the respective string (either "ASN.1"
702 * or "TTCN-3"). If a clash is found the parameters of the new module except
703 * \a path_name are deallocated and TRUE is returned. Otherwise FALSE is
705 static boolean
check_module_clash_same(const struct module_struct
*module
,
706 const char *kind
, const char *path_name
, char *dir_name
, char *file_name
,
709 if (is_same_module(module_name
, module
->module_name
)) {
710 if (is_same_file(dir_name
, file_name
,
711 module
->dir_name
, module
->file_name
)) {
712 /* the same file was given twice: just issue a warning */
713 WARNING("File `%s' was given more than once for the Makefile.",
716 /* two different files contain the same module: this cannot be
717 * resolved as the generated C++ files will clash */
718 char *path_name1
= compose_path_name(module
->dir_name
,
720 char *path_name2
= compose_path_name(dir_name
, file_name
);
721 ERROR("Both files `%s' and `%s' contain %s module `%s'.",
722 path_name1
, path_name2
, kind
, module_name
);
733 /** Checks the name clash between existing module \a module and newly added
734 * module with parameters \a dir_name, \a file_name, \a module_name. The two
735 * modules shall be of different kinds (one is ASN.1, the other is TTCN-3).
736 * Parameters \a kind1 and \a kind2 shall contain the respective strings. If a
737 * clash is found the parameters of the new module are deallocated and TRUE is
738 * returned. Otherwise FALSE is returned. */
739 static boolean
check_module_clash_different(const struct module_struct
*module
,
740 const char *kind1
, char *dir_name
, char *file_name
, char *module_name
,
743 if (is_same_module(module_name
, module
->module_name
)) {
744 /* two different files contain the same module: this cannot be resolved
745 * as the generated C++ files will clash */
746 char *path_name1
= compose_path_name(module
->dir_name
, module
->file_name
);
747 char *path_name2
= compose_path_name(dir_name
, file_name
);
748 ERROR("File `%s' containing %s module `%s' and file `%s' containing "
749 "%s module `%s' cannot be used together in the same Makefile.",
750 path_name1
, kind1
, module
->module_name
, path_name2
, kind2
, module_name
);
760 /** Adds a TTCN-3 module to Makefile descriptor structure \a makefile.
761 * The name of the TTCN-3 source file is \a path_name, the module identifier
762 * is \a module_name. It is checked whether a file or module with the same name
763 * already exists in \a makefile and an appropriate warning or error is
765 static void add_ttcn3_module(struct makefile_struct
*makefile
,
766 const char *path_name
, char *module_name
)
768 struct module_struct
*module
;
769 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
770 char *file_name
= get_file_from_path(path_name
);
771 const char *suffix
= get_suffix(file_name
);
773 boolean is_preprocessed
= FALSE
;
775 if (suffix
!= NULL
) {
776 if (!strcmp(suffix
, "ttcnpp")) {
777 if (makefile
->preprocess
) is_preprocessed
= TRUE
;
778 else WARNING("The suffix of TTCN-3 file `%s' indicates that it should be "
779 "preprocessed, but TTCN-3 preprocessing is not enabled. The file "
780 "will be added to the list of normal TTCN-3 modules in the Makefile.",
782 } else if (!strcmp(suffix
, "ttcnin")) {
783 WARNING("The suffix of file `%s' indicates that it should be a "
784 "preprocessor include file, but it contains a TTCN-3 module named `%s'. "
785 "The file will be added to the list of normal TTCN-3 modules in the "
786 "Makefile.", path_name
, module_name
);
790 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
791 if (check_module_clash_different(makefile
->ASN1Modules
+ i
, "ASN.1",
792 dir_name
, file_name
, module_name
, "TTCN-3")) return;
794 /* never entered if suffix is NULL */
795 if (is_preprocessed
) {
797 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
798 if (check_module_clash_same(makefile
->TTCN3PPModules
+ i
, "TTCN-3",
799 path_name
, dir_name
, file_name
, module_name
)) return;
801 /* clashes with normal TTCN-3 modules will be checked (and maybe resolved)
802 * in \a check_preprocessed_filename_collision() */
803 /* add it to the list of TTCN-3 modules to be preprocessed */
804 makefile
->TTCN3PPModules
= (struct module_struct
*)
805 Realloc(makefile
->TTCN3PPModules
,
806 (makefile
->nTTCN3PPModules
+ 1) * sizeof(*makefile
->TTCN3PPModules
));
807 module
= makefile
->TTCN3PPModules
+ makefile
->nTTCN3PPModules
;
808 makefile
->nTTCN3PPModules
++;
809 module
->dir_name
= dir_name
;
810 module
->file_name
= file_name
;
811 module
->module_name
= module_name
;
812 file_prefix
= cut_suffix(file_name
);
813 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
814 else module
->is_regular
= FALSE
;
817 /* the file is not preprocessed */
818 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
819 if (check_module_clash_same(makefile
->TTCN3Modules
+ i
, "TTCN-3",
820 path_name
, dir_name
, file_name
, module_name
)) return;
822 /* clashes with preprocessed TTCN-3 modules will be checked (and maybe
823 * resolved) in \a check_preprocessed_filename_collision() */
824 /* add it to the list of normal TTCN-3 modules */
825 makefile
->TTCN3Modules
= (struct module_struct
*)
826 Realloc(makefile
->TTCN3Modules
,
827 (makefile
->nTTCN3Modules
+ 1) * sizeof(*makefile
->TTCN3Modules
));
828 module
= makefile
->TTCN3Modules
+ makefile
->nTTCN3Modules
;
829 makefile
->nTTCN3Modules
++;
830 module
->dir_name
= dir_name
;
831 module
->file_name
= file_name
;
832 module
->module_name
= module_name
;
833 if (suffix
!= NULL
&& !strcmp(suffix
, "ttcn")) {
834 char *file_prefix
= cut_suffix(file_name
);
835 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
836 else module
->is_regular
= FALSE
;
839 module
->is_regular
= FALSE
;
844 /** ASN.1 filename shall contain no hyphen */
845 static boolean
is_valid_asn1_filename(const char* file_name
)
847 if (0 == strchr(file_name
, '-')) {
853 /** Adds an ASN.1 module to Makefile descriptor structure \a makefile.
854 * The name of the ASN.1 source file is \a path_name, the module identifier
855 * is \a module_name. It is checked whether a file or module with the same name
856 * already exists in \a makefile and an appropriate warning or error is
858 static void add_asn1_module(struct makefile_struct
*makefile
,
859 const char *path_name
, char *module_name
)
861 struct module_struct
*module
;
862 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
863 char *file_name
= get_file_from_path(path_name
);
864 const char *suffix
= get_suffix(file_name
);
866 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
867 if (check_module_clash_same(makefile
->ASN1Modules
+ i
, "ASN.1", path_name
,
868 dir_name
, file_name
, module_name
)) return;
870 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
871 if (check_module_clash_different(makefile
->TTCN3Modules
+ i
, "TTCN-3",
872 dir_name
, file_name
, module_name
, "ASN.1")) return;
874 if (makefile
->preprocess
) {
875 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
876 if (check_module_clash_different(makefile
->TTCN3PPModules
+ i
, "TTCN-3",
877 dir_name
, file_name
, module_name
, "ASN.1")) return;
880 makefile
->ASN1Modules
= (struct module_struct
*)
881 Realloc(makefile
->ASN1Modules
,
882 (makefile
->nASN1Modules
+ 1) * sizeof(*makefile
->ASN1Modules
));
883 module
= makefile
->ASN1Modules
+ makefile
->nASN1Modules
;
884 makefile
->nASN1Modules
++;
885 module
->dir_name
= dir_name
;
886 module
->file_name
= file_name
;
887 module
->module_name
= module_name
;
888 if (suffix
!= NULL
&& !strcmp(suffix
, "asn")) {
889 char *file_prefix
= cut_suffix(file_name
);
890 /* replace all '_' with '-' in file name prefix */
891 for (i
= 0; file_prefix
[i
] != '\0'; i
++)
892 if (file_prefix
[i
] == '_') file_prefix
[i
] = '-';
893 if (!strcmp(file_prefix
, module_name
)) module
->is_regular
= TRUE
;
894 else module
->is_regular
= FALSE
;
897 module
->is_regular
= FALSE
;
901 /** Adds the file named \a path_name to the list of files pointed by \a list_ptr
902 * and \a list_size. The suffix or contents of \a path_name are not examined,
903 * only duplicate entries are checked. In case of duplicate entries warning is
904 * reported only if argument \a report_warning is set to TRUE. */
905 static void add_path_to_list(size_t *list_size
, char ***list_ptr
,
906 const char *path_name
, const char *working_dir
, boolean report_warning
)
909 char *dir_name
= get_dir_name(path_name
, working_dir
);
910 char *file_name
= get_file_from_path(path_name
);
911 char *canonized_path_name
= compose_path_name(dir_name
, file_name
);
914 for (i
= 0; i
< *list_size
; i
++) {
915 if (!strcmp(canonized_path_name
, (*list_ptr
)[i
])) {
916 if (report_warning
) WARNING("File `%s' was given more than once for the "
917 "Makefile.", path_name
);
918 Free(canonized_path_name
);
922 *list_ptr
= (char**)Realloc(*list_ptr
, (*list_size
+ 1) * sizeof(**list_ptr
));
923 (*list_ptr
)[*list_size
] = canonized_path_name
;
927 /** Adds a C/C++ header or source file or an other file named \a path_name to
928 * Makefile descriptor structure \a makefile. The file is classified based on
929 * its suffix and not by content. If the file clashes with existing files or
930 * modules the appropriate warning or error is generated. */
931 static void add_user_file(struct makefile_struct
*makefile
,
932 const char *path_name
)
934 const char *suffix
= get_suffix(path_name
);
935 if (suffix
!= NULL
) {
936 if (!strcmp(suffix
, "ttcn") || !strcmp(suffix
, "ttcn3") ||
937 !strcmp(suffix
, "3mp") || !strcmp(suffix
, "ttcnpp")) {
938 /* The file content was already checked. Since it doesn't look like
939 * a valid TTCN-3 file, these suffixes are suspect */
940 WARNING("File `%s' does not contain a valid TTCN-3 module. "
941 "It will be added to the Makefile as other file.", path_name
);
942 } else if (!strcmp(suffix
, "ttcnin")) {
943 /* this is a TTCN-3 include file */
944 if (makefile
->preprocess
) {
945 add_path_to_list(&makefile
->nTTCN3IncludeFiles
,
946 &makefile
->TTCN3IncludeFiles
, path_name
, makefile
->working_dir
, TRUE
);
949 WARNING("The suffix of file `%s' indicates that it is a TTCN-3 "
950 "include file, but TTCN-3 preprocessing is not enabled. The file "
951 "will be added to the Makefile as other file.", path_name
);
953 } else if (!strcmp(suffix
, "asn") || !strcmp(suffix
, "asn1")) {
954 /* The file content was already checked. Since it doesn't look like
955 * a valid ASN.1 file, these suffixes are suspect */
956 WARNING("File `%s' does not contain a valid ASN.1 module. "
957 "It will be added to the Makefile as other file.", path_name
);
958 } else if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "c") || !strcmp(suffix
, "cpp")) {
959 /* this is a source file */
960 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
961 char *file_name
= get_file_from_path(path_name
);
962 char *file_prefix
= cut_suffix(file_name
);
963 struct user_struct
*user
;
965 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
966 user
= makefile
->UserFiles
+ i
;
967 if (!strcmp(file_prefix
, user
->file_prefix
)) {
968 if (user
->source_name
!= NULL
) {
969 /* the source file is already present */
970 if (is_same_file(dir_name
, file_name
,
971 user
->dir_name
, user
->source_name
)) {
972 WARNING("File `%s' was given more than once for the Makefile.",
975 char *path_name1
= compose_path_name(user
->dir_name
,
977 char *path_name2
= compose_path_name(dir_name
, file_name
);
978 ERROR("C/C++ source files `%s' and `%s' cannot be used together "
979 "in the same Makefile.", path_name1
, path_name2
);
984 /* a header file with the same prefix is already present */
985 if (is_same_directory(dir_name
, user
->dir_name
)) {
986 user
->source_name
= file_name
;
988 if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "cpp")) user
->has_cc_suffix
= TRUE
;
990 char *path_name1
= compose_path_name(dir_name
, file_name
);
991 char *path_name2
= compose_path_name(user
->dir_name
,
993 ERROR("C/C++ source file `%s' cannot be used together with "
994 "header file `%s' in the same Makefile.", path_name1
,
1006 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1007 (makefile
->nUserFiles
+ 1) * sizeof(*makefile
->UserFiles
));
1008 user
= makefile
->UserFiles
+ makefile
->nUserFiles
;
1009 makefile
->nUserFiles
++;
1010 user
->dir_name
= dir_name
;
1011 user
->file_prefix
= file_prefix
;
1012 user
->header_name
= NULL
;
1013 user
->source_name
= file_name
;
1014 user
->has_hh_suffix
= FALSE
;
1015 if (!strcmp(suffix
, "cc") || !strcmp(suffix
, "cpp")) user
->has_cc_suffix
= TRUE
;
1016 else user
->has_cc_suffix
= FALSE
;
1018 } else if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "h")) {
1019 /* this is a header file */
1020 char *dir_name
= get_dir_name(path_name
, makefile
->working_dir
);
1021 char *file_name
= get_file_from_path(path_name
);
1022 char *file_prefix
= cut_suffix(file_name
);
1023 struct user_struct
*user
;
1025 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1026 user
= makefile
->UserFiles
+ i
;
1027 if (!strcmp(file_prefix
, user
->file_prefix
)) {
1028 if (user
->header_name
!= NULL
) {
1029 /* the header file is already present */
1030 if (is_same_file(dir_name
, file_name
,
1031 user
->dir_name
, user
->header_name
)) {
1032 WARNING("File `%s' was given more than once for the Makefile.",
1035 char *path_name1
= compose_path_name(user
->dir_name
,
1037 char *path_name2
= compose_path_name(dir_name
, file_name
);
1038 ERROR("C/C++ header files `%s' and `%s' cannot be used together "
1039 "in the same Makefile.", path_name1
, path_name2
);
1044 /* a source file with the same prefix is already present */
1045 if (is_same_directory(dir_name
, user
->dir_name
)) {
1046 user
->header_name
= file_name
;
1048 if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "hpp")) user
->has_hh_suffix
= TRUE
;
1050 char *path_name1
= compose_path_name(dir_name
, file_name
);
1051 char *path_name2
= compose_path_name(user
->dir_name
,
1053 ERROR("C/C++ header file `%s' cannot be used together with "
1054 "source file `%s' in the same Makefile.", path_name1
,
1066 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1067 (makefile
->nUserFiles
+ 1) * sizeof(*makefile
->UserFiles
));
1068 user
= makefile
->UserFiles
+ makefile
->nUserFiles
;
1069 makefile
->nUserFiles
++;
1070 user
->dir_name
= dir_name
;
1071 user
->file_prefix
= file_prefix
;
1072 user
->header_name
= file_name
;
1073 user
->source_name
= NULL
;
1074 if (!strcmp(suffix
, "hh") || !strcmp(suffix
, "hpp")) user
->has_hh_suffix
= TRUE
;
1075 else user
->has_hh_suffix
= FALSE
;
1076 user
->has_cc_suffix
= FALSE
;
1079 } /* end if (suffix != NULL) */
1080 /* treat the file as other file if it was not handled yet */
1081 add_path_to_list(&makefile
->nOtherFiles
, &makefile
->OtherFiles
, path_name
,
1082 makefile
->working_dir
, TRUE
);
1085 /** Removes the generated C++ header and/or source files of module \a module
1086 * from Makefile descriptor structure \a makefile. A warning is displayed if
1087 * such file is found. */
1088 static void drop_generated_files(struct makefile_struct
*makefile
,
1089 const struct module_struct
*module
)
1091 char *module_name
= mcopystr(module
->module_name
);
1093 /* transform all '-' characters in ASN.1 module name to '_' */
1094 for (i
= 0; module_name
[i
] != '\0'; i
++)
1095 if (module_name
[i
] == '-') module_name
[i
] = '_';
1096 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1097 struct user_struct
*user
= makefile
->UserFiles
+ i
;
1098 if (!strcmp(module_name
, user
->file_prefix
)) {
1099 char *m_pathname
= compose_path_name(module
->dir_name
, module
->file_name
);
1100 /** Note: if central storage is used the generated C++ files are placed
1101 * into the same directory as the TTCN-3/ASN.1 modules, otherwise the
1102 * files are generated into the working directory. */
1103 boolean is_same_dir
= is_same_directory(user
->dir_name
,
1104 makefile
->central_storage
? module
->dir_name
: NULL
);
1105 if (user
->header_name
!= NULL
) {
1106 char *u_pathname
= compose_path_name(user
->dir_name
,
1108 if (is_same_dir
&& user
->has_hh_suffix
) {
1109 WARNING("Header file `%s' is generated from module `%s' (file `%s'). "
1110 "Removing it from the list of user files.", u_pathname
,
1111 module
->module_name
, m_pathname
);
1113 ERROR("Header file `%s' cannot be used together with module `%s' "
1114 "(file `%s') in the same Makefile.", u_pathname
,
1115 module
->module_name
, m_pathname
);
1119 if (user
->source_name
!= NULL
) {
1120 char *u_pathname
= compose_path_name(user
->dir_name
,
1122 if (is_same_dir
&& user
->has_cc_suffix
) {
1123 WARNING("Source file `%s' is generated from module `%s' (file "
1124 "`%s'). Removing it from the list of user files.", u_pathname
,
1125 module
->module_name
, m_pathname
);
1127 ERROR("Source file `%s' cannot be used together with module "
1128 "`%s' (file `%s') in the same Makefile.", u_pathname
,
1129 module
->module_name
, m_pathname
);
1134 Free(user
->dir_name
);
1135 Free(user
->file_prefix
);
1136 Free(user
->header_name
);
1137 Free(user
->source_name
);
1138 makefile
->nUserFiles
--;
1139 memmove(user
, user
+ 1, (makefile
->nUserFiles
- i
) *
1140 sizeof(*makefile
->UserFiles
));
1141 makefile
->UserFiles
= (struct user_struct
*)Realloc(makefile
->UserFiles
,
1142 makefile
->nUserFiles
* sizeof(*makefile
->UserFiles
));
1149 /** Drops all C++ header and source files of the Makefile descriptor structure
1150 * \a makefile that are generated from its TTCN-3 or ASN.1 modules. */
1151 static void filter_out_generated_files(struct makefile_struct
*makefile
)
1154 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1155 drop_generated_files(makefile
, makefile
->TTCN3Modules
+ i
);
1157 if (makefile
->preprocess
) {
1158 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1159 drop_generated_files(makefile
, makefile
->TTCN3PPModules
+ i
);
1162 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1163 drop_generated_files(makefile
, makefile
->ASN1Modules
+ i
);
1167 /** Completes the list of user C/C++ header and source files in \a makefile.
1168 * If only the source file was given the function looks for the corresponding
1169 * header file or vice versa. */
1170 static void complete_user_files(const struct makefile_struct
*makefile
)
1173 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1174 struct user_struct
*user
= makefile
->UserFiles
+ i
;
1175 if (user
->header_name
== NULL
) {
1176 static const char * const suffix_list
[] = { "hh", "h", "hpp", NULL
};
1177 const char * const *suffix_ptr
;
1178 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
1179 char *file_name
= mprintf("%s.%s", user
->file_prefix
, *suffix_ptr
);
1180 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1181 if (get_path_status(path_name
) == PS_FILE
) {
1183 user
->header_name
= file_name
;
1184 if (!strcmp(*suffix_ptr
, "hh") || !strcmp(*suffix_ptr
, "hpp")) user
->has_hh_suffix
= TRUE
;
1190 } else if (user
->source_name
== NULL
) {
1191 static const char * const suffix_list
[] = { "cc", "c", "cpp", NULL
};
1192 const char * const *suffix_ptr
;
1193 for (suffix_ptr
= suffix_list
; *suffix_ptr
!= NULL
; suffix_ptr
++) {
1194 char *file_name
= mprintf("%s.%s", user
->file_prefix
, *suffix_ptr
);
1195 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1196 if (get_path_status(path_name
) == PS_FILE
) {
1198 user
->source_name
= file_name
;
1199 if (!strcmp(*suffix_ptr
, "cc") || !strcmp(*suffix_ptr
, "cpp")) user
->has_cc_suffix
= TRUE
;
1209 /** Converts the directory name pointed by \a dir_ptr to a relative pathname
1210 * based on \a working_dir. The original directory name is deallocated and
1211 * replaced with a new string. Nothing happens if \a dir_ptr points to NULL. */
1212 static void replace_dir_with_relative(char **dir_ptr
, const char *working_dir
)
1214 if (*dir_ptr
!= NULL
) {
1215 char *rel_dir
= get_relative_dir(*dir_ptr
, working_dir
);
1221 /** Converts the directory part of path name pointed by \a path_ptr to a relative
1222 * pathname based on \a working_dir. The original path name is deallocated and
1223 * replaced with a new string. */
1224 static void convert_path_to_relative(char **path_ptr
, const char *working_dir
)
1226 char *dir_name
= get_dir_name(*path_ptr
, working_dir
);
1227 if (dir_name
!= NULL
) {
1228 char *file_name
= get_file_from_path(*path_ptr
);
1229 replace_dir_with_relative(&dir_name
, working_dir
);
1231 *path_ptr
= compose_path_name(dir_name
, file_name
);
1237 /** Converts all directories used by the Makefile descriptor structure
1238 * \a makefile to relative pathnames based on the working directory stored in
1240 static void convert_dirs_to_relative(struct makefile_struct
*makefile
)
1243 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1244 replace_dir_with_relative(&makefile
->TTCN3Modules
[i
].dir_name
,
1245 makefile
->working_dir
);
1247 if (makefile
->preprocess
) {
1248 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1249 replace_dir_with_relative(&makefile
->TTCN3PPModules
[i
].dir_name
,
1250 makefile
->working_dir
);
1252 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++) {
1253 convert_path_to_relative(makefile
->TTCN3IncludeFiles
+ i
,
1254 makefile
->working_dir
);
1257 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1258 replace_dir_with_relative(&makefile
->ASN1Modules
[i
].dir_name
,
1259 makefile
->working_dir
);
1261 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1262 replace_dir_with_relative(&makefile
->UserFiles
[i
].dir_name
,
1263 makefile
->working_dir
);
1265 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) {
1266 convert_path_to_relative(makefile
->OtherFiles
+ i
, makefile
->working_dir
);
1268 if (makefile
->ets_name
!= NULL
)
1269 convert_path_to_relative(&makefile
->ets_name
, makefile
->working_dir
);
1272 /* Returns whether the string \a file_name contains special characters. */
1273 static boolean
has_special_chars(const char *file_name
)
1275 if (file_name
!= NULL
) {
1277 for (i
= 0; ; i
++) {
1278 int c
= (unsigned char)file_name
[i
];
1308 if (!isascii(c
) || !isprint(c
)) return TRUE
;
1316 /** Checks whether the path name composed of \a dir_name and \a file_name
1317 * contains special characters that are not allowed in the Makefile. Parameter
1318 * \a what contains the description of the corresponding file. */
1319 static void check_special_chars_in_path(const char *dir_name
,
1320 const char *file_name
, const char *what
)
1322 if (has_special_chars(dir_name
) || has_special_chars(file_name
)) {
1323 char *path_name
= compose_path_name(dir_name
, file_name
);
1324 ERROR("The name of %s `%s' contains special characters that cannot be "
1325 "handled properly by the `make' utility and/or the shell.", what
,
1331 /** Checks whether the directory names or file names that will be used in the
1332 * generated Makefile contain special characters that cannot be handled by the
1333 * "make" utility. */
1334 static void check_special_chars(const struct makefile_struct
*makefile
)
1337 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1338 check_special_chars_in_path(makefile
->TTCN3Modules
[i
].dir_name
,
1339 makefile
->TTCN3Modules
[i
].file_name
, "TTCN-3 file");
1341 if (makefile
->preprocess
) {
1342 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1343 check_special_chars_in_path(makefile
->TTCN3PPModules
[i
].dir_name
,
1344 makefile
->TTCN3PPModules
[i
].file_name
,
1345 "TTCN-3 file to be preprocessed");
1348 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1349 check_special_chars_in_path(makefile
->ASN1Modules
[i
].dir_name
,
1350 makefile
->ASN1Modules
[i
].file_name
, "ASN.1 file");
1352 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1353 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1354 if (user
->source_name
!= NULL
)
1355 check_special_chars_in_path(user
->dir_name
, user
->source_name
,
1356 "C/C++ source file");
1357 else check_special_chars_in_path(user
->dir_name
, user
->header_name
,
1358 "C/C++ header file");
1360 for (i
= 0; i
< makefile
->nOtherFiles
; i
++) {
1361 check_special_chars_in_path(NULL
, makefile
->OtherFiles
[i
], "other file");
1365 /** Adds base directory \a dir_name to Makefile descriptor structure
1366 * \a makefile. Flag \a has_modules indicates whether \a dir_name contains
1367 * TTCN-3 and/or ASN.1 modules. The new directory is ignored if it is already
1368 * added to \a makefile. */
1369 static void add_base_dir(struct makefile_struct
*makefile
,
1370 const char *dir_name
, boolean has_modules
)
1372 struct base_dir_struct
*base_dir
;
1373 if (dir_name
!= NULL
) {
1375 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1376 base_dir
= makefile
->BaseDirs
+ i
;
1377 if (!strcmp(dir_name
, base_dir
->dir_name
)) {
1378 if (has_modules
) base_dir
->has_modules
= TRUE
;
1382 makefile
->BaseDirs
= (struct base_dir_struct
*)Realloc(makefile
->BaseDirs
,
1383 (makefile
->nBaseDirs
+ 1) * sizeof(*makefile
->BaseDirs
));
1384 base_dir
= makefile
->BaseDirs
+ makefile
->nBaseDirs
;
1385 makefile
->nBaseDirs
++;
1386 base_dir
->dir_name
= dir_name
;
1387 base_dir
->has_modules
= has_modules
;
1391 /** Collects all directories that are used in the Makefile descriptor structure
1392 * \a makefile in order to use pre-compiled files from them. */
1393 static void collect_base_dirs(struct makefile_struct
*makefile
)
1396 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1397 add_base_dir(makefile
, makefile
->TTCN3Modules
[i
].dir_name
, TRUE
);
1399 if (makefile
->preprocess
) {
1400 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1401 add_base_dir(makefile
, makefile
->TTCN3PPModules
[i
].dir_name
, TRUE
);
1404 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1405 add_base_dir(makefile
, makefile
->ASN1Modules
[i
].dir_name
, TRUE
);
1407 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1408 add_base_dir(makefile
, makefile
->UserFiles
[i
].dir_name
, FALSE
);
1410 if (makefile
->nBaseDirs
== 0) {
1411 WARNING("Usage of pre-compiled files from central storage (option `-c') "
1412 "is enabled, but all given files are located in the current working "
1417 /** Checks whether the TTCN-3, ASN.1 and C++ files follow the default naming
1418 * convention and sets the appropriate flags accordingly. */
1419 static void check_naming_convention(struct makefile_struct
*makefile
)
1421 /* initially set all flags to true */
1422 makefile
->TTCN3ModulesRegular
= TRUE
;
1423 makefile
->BaseTTCN3ModulesRegular
= TRUE
;
1424 makefile
->ASN1ModulesRegular
= TRUE
;
1425 makefile
->BaseASN1ModulesRegular
= TRUE
;
1426 makefile
->UserHeadersRegular
= TRUE
;
1427 makefile
->UserSourcesRegular
= TRUE
;
1428 makefile
->BaseUserHeadersRegular
= TRUE
;
1429 makefile
->BaseUserSourcesRegular
= TRUE
;
1430 if (makefile
->central_storage
) {
1431 /* this project (Makefile) will use pre-compiled files from other
1434 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1435 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1436 if (module
->dir_name
!= NULL
) {
1437 if (!module
->is_regular
) makefile
->BaseTTCN3ModulesRegular
= FALSE
;
1439 if (!module
->is_regular
) makefile
->TTCN3ModulesRegular
= FALSE
;
1441 if (!makefile
->TTCN3ModulesRegular
&& !makefile
->BaseTTCN3ModulesRegular
)
1444 /* ttcnpp files are ttcn files */
1445 if ((makefile
->TTCN3ModulesRegular
|| makefile
->BaseTTCN3ModulesRegular
) &&
1446 makefile
->preprocess
) {
1447 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1448 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1449 if (module
->dir_name
!= NULL
) {
1450 if (!module
->is_regular
) makefile
->BaseTTCN3ModulesRegular
= FALSE
;
1452 if (!module
->is_regular
) makefile
->TTCN3ModulesRegular
= FALSE
;
1454 if (!makefile
->TTCN3ModulesRegular
&& !makefile
->BaseTTCN3ModulesRegular
)
1458 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1459 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1460 if (module
->dir_name
!= NULL
) {
1461 if (!module
->is_regular
) makefile
->BaseASN1ModulesRegular
= FALSE
;
1463 if (!module
->is_regular
) makefile
->ASN1ModulesRegular
= FALSE
;
1465 if (!makefile
->ASN1ModulesRegular
&& !makefile
->BaseASN1ModulesRegular
)
1468 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1469 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1470 if (user
->dir_name
!= NULL
) {
1471 if (!user
->has_cc_suffix
)
1472 makefile
->BaseUserSourcesRegular
= FALSE
;
1473 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1474 makefile
->BaseUserHeadersRegular
= FALSE
;
1476 if (!user
->has_cc_suffix
)
1477 makefile
->UserSourcesRegular
= FALSE
;
1478 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1479 makefile
->UserHeadersRegular
= FALSE
;
1481 if (!makefile
->UserHeadersRegular
&& !makefile
->UserSourcesRegular
&&
1482 !makefile
->BaseUserHeadersRegular
&&
1483 !makefile
->BaseUserSourcesRegular
) break;
1486 /* this project (Makefile) will-be stand-alone */
1488 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1489 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1490 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1491 makefile
->TTCN3ModulesRegular
= FALSE
;
1495 if (makefile
->TTCN3ModulesRegular
&& makefile
->preprocess
) {
1496 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1497 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1498 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1499 makefile
->TTCN3ModulesRegular
= FALSE
;
1504 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1505 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1506 if (!module
->is_regular
|| module
->dir_name
!= NULL
) {
1507 makefile
->ASN1ModulesRegular
= FALSE
;
1511 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
1512 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
1513 if (!user
->has_cc_suffix
)
1514 makefile
->UserSourcesRegular
= FALSE
;
1515 if (!user
->has_cc_suffix
|| !user
->has_hh_suffix
)
1516 makefile
->UserHeadersRegular
= FALSE
;
1517 if (!makefile
->UserHeadersRegular
&& !makefile
->UserSourcesRegular
)
1523 /** Prints the name of the TTCN-3 or ASN.1 source file that belongs to module
1524 * \a module to file \a fp. */
1525 static void print_file_name(FILE *fp
, const struct module_struct
*module
)
1527 char *path_name
= compose_path_name(module
->dir_name
, module
->file_name
);
1528 fprintf(fp
, " %s", path_name
);
1532 /** Prints the name of the preprocessed TTCN-3 source file that belongs to
1533 * module \a module to file \a fp. */
1534 static void print_preprocessed_file_name(FILE *fp
,
1535 const struct module_struct
*module
)
1537 char *preprocessed_name
= get_preprocessed_file_name(module
->file_name
);
1538 char *path_name
= compose_path_name(module
->dir_name
, preprocessed_name
);
1539 fprintf(fp
, " %s", path_name
);
1541 Free(preprocessed_name
);
1544 /** Prints the name of the generated header, source or object file of module
1545 * \a module to file \a fp. The name of the directory is added only if
1546 * \a add_directory is TRUE. Parameter \a suffix shall be "hh", "cc", "hpp", "cpp" or "o". */
1547 static void print_generated_file_name(FILE *fp
,
1548 const struct module_struct
*module
, boolean add_directory
, const char *suffix
)
1550 char *file_name
= mcopystr(module
->module_name
);
1551 /* replace '-' with '_' */
1553 for (i
= 0; file_name
[i
] != '\0'; i
++)
1554 if (file_name
[i
] == '-') file_name
[i
] = '_';
1555 /* append the suffix */
1556 file_name
= mputprintf(file_name
, "%s", suffix
);
1557 /* add the directory name if necessary */
1558 if (add_directory
) {
1559 char *path_name
= compose_path_name(module
->dir_name
, file_name
);
1561 file_name
= path_name
;
1563 fprintf(fp
, " %s", file_name
);
1567 /** Prints the name of the user C/C++ header file of user module \a user if the
1568 * above file exists. */
1569 static void print_header_name(FILE *fp
, const struct user_struct
*user
)
1571 if (user
->header_name
!= NULL
) {
1572 char *path_name
= compose_path_name(user
->dir_name
, user
->header_name
);
1573 fprintf(fp
, " %s", path_name
);
1578 /** Prints the name of the user C/C++ source file of user module \a user if the
1579 * above file exists. */
1580 static void print_source_name(FILE *fp
, const struct user_struct
*user
)
1582 if (user
->source_name
!= NULL
) {
1583 char *path_name
= compose_path_name(user
->dir_name
, user
->source_name
);
1584 fprintf(fp
, " %s", path_name
);
1589 /** Prints the name of the user C/C++ object file of user module \a user if the
1590 * above file exists (i.e. the respective source file is present). */
1591 static void print_object_name(FILE *fp
, const struct user_struct
*user
)
1593 if (user
->source_name
!= NULL
) {
1594 char *file_name
= mprintf("%s.o", user
->file_prefix
);
1595 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1597 fprintf(fp
, " %s", path_name
);
1602 static void print_shared_object_name(FILE *fp
, const struct user_struct
*user
)
1604 if (user
->source_name
!= NULL
) {
1605 char *file_name
= mprintf("%s.so", user
->file_prefix
);
1606 char *path_name
= compose_path_name(user
->dir_name
, file_name
);
1608 fprintf(fp
, " %s", path_name
);
1612 /** Prints the splitted files' names for a given module. */
1613 static void print_splitted_file_names(FILE *fp
,
1614 const struct makefile_struct
*makefile
, const struct module_struct
*module
)
1616 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
1617 print_generated_file_name(fp
, module
, FALSE
, "_seq.cc");
1618 print_generated_file_name(fp
, module
, FALSE
, "_set.cc");
1619 print_generated_file_name(fp
, module
, FALSE
, "_seqof.cc");
1620 print_generated_file_name(fp
, module
, FALSE
, "_setof.cc");
1621 print_generated_file_name(fp
, module
, FALSE
, "_union.cc");
1625 static void fprint_extra_targets(FILE* fp
, struct string2_list
* target_placement_list
, const char* placement
)
1627 struct string2_list
* act_elem
= target_placement_list
;
1629 if (act_elem
->str1
&& act_elem
->str2
&& (strcmp(act_elem
->str2
,placement
)==0)) {
1630 fprintf(fp
, " %s", act_elem
->str1
);
1632 act_elem
= act_elem
->next
;
1636 #undef COMMENT_PREFIX
1637 #define COMMENT_PREFIX "# "
1639 /** Prints the Makefile based on structure \a makefile. */
1640 static void print_makefile(struct makefile_struct
*makefile
)
1642 boolean add_refd_prjs
= makefile
->sub_project_dirs
&& makefile
->sub_project_dirs
->str
;
1644 NOTIFY("Generating Makefile skeleton...");
1646 if (makefile
->force_overwrite
||
1647 get_path_status(makefile
->output_file
) == PS_NONEXISTENT
) {
1652 const char *rm_command
= makefile
->gnu_make
? "$(RM)" : "rm -f";
1654 boolean run_compiler
= (makefile
->nASN1Modules
> 0)
1655 || (makefile
->nTTCN3Modules
) || (makefile
->nTTCN3PPModules
> 0);
1657 expstring_t titan_dir
= 0;
1658 const char * last_slash
= strrchr(program_name
, '/');
1659 if (last_slash
!= NULL
) {
1660 size_t path_len
= last_slash
- program_name
;
1661 titan_dir
= mcopystr(program_name
);
1662 /* Chop off the program name, and the /bin before it (if any) */
1664 && memcmp(titan_dir
+ path_len
- 4, "/bin", 4) == 0) {
1665 titan_dir
= mtruncstr(titan_dir
, path_len
- 4);
1668 titan_dir
= mtruncstr(titan_dir
, path_len
);
1673 fp
= fopen(makefile
->output_file
, "w");
1675 ERROR("Cannot open output file `%s' for writing: %s",
1676 makefile
->output_file
, strerror(errno
));
1679 user_info
= get_user_info();
1680 fprintf(fp
, "# This Makefile was generated by the Makefile Generator\n"
1681 "# of the TTCN-3 Test Executor version " PRODUCT_NUMBER
"\n"
1683 COPYRIGHT_STRING
"\n\n"
1684 "# The following make commands are available:\n"
1685 "# - make, make all Builds the %s.\n"
1686 "# - make archive Archives all source files.\n"
1687 "# - make check Checks the semantics of TTCN-3 and ASN.1 "
1689 "# - make clean Removes all generated files.\n"
1690 "# - make compile Translates TTCN-3 and ASN.1 modules to C++.\n"
1691 "# - make dep Creates/updates dependency list.\n"
1692 "# - make executable Builds the executable test suite.\n"
1693 "# - make library Builds the library archive.\n"
1694 "# - make objects Builds the object files without linking the "
1695 "executable.\n", user_info
,
1696 makefile
->library
? "library archive." : "executable test suite");
1698 if (makefile
->dynamic
)
1699 fprintf(fp
, "# - make shared_objects Builds the shared object files "
1700 "without linking the executable.\n");
1701 if (makefile
->preprocess
)
1702 fputs("# - make preprocess Preprocess TTCN-3 files.\n", fp
);
1703 if (makefile
->central_storage
) {
1704 fputs("# WARNING! This Makefile uses pre-compiled files from the "
1705 "following directories:\n", fp
);
1706 for (i
= 0; i
< makefile
->nBaseDirs
; i
++)
1707 fprintf(fp
, "# %s\n", makefile
->BaseDirs
[i
].dir_name
);
1708 fputs("# The executable tests will be consistent only if all directories "
1710 "# the same platform and the same version of TTCN-3 Test Executor "
1712 "# C++ compiler with the same command line switches.\n\n", fp
);
1714 if (makefile
->gnu_make
) {
1715 fputs("# WARNING! This Makefile can be used with GNU make only.\n"
1716 "# Other versions of make may report syntax errors in it.\n\n"
1718 "# Do NOT touch this line...\n"
1720 ".PHONY: all shared_objects executable library objects check clean dep archive", fp
);
1721 if (makefile
->preprocess
) fputs(" preprocess", fp
);
1722 if (add_refd_prjs
) {
1723 fputs("\\\n referenced-all referenced-shared_objects referenced-executable referenced-library referenced-objects referenced-check"
1724 "\\\n referenced-clean referenced-archive", fp
);
1726 fprint_extra_targets(fp
, makefile
->target_placement_list
, "PHONY");
1728 if (makefile
->gcc_dep
) {
1729 fputs("\n\n.SUFFIXES: .d", fp
);
1734 if (add_refd_prjs
) {
1735 struct string_list
* act_elem
= makefile
->sub_project_dirs
;
1736 fputs("# This is the top level makefile of a Makefile hierarchy generated from\n"
1737 "# a Titan Project Descriptor hierarchy. List of referenced project\n"
1738 "# working directories (ordered by dependencies):\n", fp
);
1740 if (act_elem
->str
) {
1741 fprintf(fp
, "# %s\n", act_elem
->str
);
1743 act_elem
= act_elem
->next
;
1745 fputs("REFERENCED_PROJECT_DIRS = ", fp
);
1746 act_elem
= makefile
->sub_project_dirs
;
1748 if (act_elem
->str
) {
1749 fprintf(fp
, "%s ", act_elem
->str
);
1751 act_elem
= act_elem
->next
;
1757 "# Set these variables...\n"
1759 "# The path of your TTCN-3 Test Executor installation:\n"
1760 "# Uncomment this line to override the environment variable.\n"
1762 "# TTCN3_DIR = %s\n"
1764 "# The value below points to the location of the TITAN version\n"
1765 "# that generated this makefile.\n" : ""
1766 , titan_dir
? titan_dir
: "");
1767 if (titan_dir
) Free(titan_dir
);
1769 if (makefile
->cxxcompiler
) {
1770 cxx
= makefile
->cxxcompiler
;
1775 fprintf(fp
, "\n# Your platform: (SOLARIS, SOLARIS8, LINUX, FREEBSD or "
1778 "# Your C++ compiler:\n"
1779 "# (if you change the platform, you may need to change the compiler)\n"
1780 "CXX = %s \n\n", get_platform_string(), cxx
);
1783 if (makefile
->preprocess
|| makefile
->ttcn3preprocessor
) {
1784 if (makefile
->ttcn3preprocessor
) {
1785 cpp
= makefile
->ttcn3preprocessor
;
1789 fprintf(fp
,"# C preprocessor used for TTCN-3 files:\n"
1790 "CPP = %s\n\n", cpp
);
1793 fputs("# Flags for the C++ preprocessor (and makedepend as well):\n"
1794 "CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)/include", fp
);
1796 if (makefile
->use_runtime_2
) fputs(" -DTITAN_RUNTIME_2", fp
);
1798 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1799 fprintf(fp
, " -I%s", makefile
->BaseDirs
[i
].dir_name
);
1802 if (makefile
->prep_includes
) {
1803 struct string_list
* act_elem
= makefile
->prep_includes
;
1805 if (act_elem
->str
) {
1806 fprintf(fp
, " -I%s", act_elem
->str
);
1808 act_elem
= act_elem
->next
;
1812 if (makefile
->prep_defines
) {
1813 struct string_list
* act_elem
= makefile
->prep_defines
;
1815 if (act_elem
->str
) {
1816 fprintf(fp
, " -D%s", act_elem
->str
);
1818 act_elem
= act_elem
->next
;
1824 if (makefile
->gcc_dep
) {
1825 fprintf(fp
, "# Flags for dependency generation\n"
1826 "CXXDEPFLAGS = -%s\n\n", strstr(cxx
, "g++") ? "MM" : "xM1");
1829 if (makefile
->preprocess
|| makefile
->ttcn3_prep_includes
|| makefile
->ttcn3_prep_defines
) {
1830 fputs("# Flags for preprocessing TTCN-3 files:\n"
1831 "CPPFLAGS_TTCN3 =", fp
);
1833 if (makefile
->preprocess
) {
1834 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
1835 fprintf(fp
, " -I%s", makefile
->BaseDirs
[i
].dir_name
);
1838 if (makefile
->ttcn3_prep_includes
) {
1839 struct string_list
* act_elem
= makefile
->ttcn3_prep_includes
;
1841 if (act_elem
->str
) {
1842 fprintf(fp
, " -I%s", act_elem
->str
);
1844 act_elem
= act_elem
->next
;
1847 if (makefile
->ttcn3_prep_defines
) {
1848 struct string_list
* act_elem
= makefile
->ttcn3_prep_defines
;
1850 if (act_elem
->str
) {
1851 fprintf(fp
, " -D%s", act_elem
->str
);
1853 act_elem
= act_elem
->next
;
1859 /* code splitting: command line argument wins */
1860 if (makefile
->code_splitting_mode
== NULL
) {
1861 if (makefile
->codesplittpd
) {
1862 makefile
->code_splitting_mode
= mcopystr("-U type");
1866 fprintf(fp
, "# Flags for the C++ compiler:\n"
1867 "CXXFLAGS = %s%s %s %s\n\n"
1868 "# Flags for the linker:\n"
1869 "LDFLAGS = %s%s\n\n"
1870 "ifeq ($(PLATFORM), WIN32)\n"
1871 "# Silence linker warnings.\n"
1872 "LDFLAGS += -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc\n"
1874 "# Utility to create library files\n"
1877 "# Flags for the TTCN-3 and ASN.1 compiler:\n"
1878 "COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s %s\n\n"
1879 "# Execution mode: (either ttcn3 or ttcn3-parallel)\n"
1880 "TTCN3_LIB = ttcn3%s%s%s\n\n"
1882 "# The path of your OpenSSL installation:\n"
1883 "# If you do not have your own one, leave it unchanged.\n"
1884 "OPENSSL_DIR = $(TTCN3_DIR)\n\n"
1886 "# The path of your libxml2 installation:\n"
1887 "# If you do not have your own one, leave it unchanged.\n"
1888 "XMLDIR = $(TTCN3_DIR)\n\n"
1889 "# Directory to store the archived source files:\n",
1890 makefile
->dynamic
? "-Wall -fPIC" : "-Wall", /* CXXFLAGS */
1891 makefile
->coverage
? " -fprofile-arcs -ftest-coverage -g" : "", /* CXXFLAGS COVERAGE */
1892 makefile
->optlevel
? makefile
->optlevel
: "", /* CXXFLAGS optimization level */
1893 makefile
->optflags
? makefile
->optflags
: "", /* CXXFLAGS optimization level */
1894 makefile
->dynamic
? "-fPIC" : "", /* LDFLAGS */
1895 makefile
->coverage
? " -fprofile-arcs -ftest-coverage -g -lgcov" : "", /* LDFLAGS COVERAGE */
1896 /* COMPILER_FLAGS */
1897 makefile
->use_runtime_2
? " -L -R " : " -L ",
1898 (makefile
->code_splitting_mode
? makefile
->code_splitting_mode
: ""),
1899 (makefile
->quietly
? " -q" : ""),
1900 (makefile
->disablesubtypecheck
? " -y" : ""),
1901 (makefile
->disableber
? " -b" : ""),
1902 (makefile
->disableraw
? " -r" : ""),
1903 (makefile
->disabletext
? " -x" : ""),
1904 (makefile
->disablexer
? " -X" : ""),
1905 (makefile
->disablejson
? " -j" : ""),
1906 (makefile
->forcexerinasn
? " -a" : ""),
1907 (makefile
->defaultasomit
? " -d" : ""),
1908 (makefile
->gccmsgformat
? " -g" : ""),
1909 (makefile
->linenumbersonlymsg
? " -i" : ""),
1910 (makefile
->includesourceinfo
? " -l" : ""),
1911 /*(makefile->addsourcelineinfo ? " -L" : ""),*/
1912 (makefile
->suppresswarnings
? " -w" : ""),
1913 (makefile
->outparamboundness
? " -Y" : ""),
1914 (makefile
->tcov_file_name
? makefile
->tcov_file_name
: ""),
1915 /* end of COMPILER FLAGS */
1916 (makefile
->use_runtime_2
? "-rt2" : ""), /* TTCN3_LIB */
1917 (makefile
->single_mode
? "" : "-parallel"),
1918 (makefile
->dynamic
? "-dynamic": "")
1920 if (!makefile
->gnu_make
) {
1921 fputs("# Note: you can set any directory except ./archive\n", fp
);
1923 fputs("ARCHIVE_DIR = backup\n\n"
1925 "# You may change these variables. Add your files if necessary...\n"
1927 "# TTCN-3 modules of this project:\n"
1928 "TTCN3_MODULES =", fp
);
1929 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1930 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1931 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
1932 /* If the file is in the current directory or
1933 * is not in the current directory but central directory is not used,
1934 * it goes into TTCN3_MODULES */
1935 print_file_name(fp
, module
);
1937 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_MODULES");
1938 if (makefile
->preprocess
) {
1940 "# TTCN-3 modules to preprocess:\n"
1941 "TTCN3_PP_MODULES =", fp
);
1942 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1943 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1944 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
1945 print_file_name(fp
, module
);
1947 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_PP_MODULES");
1949 if (makefile
->central_storage
) {
1951 "# TTCN-3 modules used from central project(s):\n"
1952 "BASE_TTCN3_MODULES =", fp
);
1953 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
1954 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
1955 /* Central storage used AND file is not in the current directory =>
1956 * it goes into BASE_TTCN3_MODULES */
1957 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
1959 if (makefile
->preprocess
) {
1961 "# TTCN-3 modules to preprocess used from central project(s):\n"
1962 "BASE_TTCN3_PP_MODULES =", fp
);
1963 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
1964 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
1965 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
1969 if (makefile
->preprocess
) {
1971 "# Files to include in TTCN-3 preprocessed modules:\n"
1972 "TTCN3_INCLUDES =", fp
);
1973 for (i
= 0; i
< makefile
->nTTCN3IncludeFiles
; i
++)
1974 fprintf(fp
, " %s", makefile
->TTCN3IncludeFiles
[i
]);
1975 fprint_extra_targets(fp
, makefile
->target_placement_list
, "TTCN3_INCLUDES");
1978 "# ASN.1 modules of this project:\n"
1979 "ASN1_MODULES =", fp
);
1980 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1981 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1982 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
1983 print_file_name(fp
, module
);
1985 fprint_extra_targets(fp
, makefile
->target_placement_list
, "ASN1_MODULES");
1986 if (makefile
->central_storage
) {
1988 "# ASN.1 modules used from central project(s):\n"
1989 "BASE_ASN1_MODULES =", fp
);
1990 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
1991 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
1992 if (module
->dir_name
!= NULL
) print_file_name(fp
, module
);
1995 if (makefile
->preprocess
) {
1997 "# TTCN-3 source files generated by the C preprocessor:\n"
1998 "PREPROCESSED_TTCN3_MODULES =", fp
);
1999 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2000 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2001 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2002 print_preprocessed_file_name(fp
, module
);
2004 if (makefile
->central_storage
) {
2006 "# TTCN-3 files generated by the CPP used from central project(s):\n"
2007 "BASE_PREPROCESSED_TTCN3_MODULES =", fp
);
2008 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2009 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2010 if (module
->dir_name
!= NULL
)
2011 print_preprocessed_file_name(fp
, module
);
2016 "# C++ source & header files generated from the TTCN-3 & ASN.1 "
2019 "GENERATED_SOURCES =", fp
);
2020 if (makefile
->gnu_make
&& makefile
->TTCN3ModulesRegular
) {
2021 fputs(" $(TTCN3_MODULES:.ttcn=.cc)", fp
);
2022 if (makefile
->code_splitting_mode
) {
2023 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2024 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2025 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2026 print_splitted_file_names(fp
, makefile
, module
);
2029 if (makefile
->preprocess
) {
2030 fputs(" $(TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2031 if (makefile
->code_splitting_mode
) {
2032 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2033 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2034 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2035 print_splitted_file_names(fp
, makefile
, module
);
2040 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2041 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2042 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2043 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2044 if (makefile
->code_splitting_mode
)
2045 print_splitted_file_names(fp
, makefile
, module
);
2048 if (makefile
->preprocess
) {
2049 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2050 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2051 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2052 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2053 if (makefile
->code_splitting_mode
)
2054 print_splitted_file_names(fp
, makefile
, module
);
2059 if (makefile
->gnu_make
&& makefile
->ASN1ModulesRegular
) {
2060 fputs(" $(ASN1_MODULES:.asn=.cc)", fp
);
2061 if (makefile
->code_splitting_mode
) {
2062 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2063 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2064 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2065 print_splitted_file_names(fp
, makefile
, module
);
2070 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2071 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2072 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2073 print_generated_file_name(fp
, module
, FALSE
, ".cc");
2074 if (makefile
->code_splitting_mode
)
2075 print_splitted_file_names(fp
, makefile
, module
);
2080 fputs("\nGENERATED_HEADERS =", fp
);
2081 if (makefile
->gnu_make
) {
2082 fputs(" $(GENERATED_SOURCES:.cc=.hh)", fp
);
2084 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2085 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2086 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2087 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2089 if (makefile
->preprocess
) {
2090 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2091 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2092 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2093 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2096 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2097 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2098 if (module
->dir_name
== NULL
|| !makefile
->central_storage
)
2099 print_generated_file_name(fp
, module
, FALSE
, ".hh");
2102 if (makefile
->central_storage
) {
2104 "# C++ source & header files generated from the TTCN-3 & ASN.1 "
2106 "# central project(s):\n"
2107 "BASE_GENERATED_SOURCES =", fp
);
2108 if (makefile
->gnu_make
&& makefile
->BaseTTCN3ModulesRegular
) {
2109 fputs(" $(BASE_TTCN3_MODULES:.ttcn=.cc)", fp
);
2110 if (makefile
->code_splitting_mode
) {
2111 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2112 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2113 if (module
->dir_name
!= NULL
) {
2114 print_splitted_file_names(fp
, makefile
, module
);
2118 if (makefile
->preprocess
) {
2119 fputs(" $(BASE_TTCN3_PP_MODULES:.ttcnpp=.cc)", fp
);
2120 if (makefile
->code_splitting_mode
) {
2121 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2122 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2123 if (module
->dir_name
!= NULL
) {
2124 print_splitted_file_names(fp
, makefile
, module
);
2130 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2131 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2132 if (module
->dir_name
!= NULL
) {
2133 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2134 if (makefile
->code_splitting_mode
)
2135 print_splitted_file_names(fp
, makefile
, module
);
2138 if (makefile
->preprocess
) {
2139 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2140 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2141 if (module
->dir_name
!= NULL
) {
2142 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2143 if (makefile
->code_splitting_mode
)
2144 print_splitted_file_names(fp
, makefile
, module
);
2149 if (makefile
->gnu_make
&& makefile
->BaseASN1ModulesRegular
) {
2150 fputs(" $(BASE_ASN1_MODULES:.asn=.cc)", fp
);
2151 if (makefile
->code_splitting_mode
) {
2152 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2153 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2154 if (module
->dir_name
!= NULL
) {
2155 print_splitted_file_names(fp
, makefile
, module
);
2160 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2161 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2162 if (module
->dir_name
!= NULL
) {
2163 print_generated_file_name(fp
, module
, TRUE
, ".cc");
2164 if (makefile
->code_splitting_mode
)
2165 print_splitted_file_names(fp
, makefile
, module
);
2169 fputs("\nBASE_GENERATED_HEADERS =", fp
);
2170 if (makefile
->gnu_make
) {
2171 fputs(" $(BASE_GENERATED_SOURCES:.cc=.hh)", fp
);
2173 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2174 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2175 if (module
->dir_name
!= NULL
)
2176 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2178 if (makefile
->preprocess
) {
2179 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2180 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2181 if (module
->dir_name
!= NULL
)
2182 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2185 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2186 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2187 if (module
->dir_name
!= NULL
)
2188 print_generated_file_name(fp
, module
, TRUE
, ".hh");
2193 "# C/C++ Source & header files of Test Ports, external functions "
2195 "# other modules:\n"
2196 "USER_SOURCES =", fp
);
2197 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2198 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2199 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2200 print_source_name(fp
, user
);
2202 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_SOURCES");
2203 fputs("\nUSER_HEADERS =", fp
);
2204 if (makefile
->gnu_make
&& makefile
->UserHeadersRegular
) {
2205 fputs(" $(USER_SOURCES:.cc=.hh)", fp
);
2207 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2208 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2209 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2210 print_header_name(fp
, user
);
2213 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_HEADERS");
2214 if (makefile
->central_storage
) {
2216 "# C/C++ Source & header files of Test Ports, external functions "
2218 "# other modules used from central project(s):\n"
2219 "BASE_USER_SOURCES =", fp
);
2220 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2221 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2222 if (user
->dir_name
!= NULL
)
2223 print_source_name(fp
, user
);
2225 fputs("\nBASE_USER_HEADERS =", fp
);
2226 if (makefile
->gnu_make
&& makefile
->BaseUserHeadersRegular
) {
2227 fputs(" $(BASE_USER_SOURCES:.cc=.hh)", fp
);
2229 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2230 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2231 if (user
->dir_name
!= NULL
)
2232 print_header_name(fp
, user
);
2237 if (makefile
->dynamic
) {
2239 "# Shared object files of this project:\n"
2240 "SHARED_OBJECTS =", fp
);
2241 if (makefile
->gnu_make
) {
2242 fputs(" $(GENERATED_SOURCES:.cc=.so)", fp
);
2244 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2245 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2246 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2247 print_generated_file_name(fp
, module
, FALSE
, ".so");
2248 if (makefile
->code_splitting_mode
!= NULL
)
2249 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2250 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2251 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2252 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2253 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2254 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2258 if (makefile
->preprocess
) {
2259 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2260 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2261 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2262 print_generated_file_name(fp
, module
, FALSE
, ".so");
2263 if (makefile
->code_splitting_mode
!= NULL
)
2264 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2265 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2266 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2267 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2268 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2269 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2274 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2275 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2276 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2277 print_generated_file_name(fp
, module
, FALSE
, ".so");
2278 if (makefile
->code_splitting_mode
!= NULL
)
2279 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2280 print_generated_file_name(fp
, module
, FALSE
, "_seq.so");
2281 print_generated_file_name(fp
, module
, FALSE
, "_set.so");
2282 print_generated_file_name(fp
, module
, FALSE
, "_seqof.so");
2283 print_generated_file_name(fp
, module
, FALSE
, "_setof.so");
2284 print_generated_file_name(fp
, module
, FALSE
, "_union.so");
2289 if (makefile
->gnu_make
&& makefile
->UserSourcesRegular
) {
2290 fputs(" $(USER_SOURCES:.cc=.so)", fp
);
2292 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2293 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2294 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2295 print_shared_object_name(fp
, user
);
2301 "# Object files of this project that are needed for the executable "
2303 "OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)\n\n" /* never := */
2304 "GENERATED_OBJECTS =", fp
);
2305 if (makefile
->gnu_make
) {
2306 fputs(" $(GENERATED_SOURCES:.cc=.o)", fp
);
2308 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2309 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2310 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2311 print_generated_file_name(fp
, module
, FALSE
, ".o");
2312 if (makefile
->code_splitting_mode
!= NULL
)
2313 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2314 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2315 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2316 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2317 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2318 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2322 if (makefile
->preprocess
) {
2323 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2324 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2325 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2326 print_generated_file_name(fp
, module
, FALSE
, ".o");
2327 if (makefile
->code_splitting_mode
!= NULL
)
2328 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2329 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2330 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2331 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2332 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2333 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2338 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2339 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2340 if (module
->dir_name
== NULL
|| !makefile
->central_storage
) {
2341 print_generated_file_name(fp
, module
, FALSE
, ".o");
2342 if (makefile
->code_splitting_mode
!= NULL
)
2343 if (strcmp(makefile
->code_splitting_mode
, "-U type") == 0) {
2344 print_generated_file_name(fp
, module
, FALSE
, "_seq.o");
2345 print_generated_file_name(fp
, module
, FALSE
, "_set.o");
2346 print_generated_file_name(fp
, module
, FALSE
, "_seqof.o");
2347 print_generated_file_name(fp
, module
, FALSE
, "_setof.o");
2348 print_generated_file_name(fp
, module
, FALSE
, "_union.o");
2354 fputs("\n\nUSER_OBJECTS =", fp
);
2355 if (makefile
->gnu_make
&& makefile
->UserSourcesRegular
) {
2356 fputs(" $(USER_SOURCES:.cc=.o)", fp
);
2358 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2359 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2360 if (user
->dir_name
== NULL
|| !makefile
->central_storage
)
2361 print_object_name(fp
, user
);
2364 fprint_extra_targets(fp
, makefile
->target_placement_list
, "USER_OBJECTS");
2366 if (makefile
->gcc_dep
) {
2367 /* GNU Make processes included makefiles in reverse order. By putting
2368 * user sources first, their .d will be generated last, after the
2369 * GENERATED_SOURCES (and GENERATED_HEADERS) have been created.
2370 * This avoid spurious errors during incremental dependency generation */
2371 fputs("\n\nDEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d)", fp
);
2374 if (makefile
->central_storage
) {
2375 if (makefile
->dynamic
) {
2377 "# Shared object files of central project(s):\n"
2378 "BASE_SHARED_OBJECTS =", fp
);
2379 if (makefile
->gnu_make
) {
2380 fputs(" $(BASE_GENERATED_SOURCES:.cc=.so)", fp
);
2382 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2383 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2384 if (module
->dir_name
!= NULL
)
2385 print_generated_file_name(fp
, module
, TRUE
, ".so");
2387 if (makefile
->preprocess
) {
2388 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2389 const struct module_struct
*module
=
2390 makefile
->TTCN3PPModules
+ i
;
2391 if (module
->dir_name
!= NULL
)
2392 print_generated_file_name(fp
, module
, TRUE
, ".so");
2395 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2396 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2397 if (module
->dir_name
!= NULL
)
2398 print_generated_file_name(fp
, module
, TRUE
, ".so");
2401 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2402 fputs(" $(BASE_USER_SOURCES:.cc=.so)", fp
);
2404 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2405 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2406 if (user
->dir_name
!= NULL
)
2407 print_shared_object_name(fp
, user
);
2412 "# Object files of central project(s) that are needed for the "
2413 "executable test suite:\n"
2414 "BASE_OBJECTS =", fp
);
2415 if (makefile
->gnu_make
) {
2416 fputs(" $(BASE_GENERATED_SOURCES:.cc=.o)", fp
);
2418 for (i
= 0; i
< makefile
->nTTCN3Modules
; i
++) {
2419 const struct module_struct
*module
= makefile
->TTCN3Modules
+ i
;
2420 if (module
->dir_name
!= NULL
)
2421 print_generated_file_name(fp
, module
, TRUE
, ".o");
2423 if (makefile
->preprocess
) {
2424 for (i
= 0; i
< makefile
->nTTCN3PPModules
; i
++) {
2425 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ i
;
2426 if (module
->dir_name
!= NULL
)
2427 print_generated_file_name(fp
, module
, TRUE
, ".o");
2430 for (i
= 0; i
< makefile
->nASN1Modules
; i
++) {
2431 const struct module_struct
*module
= makefile
->ASN1Modules
+ i
;
2432 if (module
->dir_name
!= NULL
)
2433 print_generated_file_name(fp
, module
, TRUE
, ".o");
2436 if (makefile
->gnu_make
&& makefile
->BaseUserSourcesRegular
) {
2437 fputs(" $(BASE_USER_SOURCES:.cc=.o)", fp
);
2439 for (i
= 0; i
< makefile
->nUserFiles
; i
++) {
2440 const struct user_struct
*user
= makefile
->UserFiles
+ i
;
2441 if (user
->dir_name
!= NULL
)
2442 print_object_name(fp
, user
);
2447 "# Other files of the project (Makefile, configuration files, etc.)\n"
2448 "# that will be added to the archived source files:\n"
2449 "OTHER_FILES =", fp
);
2450 for (i
= 0; i
< makefile
->nOtherFiles
; i
++)
2451 fprintf(fp
, " %s", makefile
->OtherFiles
[i
]);
2452 fprint_extra_targets(fp
, makefile
->target_placement_list
, "OTHER_FILES");
2454 if (makefile
->ets_name
) {
2455 const char *ets_suffix
= NULL
;
2456 /* EXECUTABLE variable */
2458 "# The name of the executable test suite:\n"
2459 "EXECUTABLE = %s", makefile
->ets_name
);
2462 /* add the .exe suffix unless it is already present */
2463 ets_suffix
= get_suffix(makefile
->ets_name
);
2464 if (ets_suffix
== NULL
|| strcmp(ets_suffix
, "exe"))
2470 /* LIBRARY variable */
2471 ets_suffix
= get_suffix(makefile
->ets_name
);
2472 if (ets_suffix
!= NULL
&& !strcmp(ets_suffix
, "exe")) {
2473 char* name_prefix
= cut_suffix(makefile
->ets_name
);
2474 fprintf(fp
, "\n\nLIBRARY = %s%s\n", name_prefix
? name_prefix
: "library",
2475 makefile
->dynamic
? "_lib.so" : ".a");
2478 fprintf(fp
, "\n\nLIBRARY = %s%s\n", makefile
->ets_name
,
2479 makefile
->dynamic
? "_lib.so" : ".a");
2484 "# The name of the executable test suite:\n"
2490 "TARGET = $(%s)", makefile
->library
? "LIBRARY" : "EXECUTABLE");
2494 "# Do not modify these unless you know what you are doing...\n"
2495 "# Platform specific additional libraries:\n"
2498 fputs("SOLARIS_LIBS = -lsocket -lnsl -lxml2", fp
);
2500 fputs(" -lresolv", fp
);
2502 if (makefile
->solspeclibraries
) {
2503 struct string_list
* act_elem
= makefile
->solspeclibraries
;
2505 if (act_elem
->str
) {
2506 fprintf(fp
, " -l%s", act_elem
->str
);
2508 act_elem
= act_elem
->next
;
2513 fputs("SOLARIS8_LIBS = -lsocket -lnsl -lxml2", fp
);
2515 fputs(" -lresolv", fp
);
2517 if (makefile
->sol8speclibraries
) {
2518 struct string_list
* act_elem
= makefile
->sol8speclibraries
;
2520 if (act_elem
->str
) {
2521 fprintf(fp
, " -l%s", act_elem
->str
);
2523 act_elem
= act_elem
->next
;
2528 fputs("LINUX_LIBS = -lxml2", fp
);
2530 fputs(" -lpthread -lrt", fp
);
2532 if (makefile
->linuxspeclibraries
) {
2533 struct string_list
* act_elem
= makefile
->linuxspeclibraries
;
2535 if (act_elem
->str
) {
2536 fprintf(fp
, " -l%s", act_elem
->str
);
2538 act_elem
= act_elem
->next
;
2543 fputs("FREEBSD_LIBS = -lxml2", fp
);
2544 if (makefile
->freebsdspeclibraries
) {
2545 struct string_list
* act_elem
= makefile
->freebsdspeclibraries
;
2547 if (act_elem
->str
) {
2548 fprintf(fp
, " -l%s", act_elem
->str
);
2550 act_elem
= act_elem
->next
;
2555 fputs("WIN32_LIBS = -lxml2", fp
);
2556 if (makefile
->win32speclibraries
) {
2557 struct string_list
* act_elem
= makefile
->win32speclibraries
;
2559 if (act_elem
->str
) {
2560 fprintf(fp
, " -l%s", act_elem
->str
);
2562 act_elem
= act_elem
->next
;
2568 "# Rules for building the executable...\n"
2570 fprintf(fp
, "all:%s $(TARGET) ;\n\n", add_refd_prjs
?" referenced-all":"");
2572 if (makefile
->dynamic
) {
2573 fprintf(fp
, "shared_objects:%s $(SHARED_OBJECTS) ;\n\n", add_refd_prjs
?" referenced-shared_objects":"");
2577 "executable:%s $(EXECUTABLE) ;\n\n"
2578 "library:%s $(LIBRARY) ;\n\n"
2579 "objects:%s $(OBJECTS) compile;\n\n", add_refd_prjs
?" referenced-executable":"", add_refd_prjs
?" referenced-library":"", add_refd_prjs
?" referenced-objects":"");
2581 /* target $(EXECUTABLE) */
2582 if (makefile
->dynamic
&& makefile
->library
) {
2583 /* There is no need to create the .so for all the source files */
2584 fputs("$(EXECUTABLE): $(LIBRARY)\n"
2585 "\tif $(CXX) $(LDFLAGS) -o $@ $(LIBRARY)", fp
);
2587 fprintf(fp
, "$(EXECUTABLE): %s", makefile
->dynamic
? "$(SHARED_OBJECTS)" : "$(OBJECTS)");
2588 if (makefile
->central_storage
) {
2589 if (makefile
->dynamic
) {
2590 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
2592 fputs(" $(BASE_OBJECTS)", fp
);
2596 "\tif $(CXX) $(LDFLAGS) -o $@ ", fp
); /* start writing the link step */
2597 if (makefile
->gnu_make
) fputs("$^", fp
);
2599 if (makefile
->dynamic
) {
2600 fputs("$(SHARED_OBJECTS)", fp
);
2601 if (makefile
->central_storage
)
2602 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
2604 fputs("$(OBJECTS)", fp
);
2605 if (makefile
->central_storage
)
2606 fputs(" $(BASE_OBJECTS)", fp
);
2611 if (makefile
->additionalObjects
) {
2612 struct string_list
* act_elem
= makefile
->additionalObjects
;
2614 if (act_elem
->str
) {
2615 fprintf(fp
, " %s", act_elem
->str
);
2617 act_elem
= act_elem
->next
;
2622 "\t-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB)"
2624 "\t-L$(OPENSSL_DIR)/lib -lcrypto");
2625 if (makefile
->linkerlibraries
) {
2626 struct string_list
* act_elem
= makefile
->linkerlibraries
;
2628 if (act_elem
->str
) {
2629 fprintf(fp
, " -l%s", act_elem
->str
);
2631 act_elem
= act_elem
->next
;
2634 if (makefile
->linkerlibsearchpath
) {
2635 struct string_list
* act_elem
= makefile
->linkerlibsearchpath
;
2637 if (act_elem
->str
) {
2638 fprintf(fp
, " -L%s", act_elem
->str
);
2640 act_elem
= act_elem
->next
;
2644 "\t-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \\\n"
2645 "\tthen : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi\n");
2646 /* If the compiler will not be run because there are no TTCN(PP) or ASN.1
2647 * files, create the "compile" marker file which is checked by the
2648 * superior makefile if using this project as central storage */
2649 if (!run_compiler
) fputs("\ttouch compile\n", fp
);
2650 /* End of target $(EXECUTABLE) */
2652 /* target $(LIBRARY) */
2653 if (makefile
->dynamic
) {
2655 "$(LIBRARY): $(OBJECTS)\n"
2656 "\t$(CXX) -shared -o $@ $(OBJECTS)", fp
);
2657 if (makefile
->central_storage
) {
2658 fputs(" $(BASE_SHARED_OBJECTS)", fp
);
2662 "$(LIBRARY): $(OBJECTS)\n"
2663 "\t$(AR) -r $(ARFLAGS) $(LIBRARY) $(OBJECTS)", fp
);
2664 if (makefile
->central_storage
) {
2665 fputs(" $(BASE_OBJECTS)", fp
);
2669 fputs("\n\n.cc.o .c.o:\n"
2670 "\t$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<\n\n", fp
);
2672 if (makefile
->gcc_dep
) {
2673 fputs(".cc.d .c.d:\n"
2674 "\t@echo Creating dependency file for '$<'; set -e; \\\n"
2675 "\t$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \\\n"
2676 "\t| sed 's/\\($*\\)\\.o[ :]*/\\1.o $@ : /g' > $@; \\\n"
2677 "\t[ -s $@ ] || rm -f $@\n\n", fp
);
2678 /* "set -e" causes bash to exit the script if any statement
2679 * returns nonzero (failure).
2680 * The sed line transforms the first line of the dependency from
2681 * "x.o: x.cc" to "x.o x.d: x.cc", making the dependency file depend
2682 * on the source and headers.
2683 * [ -s x.d ] checks that the generated dependency is not empty;
2684 * otherwise it gets deleted.
2688 if (makefile
->dynamic
) {
2690 "\t$(CXX) -shared -o $@ $<\n\n", fp
);
2693 if (makefile
->preprocess
) {
2694 fputs("%.ttcn: %.ttcnpp $(TTCN3_INCLUDES)\n"
2695 "\t$(CPP) -x c -nostdinc $(CPPFLAGS_TTCN3) $< $@\n\n"
2696 "preprocess: $(PREPROCESSED_TTCN3_MODULES) ;\n\n", fp
);
2699 if (makefile
->central_storage
) {
2700 boolean is_first
= TRUE
;
2701 fputs("$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile-all compile ", fp
);
2702 if (add_refd_prjs
) fputs("referenced-dep", fp
);
2703 /* These extra compile dependencies for the generated .cc are here to
2704 * check if all the referenced projects are up to date.
2705 * If the referenced projects are built too then they are not needed
2706 * (and cause problems as the included .d depends on the .cc).
2708 if (!add_refd_prjs
) for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
2709 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
2710 if (base_dir
->has_modules
) {
2714 } else putc(' ', fp
);
2715 fprintf(fp
, "%s/compile", base_dir
->dir_name
);
2719 if (makefile
->preprocess
) {
2721 "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
2723 "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2724 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
2726 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n"
2727 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", rm_command
, add_refd_prjs
?" referenced-check":"");
2728 if (makefile
->gnu_make
) {
2729 if (add_refd_prjs
) // referenced-check cannot be compiled it is not a ttcn modul
2730 fputs("$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2731 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
2733 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n", fp
);
2739 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2740 "\t$(PREPROCESSED_TTCN3_MODULES) "
2741 "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
2742 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp
);
2745 "compile: $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) "
2747 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
2748 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2749 "\t$(PREPROCESSED_TTCN3_MODULES) "
2750 "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
2751 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) - $?\n"
2754 "compile-all: $(BASE_TTCN3_MODULES) "
2755 "$(BASE_PREPROCESSED_TTCN3_MODULES) \\\n"
2756 "$(BASE_ASN1_MODULES)\n"
2757 "\t$(MAKE) preprocess\n"
2758 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
2759 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2760 "\t$(PREPROCESSED_TTCN3_MODULES) $(BASE_PREPROCESSED_TTCN3_MODULES) "
2762 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
2763 "\t- $(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)\n"
2764 "\ttouch $@ compile\n\n", fp
);
2767 "\t@if [ ! -f $@ ]; then %s compile-all; $(MAKE) compile-all; fi\n"
2769 "check:%s $(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2770 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n"
2771 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", rm_command
, add_refd_prjs
?" referenced-check":"");
2772 if (makefile
->gnu_make
) {
2773 if (add_refd_prjs
) // referenced-check cannot be compiled it is not a ttcn modul
2774 fputs("$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2775 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)\n", fp
);
2781 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2782 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES)", fp
);
2785 "compile: $(TTCN3_MODULES) $(ASN1_MODULES)\n"
2786 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
2787 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2788 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
2792 "compile-all: $(BASE_TTCN3_MODULES) $(BASE_ASN1_MODULES)\n"
2793 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \\\n"
2794 "\t$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n"
2795 "\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
2796 "\t- $(TTCN3_MODULES) $(ASN1_MODULES)\n"
2797 "\ttouch $@ compile\n\n", fp
);
2799 for (i
= 0; i
< makefile
->nBaseDirs
; i
++) {
2800 const struct base_dir_struct
*base_dir
= makefile
->BaseDirs
+ i
;
2801 if (base_dir
->has_modules
) {
2803 fprintf(fp
, "%s/compile:", base_dir
->dir_name
);
2804 for (j
= 0; j
< makefile
->nTTCN3Modules
; j
++) {
2805 const struct module_struct
*module
= makefile
->TTCN3Modules
+ j
;
2806 if (module
->dir_name
!= NULL
&&
2807 !strcmp(base_dir
->dir_name
, module
->dir_name
))
2808 print_file_name(fp
, module
);
2810 for (j
= 0; j
< makefile
->nTTCN3PPModules
; j
++) {
2811 const struct module_struct
*module
= makefile
->TTCN3PPModules
+ j
;
2812 if (module
->dir_name
!= NULL
&&
2813 !strcmp(base_dir
->dir_name
, module
->dir_name
))
2814 print_file_name(fp
, module
);
2816 for (j
= 0; j
< makefile
->nASN1Modules
; j
++) {
2817 const struct module_struct
*module
= makefile
->ASN1Modules
+ j
;
2818 if (module
->dir_name
!= NULL
&&
2819 !strcmp(base_dir
->dir_name
, module
->dir_name
))
2820 print_file_name(fp
, module
);
2823 "\t@echo 'Central directory %s is not up-to-date!'\n"
2824 "\t@exit 2\n\n", base_dir
->dir_name
);
2827 } else { /* not central storage */
2828 fprintf(fp
, "$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile\n"
2829 "\t@if [ ! -f $@ ]; then %s compile; $(MAKE) compile; fi\n\n"
2830 "check: $(TTCN3_MODULES) ", rm_command
);
2831 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
2832 fputs("$(ASN1_MODULES)\n"
2833 "\t$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) ", fp
);
2834 if (makefile
->gnu_make
) fputs("$^", fp
);
2837 "\t$(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)",
2841 "compile: $(TTCN3_MODULES) ", fp
);
2842 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
2843 fputs("$(ASN1_MODULES)\n"
2844 "\t$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) ", fp
);
2845 if (makefile
->gnu_make
) fputs("$^", fp
);
2848 "\t$(TTCN3_MODULES) ", fp
);
2849 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
2850 fputs("$(ASN1_MODULES)", fp
);
2856 fprintf(fp
, "clean:%s\n"
2857 "\t-%s $(EXECUTABLE) $(LIBRARY) $(OBJECTS) $(GENERATED_HEADERS) \\\n"
2858 "\t$(GENERATED_SOURCES) ", add_refd_prjs
?" referenced-clean":"", rm_command
);
2859 if (makefile
->dynamic
) fputs("$(SHARED_OBJECTS) ", fp
);
2860 if (makefile
->preprocess
) fputs("$(PREPROCESSED_TTCN3_MODULES) ", fp
);
2861 fputs("compile", fp
);
2862 if (makefile
->central_storage
) fputs(" compile-all", fp
);
2863 if (makefile
->gcc_dep
) fputs(" $(DEPFILES)", fp
);
2866 add_refd_prjs
?" referenced*":"");
2868 fputs("\n\ndep: $(GENERATED_SOURCES) $(USER_SOURCES)",fp
);
2869 if (add_refd_prjs
) fprintf(fp
, "\n\t%s referenced-dep", rm_command
);
2870 else fputs(" ;",fp
);
2872 if (makefile
->gcc_dep
) {
2874 "ifeq ($(findstring n,$(MAKEFLAGS)),)\n"
2875 "ifeq ($(filter clean check compile archive diag%s,$(MAKECMDGOALS)),)\n"
2876 "-include $(DEPFILES)\n"
2878 "endif", (makefile
->preprocess
? " preprocess" : ""));
2879 /* Don't include .d files when cleaning etc.; make will try to build them
2880 * and this involves running the Titan compiler. Same for preprocess.
2881 * The check target would be pointless if running the compiler
2882 * without generating code was always preceded by running the compiler
2883 * _and_ generating C++ code. */
2885 else { /* old-style dep with makedepend. Do not check compiler version. */
2886 fputs("\n\tmakedepend $(CPPFLAGS) -DMAKEDEPEND_RUN ", fp
);
2887 if (makefile
->gnu_make
) fputs("$^", fp
);
2888 else fputs("$(GENERATED_SOURCES) $(USER_SOURCES)", fp
);
2892 "\tmkdir -p $(ARCHIVE_DIR)\n"
2893 "\ttar -cvhf - ", add_refd_prjs
?" referenced-archive":"");
2894 if (makefile
->central_storage
) {
2895 fputs("$(TTCN3_MODULES) $(BASE_TTCN3_MODULES) \\\n", fp
);
2896 if (makefile
->preprocess
) {
2897 fputs("\t$(TTCN3_PP_MODULES) $(BASE_TTCN3_PP_MODULES) "
2898 "$(TTCN3_INCLUDES)\\\n", fp
);
2900 fputs("\t$(ASN1_MODULES) $(BASE_ASN1_MODULES) \\\n"
2901 "\t$(USER_HEADERS) $(BASE_USER_HEADERS) \\\n"
2902 "\t$(USER_SOURCES) $(BASE_USER_SOURCES)", fp
);
2904 fputs("$(TTCN3_MODULES) ", fp
);
2905 if (makefile
->preprocess
) {
2906 fputs("$(TTCN3_PP_MODULES) \\\n"
2907 "\t$(TTCN3_INCLUDES) ", fp
);
2909 fputs("$(ASN1_MODULES) \\\n"
2910 "\t$(USER_HEADERS) $(USER_SOURCES)", fp
);
2912 fputs(" $(OTHER_FILES) \\\n"
2913 "\t| gzip >$(ARCHIVE_DIR)/`basename $(TARGET) .exe`-"
2914 "`date '+%y%m%d-%H%M'`.tgz\n\n", fp
);
2916 fprintf(fp
, "diag:\n"
2917 "\t$(TTCN3_DIR)/bin/compiler -v 2>&1\n"
2918 "\t$(TTCN3_DIR)/bin/mctr_cli -v 2>&1\n"
2919 "\t$(CXX) -v 2>&1\n"
2921 "\t@echo TTCN3_DIR=$(TTCN3_DIR)\n"
2922 "\t@echo OPENSSL_DIR=$(OPENSSL_DIR)\n"
2923 "\t@echo XMLDIR=$(XMLDIR)\n"
2924 "\t@echo PLATFORM=$(PLATFORM)\n\n",
2925 makefile
->dynamic
? "" : "\t$(AR) -V 2>&1\n");
2927 if (add_refd_prjs
) {
2928 fputs("referenced-all referenced-shared_objects referenced-executable referenced-library \\\n"
2929 "referenced-objects referenced-check \\\n"
2930 "referenced-clean referenced-archive:\n"
2931 "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
2932 "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
2933 "\tdone; \n\n", fp
);
2934 fputs("referenced-dep:\n"
2935 "\t@for dir in $(REFERENCED_PROJECT_DIRS); do \\\n"
2936 "\t $(MAKE) -C $$dir $(subst referenced-,,$@) || exit; \\\n"
2938 "\ttouch $@\n\n", fp
);
2941 if (makefile
->generatorCommandOutput
) {
2942 fputs("### Project specific rules generated by user written script:\n\n", fp
);
2943 fputs(makefile
->generatorCommandOutput
, fp
);
2944 fputs("\n### End of project specific rules.\n\n", fp
);
2948 "# Add your rules here if necessary...\n"
2951 if (strcmp(makefile
->output_file
, "Makefile")) {
2952 NOTIFY("Makefile skeleton was written to `%s'.", makefile
->output_file
);
2954 NOTIFY("Makefile skeleton was generated.");
2957 ERROR("Output file `%s' already exists. Use switch `-f' to force "
2958 "overwrite.", makefile
->output_file
);
2962 #undef COMMENT_PREFIX
2963 #define COMMENT_PREFIX
2965 /** run makefilegen commans for sub-projects */
2966 static void run_makefilegen_commands(struct string2_list
* run_command_list
)
2968 struct string2_list
* act_elem
= run_command_list
;
2970 struct string2_list
* next_elem
= act_elem
->next
;
2971 /* run commands if there were no ERRORs */
2972 if ((error_count
== 0) && act_elem
->str1
&& act_elem
->str2
) {
2974 char* sub_proj_effective_work_dir
= act_elem
->str1
;
2975 char* command
= act_elem
->str2
;
2976 char* orig_dir
= get_working_dir();
2977 rv
= set_working_dir(sub_proj_effective_work_dir
);
2978 if (rv
) ERROR("Could not set working dir to `%s'", sub_proj_effective_work_dir
);
2980 printf("Executing `%s' in working directory `%s'...\n", command
, sub_proj_effective_work_dir
);
2981 rv
= system(command
);
2982 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
2984 rv
= set_working_dir(orig_dir
);
2985 if (rv
) ERROR("Could not restore working dir to `%s'", orig_dir
);
2988 Free(act_elem
->str1
);
2989 Free(act_elem
->str2
);
2991 act_elem
= next_elem
;
2995 /** create symlinks and delete list */
2996 static void generate_symlinks(struct string2_list
* create_symlink_list
)
2998 struct string2_list
* act_elem
= create_symlink_list
;
3000 struct string2_list
* next_elem
= act_elem
->next
;
3001 /* create symlinks if there were no ERRORs */
3002 if ((error_count
== 0) && act_elem
->str1
&& act_elem
->str2
) {
3003 int fail
= symlink(act_elem
->str1
, act_elem
->str2
);
3004 if (fail
) perror(act_elem
->str2
); /* complain but do not call ERROR() */
3006 Free(act_elem
->str1
);
3007 Free(act_elem
->str2
);
3009 act_elem
= next_elem
;
3013 /** Performs all tasks of Makefile generation based on the given list of
3014 * modules/files (taken from the command line) and options that represent
3015 * command line switches. */
3016 static void generate_makefile(size_t n_arguments
, char *arguments
[],
3017 size_t n_other_files
, const char *other_files
[], const char *output_file
,
3018 const char *ets_name
, boolean gnu_make
, boolean single_mode
,
3019 boolean central_storage
, boolean absolute_paths
, boolean preprocess
,
3020 boolean dump_makefile_data
, boolean force_overwrite
, boolean use_runtime_2
,
3021 boolean dynamic
, boolean makedepend
, boolean coverage
,
3022 const char *code_splitting_mode
, const char *tcov_file_name
,
3023 boolean Lflag
, struct string_list
* sub_project_dirs
, struct string_list
* ttcn3_prep_includes
,
3024 struct string_list
* ttcn3_prep_defines
, struct string_list
* prep_includes
, struct string_list
* prep_defines
,
3025 boolean codesplittpd
, boolean quietly
, boolean disablesubtypecheck
, const char* cxxcompiler
,
3026 const char* optlevel
, const char* optflags
, boolean disableber
, boolean disableraw
, boolean disabletext
,
3027 boolean disablexer
, boolean disablejson
, boolean forcexerinasn
, boolean defaultasomit
, boolean gccmsgformat
,
3028 boolean linenumbersonlymsg
, boolean includesourceinfo
, boolean addsourcelineinfo
, boolean suppresswarnings
,
3029 boolean outparamboundness
, struct string_list
* solspeclibraries
, struct string_list
* sol8speclibraries
,
3030 struct string_list
* linuxspeclibraries
, struct string_list
* freebsdspeclibraries
,
3031 struct string_list
* win32speclibraries
, const char* ttcn3preprocessor
, struct string_list
* linkerlibraries
,
3032 struct string_list
* additionalObjects
, struct string_list
* linkerlibsearchpath
, char* generatorCommandOutput
,
3033 struct string2_list
* target_placement_list
)
3037 struct makefile_struct makefile
;
3038 init_makefile_struct(&makefile
);
3040 makefile
.central_storage
= central_storage
;
3041 makefile
.gnu_make
= gnu_make
;
3042 makefile
.preprocess
= preprocess
;
3043 makefile
.single_mode
= single_mode
;
3044 makefile
.force_overwrite
= force_overwrite
;
3045 makefile
.use_runtime_2
= use_runtime_2
;
3046 makefile
.dynamic
= dynamic
;
3047 makefile
.gcc_dep
= gnu_make
&& !makedepend
;
3048 makefile
.coverage
= coverage
;
3049 makefile
.library
= Lflag
;
3050 makefile
.sub_project_dirs
= sub_project_dirs
;
3051 makefile
.ttcn3_prep_includes
= ttcn3_prep_includes
;
3052 makefile
.ttcn3_prep_defines
= ttcn3_prep_defines
;
3053 makefile
.prep_includes
= prep_includes
;
3054 makefile
.prep_defines
= prep_defines
;
3055 makefile
.codesplittpd
= codesplittpd
;
3056 makefile
.quietly
= quietly
;
3057 makefile
.disablesubtypecheck
= disablesubtypecheck
;
3058 makefile
.cxxcompiler
= cxxcompiler
;
3059 makefile
.optlevel
= optlevel
;
3060 makefile
.optflags
= optflags
;
3061 makefile
.disableber
= disableber
;
3062 makefile
.disableraw
= disableraw
;
3063 makefile
.disabletext
= disabletext
;
3064 makefile
.disablexer
= disablexer
;
3065 makefile
.disablejson
= disablejson
;
3066 makefile
.forcexerinasn
= forcexerinasn
;
3067 makefile
.defaultasomit
= defaultasomit
;
3068 makefile
.gccmsgformat
= gccmsgformat
;
3069 makefile
.linenumbersonlymsg
= linenumbersonlymsg
;
3070 makefile
.includesourceinfo
= includesourceinfo
;
3071 makefile
.addsourcelineinfo
= addsourcelineinfo
;
3072 makefile
.suppresswarnings
= suppresswarnings
;
3073 makefile
.outparamboundness
= outparamboundness
;
3074 makefile
.solspeclibraries
= solspeclibraries
;
3075 makefile
.sol8speclibraries
= sol8speclibraries
;
3076 makefile
.linuxspeclibraries
= linuxspeclibraries
;
3077 makefile
.freebsdspeclibraries
= freebsdspeclibraries
;
3078 makefile
.win32speclibraries
= win32speclibraries
;
3079 makefile
.ttcn3preprocessor
= ttcn3preprocessor
;
3080 makefile
.linkerlibraries
= linkerlibraries
;
3081 makefile
.additionalObjects
= additionalObjects
;
3082 makefile
.linkerlibsearchpath
= linkerlibsearchpath
;
3083 makefile
.generatorCommandOutput
= generatorCommandOutput
;
3084 makefile
.target_placement_list
= target_placement_list
;
3086 for (i
= 0; i
< n_arguments
; i
++) {
3087 char *file_name
= get_file_name_for_argument(arguments
[i
]);
3088 if (file_name
!= NULL
) {
3089 FILE *fp
= fopen(file_name
, "r");
3092 if (is_ttcn3_module(file_name
, fp
, &module_name
)) {
3093 if (is_asn1_module(file_name
, fp
, NULL
)) {
3094 ERROR("File `%s' looks so strange that it can be both ASN.1 and "
3095 "TTCN-3 module. Add it to the Makefile manually.", file_name
);
3098 add_ttcn3_module(&makefile
, file_name
, module_name
);
3100 } else if (is_asn1_module(file_name
, fp
, &module_name
)) {
3101 if (is_valid_asn1_filename(file_name
)) {
3102 add_asn1_module(&makefile
, file_name
, module_name
);
3104 ERROR("The file name (without suffix) shall be identical to the module name.\n"
3105 "If the name of the ASN.1 module contains a hyphen, the corresponding "
3106 "file name shall contain an underscore character instead.");
3109 add_user_file(&makefile
, file_name
);
3113 ERROR("Cannot open file `%s' for reading: %s", file_name
,
3118 } else if (get_path_status(arguments
[i
]) == PS_DIRECTORY
) {
3119 ERROR("Argument `%s' is a directory.", arguments
[i
]);
3121 ERROR("Cannot find any source file for argument `%s'.", arguments
[i
]);
3124 for (i
= 0; i
< n_other_files
; i
++) {
3125 char *file_name
= get_file_name_for_argument(other_files
[i
]);
3126 if (file_name
!= NULL
) {
3127 add_path_to_list(&makefile
.nOtherFiles
, &makefile
.OtherFiles
, file_name
,
3128 makefile
.working_dir
, TRUE
);
3130 } else if (get_path_status(other_files
[i
]) == PS_DIRECTORY
) {
3131 ERROR("Argument `%s' given as other file is a directory.",
3134 ERROR("Cannot find any other file for argument `%s'.", other_files
[i
]);
3138 if (ets_name
!= NULL
) {
3139 char *dir_name
= get_dir_name(ets_name
, makefile
.working_dir
);
3140 char *file_name
= get_file_from_path(ets_name
);
3141 makefile
.ets_name
= compose_path_name(dir_name
, file_name
);
3146 if (code_splitting_mode
!= NULL
) {
3147 makefile
.code_splitting_mode
= mputprintf(makefile
.code_splitting_mode
, "-U %s", code_splitting_mode
);
3150 if (tcov_file_name
!= NULL
) {
3151 makefile
.tcov_file_name
= mputprintf(makefile
.tcov_file_name
, "-K %s", tcov_file_name
);
3154 if (makefile
.nTTCN3Modules
>= 1) {
3155 if (makefile
.ets_name
== NULL
)
3156 makefile
.ets_name
= mcopystr(makefile
.TTCN3Modules
[0].module_name
);
3157 } else if (preprocess
&& (makefile
.nTTCN3PPModules
>= 1)) {
3158 if (makefile
.ets_name
== NULL
)
3159 makefile
.ets_name
= mcopystr(makefile
.TTCN3PPModules
[0].module_name
);
3160 } else if (makefile
.nASN1Modules
>= 1) {
3161 WARNING("No TTCN-3 module was given for the Makefile.");
3162 if (makefile
.ets_name
== NULL
)
3163 makefile
.ets_name
= mcopystr(makefile
.ASN1Modules
[0].module_name
);
3164 } else if (makefile
.nUserFiles
> 0) {
3165 WARNING("No TTCN-3 or ASN.1 module was given for the Makefile.");
3166 if (makefile
.ets_name
== NULL
)
3167 makefile
.ets_name
= mcopystr(makefile
.UserFiles
[0].file_prefix
);
3169 WARNING("No source files were given for the Makefile");
3172 if (output_file
!= NULL
) {
3173 if (get_path_status(output_file
) == PS_DIRECTORY
)
3174 makefile
.output_file
= mprintf("%s/Makefile", output_file
);
3175 else makefile
.output_file
= mcopystr(output_file
);
3176 } else makefile
.output_file
= mcopystr("Makefile");
3177 add_path_to_list(&makefile
.nOtherFiles
, &makefile
.OtherFiles
,
3178 makefile
.output_file
, makefile
.working_dir
, FALSE
);
3180 if (preprocess
) check_preprocessed_filename_collision(&makefile
);
3181 filter_out_generated_files(&makefile
);
3182 complete_user_files(&makefile
);
3183 if (!absolute_paths
) convert_dirs_to_relative(&makefile
);
3184 check_special_chars(&makefile
);
3185 if (central_storage
) collect_base_dirs(&makefile
);
3186 check_naming_convention(&makefile
);
3188 if (dump_makefile_data
) dump_makefile_struct(&makefile
, 0);
3190 if (error_count
== 0) print_makefile(&makefile
);
3192 free_makefile_struct(&makefile
);
3195 #ifdef COVERAGE_BUILD
3202 static void usage(void)
3204 fprintf(stderr
, "\n"
3205 "usage: %s [-abc" C_flag
"dDfFglLmprRstTVwWX] [-K file] [-P dir]"
3206 " [-U none|type] [-e ets_name] [-o dir|file]\n"
3207 " [-t project_descriptor.tpd [-b buildconfig]]\n"
3208 " [-O file] ... module_name ... testport_name ...\n"
3212 " -a: use absolute pathnames in the generated Makefile\n"
3213 " -c: use the pre-compiled files from central directories\n"
3214 #ifdef COVERAGE_BUILD
3215 " -C: enable coverage of generated C++ code\n"
3217 " -d: dump the data used for Makefile generation\n"
3218 " -e ets_name: name of the target executable\n"
3219 " -f: force overwriting of the output Makefile\n"
3220 " -g: generate Makefile for use with GNU make\n"
3221 " -l: use dynamic linking\n"
3222 " -L: create makefile with library archive as the default target\n"
3223 " -m: always use makedepend for dependencies\n"
3224 " -K file: enable selective code coverage\n"
3225 " -o dir|file: write the Makefile to the given directory or file\n"
3226 " -O file: add the given file to the Makefile as other file\n"
3227 " -p: generate Makefile with TTCN-3 preprocessing\n"
3228 " -R: use function test runtime (TITAN_RUNTIME_2)\n"
3229 " -s: generate Makefile for single mode\n"
3230 " -U none|type: split generated code\n"
3231 " -v: show version\n"
3232 " -w: suppress warnings\n"
3233 " -Y: Enforces legacy behaviour of the \"out\" function parameters (see refguide)\n"
3234 "Options for processing the Titan Project Descriptor file(s):\n"
3235 " -t tpd: read project descriptor file\n"
3236 " -b buildconfig: use the specified build config instead of the default\n"
3237 " -D: use current directory as working directory\n"
3238 " -V: disable validation of TPD file with schema\n"
3239 " -r: generate Makefile hierarchy for TPD hierarchy (recursive)\n"
3240 " -F: force overwriting of all generated Makefiles, use with -r\n"
3241 " -T: generate only top-level Makefile of the hierarchy, use with -r\n"
3242 " -P dir: prints out a file list found in a given TPD relative to the given directory\n"
3243 " -X: generate XML file that describes the TPD hierarchy, use with -r\n"
3244 " -W: prefix working directories with project name\n"
3245 , program_name
, program_name
);
3248 #define SET_FLAG(x) if (x##flag) {\
3249 ERROR("Flag -" #x " was specified more than once.");\
3251 } else x##flag = TRUE
3253 void free_string_list(struct string_list
* act_elem
)
3256 struct string_list
* next_elem
= act_elem
->next
;
3257 Free(act_elem
->str
);
3259 act_elem
= next_elem
;
3263 void free_string2_list(struct string2_list
* act_elem
)
3266 struct string2_list
* next_elem
= act_elem
->next
;
3267 Free(act_elem
->str1
);
3268 Free(act_elem
->str2
);
3270 act_elem
= next_elem
;
3274 int main(int argc
, char *argv
[])
3277 aflag
= FALSE
, bflag
= FALSE
, cflag
= FALSE
, Cflag
= FALSE
,
3278 dflag
= FALSE
, eflag
= FALSE
, fflag
= FALSE
, gflag
= FALSE
,
3279 oflag
= FALSE
, Kflag
= FALSE
, lflag
= FALSE
, pflag
= FALSE
,
3280 Pflag
= FALSE
, Rflag
= FALSE
, sflag
= FALSE
, tflag
= FALSE
,
3281 wflag
= FALSE
, vflag
= FALSE
, mflag
= FALSE
, Uflag
= FALSE
,
3282 Lflag
= FALSE
, rflag
= FALSE
, Fflag
= FALSE
, Xflag
= FALSE
,
3283 Tflag
= FALSE
, Yflag
= FALSE
, csflag
= FALSE
, quflag
= FALSE
,
3284 dsflag
= FALSE
, dbflag
= FALSE
, drflag
= FALSE
, dtflag
= FALSE
,
3285 dxflag
= FALSE
, fxflag
= FALSE
, doflag
= FALSE
,
3286 gfflag
= FALSE
, lnflag
= FALSE
, isflag
= FALSE
, asflag
= FALSE
,
3287 swflag
= FALSE
, Vflag
= FALSE
, Dflag
= FALSE
, Wflag
= FALSE
,
3289 boolean error_flag
= FALSE
;
3290 char *output_file
= NULL
;
3291 char *ets_name
= NULL
;
3292 size_t n_other_files
= 0;
3293 const char **other_files
= NULL
;
3294 const char *code_splitting_mode
= NULL
;
3295 const char *tpd_file_name
= NULL
;
3296 const char *tpd_build_config
= NULL
;
3297 const char *tcov_file_name
= NULL
;
3298 const char *file_list_path
= NULL
;
3299 enum tpd_result tpd_processed
= FALSE
;
3300 struct string_list
* sub_project_dirs
= NULL
;
3301 struct string2_list
* create_symlink_list
= NULL
;
3302 struct string_list
* ttcn3_prep_includes
= NULL
;
3303 struct string_list
* ttcn3_prep_defines
= NULL
;
3304 struct string_list
* prep_includes
= NULL
;
3305 struct string_list
* prep_defines
= NULL
;
3306 char *cxxcompiler
= NULL
;
3307 char *optlevel
= NULL
;
3308 char *optflags
= NULL
;
3309 struct string_list
* solspeclibraries
= NULL
;
3310 struct string_list
* sol8speclibraries
= NULL
;
3311 struct string_list
* linuxspeclibraries
= NULL
;
3312 struct string_list
* freebsdspeclibraries
= NULL
;
3313 struct string_list
* win32speclibraries
= NULL
;
3314 char *ttcn3prep
= NULL
;
3315 struct string_list
* linkerlibraries
= NULL
;
3316 struct string_list
* additionalObjects
= NULL
;
3317 struct string_list
* linkerlibsearchpath
= NULL
;
3318 char* generatorCommandOutput
= NULL
;
3319 struct string2_list
* target_placement_list
= NULL
;
3320 struct string2_list
* run_command_list
= NULL
;
3323 license_struct lstr
;
3327 program_name
= argv
[0];
3330 fputs("Makefile Generator for the TTCN-3 Test Executor, version "
3331 PRODUCT_NUMBER
"\n", stderr
);
3333 return EXIT_FAILURE
;
3337 int c
= getopt(argc
, argv
, "O:ab:c" C_flag
"dDe:fFgK:o:lLmpP:rRst:TU:vVwWXY");
3342 other_files
= (const char**)
3343 Realloc(other_files
, n_other_files
* sizeof(*other_files
));
3344 other_files
[n_other_files
- 1] = optarg
;
3351 tpd_build_config
= optarg
;
3358 tcov_file_name
= optarg
;
3360 #ifdef COVERAGE_BUILD
3386 output_file
= optarg
;
3402 /* Optional arguments with `::' are GNU specific... */
3403 if (get_path_status(optarg
) == PS_DIRECTORY
) {
3404 file_list_path
= optarg
;
3406 ERROR("The -P flag requires a valid directory as its argument "
3407 "instead of `%s'", optarg
);
3422 tpd_file_name
= optarg
;
3432 code_splitting_mode
= optarg
;
3433 if (strcmp(optarg
, "none") != 0 &&
3434 strcmp(optarg
, "type") != 0)
3435 ERROR("Unrecognizable argument: '%s'. Valid options for -U switch are: "
3436 "'none', 'type'", optarg
);
3446 suppress_warnings
= TRUE
;
3460 /* Checking incompatible options */
3462 /* -v prints the version and exits, it's pointless to specify other flags */
3463 if ( aflag
|| bflag
|| cflag
|| Cflag
|| dflag
|| eflag
|| fflag
|| Fflag
|| gflag
3464 || mflag
|| oflag
|| lflag
|| pflag
|| Pflag
|| rflag
|| Rflag
|| sflag
3465 || tflag
|| Tflag
|| Vflag
|| wflag
|| Xflag
|| Kflag
|| Dflag
|| Wflag
|| Yflag
3466 || n_other_files
> 0)
3470 if ((bflag
|| Dflag
|| Pflag
|| Vflag
|| rflag
|| Wflag
) && !tflag
) {
3471 ERROR("Using the '-b', '-D', '-P', '-V', '-r' or '-W' option requires the use of the -t' option.");
3475 if (rflag
&& !cflag
) {
3476 ERROR("Using the '-r' option requires use of the '-c' option. Recursive makefile hierarchy uses the central directory feature.");
3480 if (Fflag
&& !rflag
) {
3481 ERROR("Using the '-F' option requires use of the '-r' option.");
3485 if (Xflag
&& !rflag
) {
3486 ERROR("Using the '-X' option requires use of the '-r' option.");
3490 if (Tflag
&& !rflag
) {
3491 ERROR("Using the '-T' option requires use of the '-r' option.");
3495 if (lflag
&& !strncmp(get_platform_string(), "WIN32", 5)) {
3496 ERROR("Generating Makefile with dynamic linking enabled is not supported "
3497 "on Windows platform");
3503 return EXIT_FAILURE
;
3507 fputs("Makefile Generator for the TTCN-3 Test Executor\n"
3508 "Product number: " PRODUCT_NUMBER
"\n"
3509 "Build date: " __DATE__
" " __TIME__
"\n"
3510 "Compiled with: " C_COMPILER_VERSION
"\n\n"
3511 COPYRIGHT_STRING
"\n\n", stderr
);
3513 print_license_info();
3515 return EXIT_SUCCESS
;
3520 load_license(&lstr
);
3521 valid_license
= verify_license(&lstr
);
3523 if (!valid_license
) {
3524 free_license(&lstr
);
3527 if (!check_feature(&lstr
, FEATURE_TPGEN
)) {
3528 ERROR("The license key does not allow the generation of "
3529 "Makefile skeletons.");
3530 return EXIT_FAILURE
;
3532 free_license(&lstr
);
3536 char* abs_work_dir
= NULL
;
3537 FILE* prj_graph_fp
= NULL
;
3538 sub_project_dirs
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3539 sub_project_dirs
->str
= NULL
;
3540 sub_project_dirs
->next
= NULL
;
3541 ttcn3_prep_includes
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3542 ttcn3_prep_includes
->str
= NULL
;
3543 ttcn3_prep_includes
->next
= NULL
;
3544 ttcn3_prep_defines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3545 ttcn3_prep_defines
->str
= NULL
;
3546 ttcn3_prep_defines
->next
= NULL
;
3547 prep_includes
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3548 prep_includes
->str
= NULL
;
3549 prep_includes
->next
= NULL
;
3550 prep_defines
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3551 prep_defines
->str
= NULL
;
3552 prep_defines
->next
= NULL
;
3553 solspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3554 solspeclibraries
->str
= NULL
;
3555 solspeclibraries
->next
= NULL
;
3556 sol8speclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3557 sol8speclibraries
->str
= NULL
;
3558 sol8speclibraries
->next
= NULL
;
3559 linuxspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3560 linuxspeclibraries
->str
= NULL
;
3561 linuxspeclibraries
->next
= NULL
;
3562 freebsdspeclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3563 freebsdspeclibraries
->str
= NULL
;
3564 freebsdspeclibraries
->next
= NULL
;
3565 win32speclibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3566 win32speclibraries
->str
= NULL
;
3567 win32speclibraries
->next
= NULL
;
3568 linkerlibraries
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3569 linkerlibraries
->str
= NULL
;
3570 linkerlibraries
->next
= NULL
;
3571 additionalObjects
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3572 additionalObjects
->str
= NULL
;
3573 additionalObjects
->next
= NULL
;
3574 linkerlibsearchpath
= (struct string_list
*)Malloc(sizeof(struct string_list
));
3575 linkerlibsearchpath
->str
= NULL
;
3576 linkerlibsearchpath
->next
= NULL
;
3579 const char* prj_graph_filename
= "project_hierarchy_graph.xml";
3580 prj_graph_fp
= fopen(prj_graph_filename
, "w");
3581 if (prj_graph_fp
==NULL
) WARNING("Cannot open output file `%s' for writing: %s", prj_graph_filename
, strerror(errno
));
3582 if (prj_graph_fp
) fprintf(prj_graph_fp
, "<project_hierarchy_graph top_level_tpd=\"%s\">\n", tpd_file_name
);
3584 create_symlink_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
3585 create_symlink_list
->str1
= NULL
;
3586 create_symlink_list
->str2
= NULL
;
3587 create_symlink_list
->next
= NULL
;
3588 target_placement_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
3589 target_placement_list
->str1
= NULL
;
3590 target_placement_list
->str2
= NULL
;
3591 target_placement_list
->next
= NULL
;
3592 run_command_list
= (struct string2_list
*)Malloc(sizeof(struct string2_list
));
3593 run_command_list
->str1
= NULL
;
3594 run_command_list
->str2
= NULL
;
3595 run_command_list
->next
= NULL
;
3596 tpd_processed
= process_tpd(tpd_file_name
, tpd_build_config
, file_list_path
,
3597 &argc
, &argv
, &optind
, &ets_name
,
3598 &gflag
, &sflag
, &cflag
, &aflag
, &pflag
,
3599 &Rflag
, &lflag
, &mflag
, &Pflag
, &Lflag
, rflag
, Fflag
, Tflag
, output_file
, &abs_work_dir
, sub_project_dirs
, program_name
, prj_graph_fp
,
3600 create_symlink_list
,ttcn3_prep_includes
, ttcn3_prep_defines
, prep_includes
, prep_defines
, &csflag
, &quflag
, &dsflag
, &cxxcompiler
,
3601 &optlevel
, &optflags
, &dbflag
, &drflag
, &dtflag
, &dxflag
, &djflag
, &fxflag
, &doflag
, &gfflag
, &lnflag
, &isflag
,
3602 &asflag
, &swflag
, &Yflag
, solspeclibraries
, sol8speclibraries
, linuxspeclibraries
, freebsdspeclibraries
, win32speclibraries
, &ttcn3prep
,
3603 linkerlibraries
, additionalObjects
, linkerlibsearchpath
, Vflag
, Dflag
, &generatorCommandOutput
, target_placement_list
, Wflag
, run_command_list
);
3606 fprintf(prj_graph_fp
, "</project_hierarchy_graph>\n");
3607 fclose(prj_graph_fp
);
3609 if (tpd_processed
== TPD_FAILED
) ERROR("Failed to process %s", tpd_file_name
);
3613 run_makefilegen_commands(run_command_list
);
3614 generate_symlinks(create_symlink_list
);
3615 generate_makefile(argc
- optind
, argv
+ optind
, n_other_files
, other_files
,
3616 output_file
, ets_name
, gflag
, sflag
, cflag
, aflag
, pflag
, dflag
, fflag
||Fflag
,
3617 Rflag
, lflag
, mflag
, Cflag
, code_splitting_mode
, tcov_file_name
, Lflag
, rflag
? sub_project_dirs
: NULL
, ttcn3_prep_includes
,
3618 ttcn3_prep_defines
, prep_includes
, prep_defines
, csflag
, quflag
, dsflag
, cxxcompiler
, optlevel
, optflags
, dbflag
,
3619 drflag
, dtflag
, dxflag
, djflag
, fxflag
, doflag
, gfflag
, lnflag
, isflag
, asflag
, swflag
, Yflag
, solspeclibraries
,
3620 sol8speclibraries
, linuxspeclibraries
, freebsdspeclibraries
, win32speclibraries
, ttcn3prep
, linkerlibraries
, additionalObjects
,
3621 linkerlibsearchpath
, generatorCommandOutput
, target_placement_list
);
3624 free_string_list(sub_project_dirs
);
3625 free_string_list(ttcn3_prep_includes
);
3626 free_string_list(ttcn3_prep_defines
);
3627 free_string_list(prep_includes
);
3628 free_string_list(prep_defines
);
3629 free_string_list(solspeclibraries
);
3630 free_string_list(sol8speclibraries
);
3631 free_string_list(linuxspeclibraries
);
3632 free_string_list(freebsdspeclibraries
);
3633 free_string_list(win32speclibraries
);
3634 free_string_list(linkerlibraries
);
3635 free_string_list(additionalObjects
);
3636 free_string_list(linkerlibsearchpath
);
3638 Free(generatorCommandOutput
);
3639 free_string2_list(target_placement_list
);
3642 if (tpd_processed
== TPD_SUCCESS
) {
3644 if (!(eflag
&& ets_name
))
3654 /* Free(output_file); */
3655 for (E
= 0; E
< argc
; ++E
) Free(argv
[E
]);
3658 /* check_mem_leak(program_name); not needed when linked to new.cc */
3659 return error_count
> 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;