4 # An Awk script that generates a unix Makefile from a
5 # Microsoft Developer Studio workspace file.
7 # Copyright (C) 2001 José Fonseca
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public License
11 # as published by the Free Software Foundation; either version 2
12 # of the License, or (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
20 # José Fonseca <j_r_fonseca@yahoo.co.uk>
23 # - generation of GUI applications (including resource files),
24 # DLLs, console applications and static libraries
25 # - translations of the most common compiler and linker options
26 # - conversion of workspace files (.dsw) and all associated
27 # projects files (.dsp) generating all necessary Makefiles
28 # - handling of nested !IF, !ELSEIF and !ENDIF maintaining the
29 # same build configurations as the original project
30 # - automatic generation of the dependencies
33 # gawk -f dsw2mak.awk MyApp.dsw
36 # - Make sure that both this script and the input files are in
37 # a line ending convention that gawk version in your system
39 # - If an option is not handled by this script don't edit all
40 # generate Makefiles by hand. Add support for the option in
41 # this script and submit your additions to the author.
43 # Changelog (incomplete):
44 # 2003-11-25: Amitai Yuval
45 # Strip DOS line-endings from DSW's too.
47 # 2002-11-07: Alain Touret
48 # Fix bug in the linker output target determination.
49 # Support for C++ source files with .cc and .cxx extensions.
51 # 2001-02-18: José Fonseca
52 # Improved linker libraries and options handling.
54 # Better handling of custom builds
56 # 2001-02-15: José Fonseca
57 # Improved C compiler options handling.
58 # More verbose warning output.
60 # 2001-02-14: José Fonseca
61 # Added comments to the source code.
65 # check and remove unnecessary quotes from a string
66 function fixquotes(str) {
67 if(str ~ /^"[^[:blank:]]+"$/) {
76 function fixpath(path) {
77 # remove leading and trainling whitespaces
78 sub(/^[[:blank:]]+/, "", path);
79 sub(/[[:blank:]]+$/, "", path);
81 # check and remove unnecessary quotes
82 path = fixquotes(path)
84 # change the forward slashes to backslashes
87 # remove reduntant ./ directories
88 gsub(/^(\.\/)+/, "", path)
89 gsub(/^\/(\.\/)+/, "", path)
94 # get the base directory from a path
95 function basedir(path) {
96 # remove leading and trainling whitespaces
97 sub(/^[[:blank:]]+/, "", path);
98 sub(/[[:blank:]]+$/, "", path);
101 if(path ~ /^".+"$/) {
106 # remove the leading path
107 sub(/(^|[\/\\:])[^\/\\:]*$/, "", path)
109 # add quotes if needed
110 if(path ~ /[[:blank:]]/)
111 path = "\"" path "\""
116 # get the filename from a path
117 function basefile(path) {
118 # remove leading and trainling whitespaces
119 sub(/^[[:blank:]]+/, "", path);
120 sub(/[[:blank:]]+$/, "", path);
123 if(path ~ /^".+"$/) {
128 # remove the trailing path
129 sub(/^.*[\/\\:]/, "", path)
131 # add quotes if needed
132 if(path ~ /[[:blank:]]/)
133 path = "\"" path "\""
138 # skip lines until matching a given regular expression
139 # NOTE: not used but it could be eventually handy
140 function skip(regexp, infile, ret) {
141 while((ret = getline < infile) == 1 && $0 !~ regexp) {}
146 # parses a project file (.dsp) specified by 'infile' and generates a makefile to 'outfile'
147 function parse_dsp(infile, outfile, i) {
150 # this specifies verbose debug output
153 # this specifies a prefix to the binutils and gcc binaries
157 # this specifies the name of the 'rm -f' or equivalent command
160 # check for a bad file
161 if((getline < infile) == -1) {
162 print infile ": " ERRNO
166 # Strip DOS line-endings
169 # count the number of lines
172 # print the Makefile header
173 print "# Makefile - " basefile(infile) > outfile
176 # this specifies the default name for the dependencies file
177 dependencies = ".dependencies"
179 # attemp to get the project name
180 if(/^# Microsoft Developer Studio Project File/) {
181 name = gensub(/^# Microsoft Developer Studio Project File - Name="(.*)".*$/, "\\1", "1")
182 dependencies = name ".dep"
186 while((getline < infile) == 1) {
187 # Strip DOS line-endings
190 # increment the number of lines
193 # catch the target type definition
195 if (/[[:space:]]0x0101$/) {
196 # Win32 (x86) Application
201 if (/[[:space:]]0x0102$/) {
202 # Win32 (x86) Dynamic-Link Library
207 if (/[[:space:]]0x0103$/) {
208 # Win32 (x86) Console Application
213 if (/[[:space:]]0x0104$/) {
214 # Win32 (x86) Static Library
222 # catch the default configuration definition
224 print "ifndef CFG" > outfile
226 print "endif" > outfile
229 # deal with the preprocessor commands
231 # as GNU make doesn't have the '!ELSEIF' equivalent we have to use nested 'if ... else .. endif' to obtain the same effect
232 # a stack is used to keep track of the current nested level
235 $0 = gensub(/^!IF[[:space:]]+(.+)[[:space:]]*==[[:space:]]*(.+)$/, "ifeq \\1 \\2", "1")
236 $0 = gensub(/^!IF[[:space:]]+(.+)[[:space:]]*!=[[:space:]]*(.+)$/, "ifneq \\1 \\2", "1")
246 $0 = gensub(/^!ELSEIF[[:space:]]+(.+)[[:space:]]*==[[:space:]]*(.+)$/, "else\nifeq \\1 \\2", "1")
247 $0 = gensub(/^!ELSEIF[[:space:]]+(.+)[[:space:]]*!=[[:space:]]*(.+)$/, "else\nifneq \\1 \\2", "1")
252 if(/^!ENDIF[[:space:]]*$/) {
253 for (i = 0; i < stack[stacktop]; i++)
254 print "endif" > outfile
260 # catch the C++ compiler definition
262 print "CC=" prefix "gcc" > outfile
263 print "CFLAGS=" > outfile
264 print "CXX=" prefix "g++" > outfile
265 print "CXXFLAGS=$(CFLAGS)" > outfile
270 # catch the C++ compiler flags
273 print infile ":" inline ": " $0
275 # extract the flags from the line
277 sub(/^# ADD CPP /, "", cflags)
279 split(" " cflags, options, /[[:space:]]+\//)
285 # translate the options
286 # some of the translations effectively remove the option (and its arguments) since there is no translation equivalent
289 } else if(option ~ /^nologo$/) {
290 # Suppress Startup Banner and Information Messages
292 } else if (option ~ /^W0$/) {
293 # Turns off all warning messages
295 } else if (option ~ /^W[123]$/) {
298 } else if (option ~ /^W4$/) {
301 } else if (option ~ /^WX$/) {
304 } else if (option ~ /^Gm$/) {
305 # Enable Minimal Rebuild
307 } else if (option ~ /^GX$/) {
308 # Enable Exception Handling
309 option = "-fexceptions"
310 } else if (option ~ /^Z[d7iI]$/) {
313 } else if (option ~ /^Od$/) {
314 # Disable Optimizations
316 } else if (option ~ /^O1$/) {
319 } else if (option ~ /^O2$/) {
322 } else if (option ~ /^Ob0$/) {
323 # Disables inline Expansion
324 option = "-fno-inline"
325 } else if (option ~ /^Ob1$/) {
326 # In-line Function Expansion
328 } else if (option ~ /^Ob2$/) {
329 # auto In-line Function Expansion
330 option = "-finline-functions"
331 } else if (option ~ /^Oy$/) {
332 # Frame-Pointer Omission
333 option = "-fomit-frame-pointer"
334 } else if (option ~ /^GZ$/) {
335 # Catch Release-Build Errors in Debug Build
337 } else if (option ~ /^M[DLT]d?$/) {
338 # Use Multithreaded Run-Time Library
340 } else if (option ~ /^D/) {
341 # Preprocessor Definitions
342 gsub(/^D[[:space:]]*/, "", option)
343 option = "-D" fixquotes(option)
344 } else if (option ~ /^I/) {
345 # Additional Include Directories
346 gsub(/^I[[:space:]]*/, "", option)
347 option = "-I" fixpath(option)
348 } else if (option ~ /^U/) {
349 # Undefines a previously defined symbol
350 gsub(/^U[[:space:]]*/, "", option)
351 option = "-U" fixquotes(option)
352 } else if (option ~ /^Fp/) {
355 } else if (option ~ /^F[Rr]/) {
358 } else if (option ~ /^YX$/) {
359 # Automatic Use of Precompiled Headers
361 } else if (option ~ /^FD$/) {
362 # Generate File Dependencies
364 } else if (option ~ /^c$/) {
365 # Compile Without Linking
366 # this option is always present and is already specified in the suffix rules
368 } else if (option ~ /^GB$/) {
370 option = "-mcpu=pentiumpro -D_M_IX86=500"
371 } else if (option ~ /^G6$/) {
372 # Pentium Pro Optimization
373 option = "-march=pentiumpro -D_M_IX86=600"
374 } else if (option ~ /^G5$/) {
375 # Pentium Optimization
376 option = "-mcpu=pentium -D_M_IX86=500"
377 } else if (option ~ /^G3$/) {
379 option = "-mcpu=i386 -D_M_IX86=300"
380 } else if (option ~ /^G4$/) {
382 option = "-mcpu=i486 -D_M_IX86=400"
383 } else if (option ~ /^Yc/) {
384 # Create Precompiled Header
386 } else if (option ~ /^Yu/) {
387 # Use Precompiled Header
389 } else if (option ~ /^Za$/) {
390 # Disable Language Extensions
392 } else if (option ~ /^Ze$/) {
393 # Enable Microsoft Extensions
394 print infile ":" inline ": /" option ": Enable Microsoft Extensions option ignored" > "/dev/stderr"
396 } else if (option ~ /^Zm[[:digit:]]+$/) {
397 # Specify Memory Allocation Limit
399 } else if (option ~ /^Zp1$/) {
400 # Packs structures on 1-byte boundaries
401 option = "-fpack-struct"
402 } else if (option ~ /^Zp(2|4|8|16)?$/) {
403 # Struct Member Alignment
405 print infile ":" inline ": /" option ": Struct Member Alignment option ignored" > "/dev/stderr"
407 print infile ":" inline ": /" option ": C compiler option not implemented" > "/dev/stderr"
415 cflags = cflags " " option
421 gsub(/\\/, "/", cflags)
423 print "CFLAGS+=" cflags > outfile
426 print outfile ": " "CFLAGS+=" cflags
431 # catch the linker definition
434 print "LD=$(CXX) $(CXXFLAGS)" > outfile
436 print "LD=" prefix "dllwrap" > outfile
438 print "LDFLAGS=" > outfile
443 # catch the linker flags
444 if(/^# ADD LINK32 /) {
446 print infile ":" inline ": " $0
448 # extract the flags from the line
450 sub(/^# ADD LINK32 /, "", ldflags)
452 split(ldflags, options, /[[:space:]]+\//)
454 # attempts to get the used libraries to a seperate variable
456 libs = gensub(/([[:alnum:]/\\_-]+)\.lib/, "-l\\1", "g", libs)
463 # translate the options
464 # some of the translations effectively remove the option (and its arguments) since there is no translation equivalent
466 } else if (option ~ /^base:/) {
468 gsub(/^base:/, "--image-base ", option)
469 } else if (option ~ /^debug$/) {
470 # Generate Debug Info
472 } else if (option ~ /^dll$/) {
476 # remove this option since the DLL output option is handled by the suffix rules
478 } else if (option ~ /^incremental:[[:alpha:]]+$/) {
481 } else if (option ~ /^implib:/) {
482 # Name import library
483 gsub(/^implib:/, "", option)
484 option = "--implib " fixpath(gensub(/([[:alnum:]_-]+)\.lib/, "lib\\1.a", "g", option))
485 } else if (option ~ /^libpath:/) {
487 gsub(/^libpath:/, "", option)
488 option = "-L" fixpath(option)
489 } else if (option ~ /^machine:[[:alnum:]]+$/) {
490 # Specify Target Platform
492 } else if (option ~ /^map/) {
494 if (option ~ /^map:/)
495 gsub(/^map:/, "-Map ", option)
497 option = "-Map " name ".map"
498 } else if(option ~ /^nologo$/) {
499 # Suppress Startup Banner and Information Messages
501 } else if (option ~ /^out:/) {
503 target = fixpath(gensub(/out:("[^"]+"|[^[:space:]]+).*$/, "\\1", "1", option))
505 print "TARGET=" target > outfile
507 # remove this option since the output option is handled by the suffix rules
509 } else if (option ~ /^pdbtype:/) {
510 # Program Database Storage
512 } else if (option ~ /^subsystem:/) {
514 gsub(/^subsystem:/, "-Wl,--subsystem,", option)
515 } else if (option ~ /^version:[[:digit:].]+$/) {
516 # Version Information
519 print infile ":" inline ": /" option ": linker option not implemented" > "/dev/stderr"
527 ldflags = ldflags " " option
532 # attempt to get the name of the target from the '/out:' option
533 if (ldflags ~ /\/out:/) { # Output File Name
537 gsub(/\\/, "/", ldflags)
539 print "LDFLAGS+=" ldflags > outfile
540 print "LIBS+=" libs > outfile
543 print outfile ": " "LDFLAGS+=" ldflags
544 print outfile ": " "LIBS+=" libs
550 # catch the library archiver definition
554 print "AR=" prefix "ar" > outfile
559 # catch the library archiver flags
560 if(/^# ADD LIB32 /) {
561 # extract the flags from the line
563 sub(/^# ADD LIB32 /, "", arflags)
565 # translate the options
566 gsub(/\/nologo[[:space:]]*/, "", arflags) # Suppress Startup Banner and Information Messages
567 gsub(/\/machine:[[:alnum:]]+[[:space:]]*/, "", arflags) # Specify Target Platform
569 # attempt to get the name of the target from the '/out:' option
570 if (arflags ~ /\/out:/) {
571 target = fixpath(gensub(/^.*\/out:(".*"|[^[:space:]]+).*$/, "\\1", "1", arflags))
572 target = basedir(target) "/lib" basefile(gensub(/(\.[^.]*)?$/, ".a", 1, target))
574 print "TARGET=" target > outfile
576 # remove this option since the output option is handled differentely
577 sub(/\/out:(".*"|[^[:space:]]+)/, "", arflags)
581 gsub(/\\/, "/", arflags)
583 print "ARFLAGS=rus" > outfile
588 # catch the resource compiler definition
590 print "RC=" prefix "windres -O COFF" > outfile
594 # handle the begin of the target definition
595 if(/^# Begin Target$/) {
598 # print the default target name definition
599 print "ifndef TARGET" > outfile
601 print "TARGET=" name ".exe" > outfile
603 print "TARGET=" name ".dll" > outfile
605 print "TARGET=lib" name ".a" > outfile
606 print "endif" > outfile
609 # print the default target and the suffix rules
610 print ".PHONY: all" > outfile
611 print "all: $(TARGET)" > outfile
613 print "%.o: %.c" > outfile
614 print "\t$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<" > outfile
616 print "%.o: %.cc" > outfile
617 print "\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<" > outfile
619 print "%.o: %.cpp" > outfile
620 print "\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<" > outfile
622 print "%.o: %.cxx" > outfile
623 print "\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<" > outfile
625 print "%.res: %.rc" > outfile
626 print "\t$(RC) $(CPPFLAGS) -o $@ -i $<" > outfile
629 # initialize some bookeeping variables
630 ngroups = 0 # number of groups in the target
631 nsources = 0 # number of isolated sources in the target
632 groupflag = 0 # state variable that indicates if we are inside or outside of a group definition
637 # handle the end of a target definition
638 if(/^# End Target$/) {
639 # print the sources files definition that includes...
640 printf "SRCS=" > outfile
642 # ... the sources groups variables...
643 for (i = 0; i < ngroups; i++)
644 printf "$(%s) ", groups[i] > outfile
646 # ... and isolated sources not included in any group
648 print " \\" > outfile
649 for (i = 0; i < nsources - 1; i++)
650 print "\t" sources[i] " \\" > outfile
651 print "\t" sources[i] > outfile
657 # define the objects automatically from the sources in the Makefile
658 print "OBJS=$(patsubst %.rc,%.res,$(patsubst %.cxx,%.o,$(patsubst %.cpp,%.o,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(filter %.c %.cc %.cpp %.cxx %.rc,$(SRCS)))))))" > outfile
661 # print the target rule, according with the type of target
662 print "$(TARGET): $(OBJS)" > outfile
664 print "\t$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)" > outfile
666 print "\t$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)" > outfile
668 print "\t$(AR) $(ARFLAGS) $@ $(OBJS)" > outfile
674 # gather groups of source files to put them in diferent variables in the Makefile
675 if(/^# Begin Group/) {
677 groupname = gensub(/^# Begin Group "(.*)"$/, "\\1", "1")
679 # take the variable name as the upper case of the group name and changing the spaces to underscores
680 groupvarname = toupper(groupname)
681 gsub(/[[:space:]]/, "_", groupvarname)
683 # add this information to the groups array
684 groups[ngroups] = groupvarname
687 # initialize some bookeeping variables
688 ngsources = 0 # number of sources in this group
690 # signal that we are inside a group
695 if(/^# End Group$/) {
696 # print the group source variable definition
697 printf "%s=", groupvarname > outfile
699 for (i = 0; i < ngsources; i++)
700 printf " \\\n\t%s", gsources[i] > outfile
705 # signal that we are outside a group
712 # get the source file name
713 source = fixpath(gensub(/^SOURCE=(.*)$/, "\\1", "1"))
715 # add to the group sources or isolated sources according we are in a group or not
718 gsources[ngsources] = source
723 sources[nsources] = source
730 # attempts to handle custom builds definition
731 if(/^# Begin Custom Build/) {
732 print infile ":" inline ": " source ": Custom Build" > "/dev/stderr"
734 # signal we are inside a custom build definition
740 if(/^# End Custom Build/) {
741 # signal we are leaving a custom build definition
750 # MSDS handles customs builds defining a series of variables for the user convenience
751 # handle their definition ...
752 if($0 ~ /^IntDir=/) {
753 gsub(/^IntDir=/, "", $0)
757 if($0 ~ /^IntPath=/) {
758 gsub(/^IntPath=/, "", $0)
759 IntPath = fixpath($0)
762 if($0 ~ /^OutDir=/) {
763 gsub(/^OutDir=/, "", $0)
764 OutDir_ = fixpath($0)
768 if($0 ~ /^InputDir=/) {
769 gsub(/^InputDir=/, "", $0)
770 InputDir = fixpath($0)
773 if($0 ~ /^InputName=/) {
774 gsub(/^InputName=/, "", $0)
775 InputName = fixquotes($0)
778 if($0 ~ /^InputPath=/) {
779 gsub(/^InputPath=/, "", $0)
780 InputPath = fixpath($0)
783 if($0 ~ /^TargetDir=/) {
784 gsub(/^TargetDir=/, "", $0)
785 TargetDir_ = fixpath($0)
789 if($0 ~ /^TargetPath=/) {
790 gsub(/^TargetPath=/, "", $0)
791 gsub(TargetDir_, ".", $0)
792 TargetPath = fixpath($0)
796 # ... and substitute them in the rules
797 gsub(/\$\(IntDir\)/, IntDir)
798 gsub(/\$\(IntPath\)/, IntPath)
799 gsub(/\$\(OutDir\)/, OutDir)
800 gsub(/\$\(InputDir\)/, InputDir)
801 gsub(/\$\(InputName\)/, InputName)
802 gsub(/\$\(InputPath\)/, InputPath)
803 gsub(/\$\(TargetDir\)/, TargetDir)
804 gsub(/\$\(TargetPath\)/, TargetPath)
806 gsub(/\$\(SOURCE\)/, source)
807 gsub(/"\$\(INTDIR\)"[[:space:]]*/, "")
808 gsub(/"\$\(OUTDIR\)"[[:space:]]*/, "")
810 # do a serie of generic actions to convert the rule
819 print outfile ": " $0
823 # print the 'clean' target rule
824 print ".PHONY: clean" > outfile
825 print "clean:" > outfile
826 print "\t-" rm " $(OBJS) $(TARGET) " dependencies > outfile
829 # print the 'depends' target rule for automatic dependencies generation
830 print ".PHONY: depends" > outfile
831 print "depends:" > outfile
832 print "\t-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $(filter %.c %.cc %.cpp %.cxx,$(SRCS)) > " dependencies> outfile
834 print "-include " dependencies > outfile
842 # parses a workpace file (.dsw) specified by 'infile' and generates a makefile to 'outfile'
843 function parse_dsw(infile, outfile, i)
847 # print the Makefile header
848 print "# Makefile - " basefile(infile) > outfile
851 # initialize the number of projects counter
855 while((getline < infile) == 1) {
856 # Strip DOS line-endings
859 # catch a project definition
861 # increment the project counter
865 # extract the project name and filename
866 project_name[project] = fixpath(gensub(/^Project:[[:blank:]]+(.*)=(.*)[[:blank:]]+-[[:blank:]]+.*$/, "\\1", 1))
867 project_file[project] = fixpath(gensub(/^Project:[[:blank:]]+(.*)=(.*)[[:blank:]]+-[[:blank:]]+.*$/, "\\2", 1))
869 # check for a .dsp file extension
870 if(project_file[project] ~ /\.[Dd][Ss][Pp]$/) {
871 # create the output filename by renaming the file extension from .dsp to .mak
872 project_makefile[project] = project_file[project]
873 sub(/(\.[^.]*)?$/, ".mak", project_makefile[project])
876 project_makefile[project] = ""
878 # initialize the project dependencies
879 project_dependencies[project] = ""
884 # catch a project dependency marker
885 if(project && /^{{{$/) {
886 # read dependencies until the end marker
887 while((getline < infile) == 1 && !/^}}}$/)
888 if(/^[[:blank:]]*Project_Dep_Name[[:blank:]]+/)
889 project_dependencies[project] = project_dependencies[project] " " fixpath(gensub(/^[[:blank:]]*Project_Dep_Name[[:blank:]]+(.*)$/, "\\1", 1))
894 # catch other (perhaps important) section definitions and produce a warning
898 print infile ": " gensub(/^([[:alpha:]]+):/, "\\1", 1) ": unknown section" > "/dev/stderr"
902 # print the default target rule
903 print ".PHONY: all" > outfile
904 printf "all:" > outfile
905 for(i = 0; i < nprojects; i++)
906 printf " \\\n\t%s", project_name[i] > outfile
910 # print the rules for each project target
911 for(i = 0; i < nprojects; i++) {
912 print ".PHONY: " project_name[i] > outfile
913 print project_name[i] ":" project_dependencies[i] > outfile
914 if(project_makefile[i] != "") {
915 if(basedir(project_makefile[i]) == "")
916 print "\t$(MAKE) -f " project_makefile[i] > outfile
918 print "\t$(MAKE) -C " basedir(project_makefile[i]) " -f " basefile(project_makefile[i]) > outfile
923 # print the 'clean' target rule
924 print ".PHONY: clean" > outfile
925 print "clean:" > outfile
926 for(i = 0; i < nprojects; i++)
927 if(project_makefile[i] != "") {
928 if(basedir(project_makefile[i]) == "")
929 print "\t$(MAKE) -f " project_makefile[i] " clean" > outfile
931 print "\t$(MAKE) -C " basedir(project_makefile[i]) " -f " basefile(project_makefile[i]) " clean" > outfile
935 # print the 'depends' target rule for automatic dependencies generation
936 print ".PHONY: depends" > outfile
937 print "depends:" > outfile
938 for(i = 0; i < nprojects; i++)
939 if(project_makefile[i] != "") {
940 if(basedir(project_makefile[i]) == "")
941 print "\t$(MAKE) -f " project_makefile[i] " depends" > outfile
943 print "\t$(MAKE) -C " basedir(project_makefile[i]) " -f " basefile(project_makefile[i]) " depends" > outfile
950 # parse every project file
951 for(i = 0; i < nprojects; i++)
952 if(project_makefile[i] != "") {
953 if(basedir(infile) == "")
954 parse_dsp(project_file[i], project_makefile[i])
956 parse_dsp(basedir(infile) "\\" project_file[i], basedir(infile) "\\" project_makefile[i])
962 print "dsw2mak.awk Generates a Makefile from a .DSW/.DSP file Jose Fonseca"
965 # for each argument ...
966 for (i = 1; i < ARGC; i++) {
969 # determine whether is a workspace or a project file and parse it
970 if(infile ~ /\.[Dd][Ss][Ww]$/) {
971 # create the output filename by renaming the filename to Makefile
973 sub(/[^\/\\:]+$/, "Makefile", outfile)
975 parse_dsw(infile, outfile)
976 } else if(infile ~ /\.[Dd][Ss][Pp]$/) {
977 # create the output filename by renaming the file extension from .dsp to .mak
979 sub(/(\.[^.]*)?$/, ".mak", outfile)
981 parse_dsp(infile, outfile)
983 print infile ": unknown file format" > "/dev/stderr"