cffffba59890316caee80babfc2c7edaa4dfbd8f
[supertux.git] / mk / jam / msvcgen.jam
1 #============================================================================
2 # Rules for creating msvc projectfiles
3 #============================================================================
4
5 # BUGS & TODO 
6 #------------
7 # - Create a secondary target (such as "msvcinst") which copies the generated
8 #   project files from the build/"out" directory back into the source
9 #   directory.  This is useful for maintainers who, after having created and
10 #   tested a new set of project files, want to then commit them to the CVS
11 #   repository.
12 #
13 # - Either respect ExternaLibs() or fix all the Jamfiles which require special
14 #   Windows libraries to invoke MsvcExternalLibrary().  This is necessary for
15 #   modules such as cssocket and ensocket which require wsock32.lib, for
16 #   instance.  There are a number of other such modules.  The current monlithic
17 #   solution of placing this information in CS/mk/msvcgen/Jamconfig is ugly,
18 #   error-prone, and a maintenance headache.
19 #
20 # - Overhaul the "config" file handling rule so that it associates
21 #   configuration files with built targets.  This will allow the generated
22 #   projects to reference configuration files.  Rather than the present
23 #   InstallConfig rule, we either need a ConfigFile:<target>:<configs> rule, or
24 #   we should upgrade the Application and Plugin rules to also accept
25 #   configuration files.
26 #
27 # - Likewise, provide a generic Resources() rule which allows specification of
28 #   additional textual resources for inclusion in generated projects.
29 #
30 # - Upgrade module Jamfiles to mention headers from the CS/include/module
31 #   directory.  This will allow related headers to appear in the generated
32 #   project files.  For instance, the libcsengine project should mention
33 #   headers from CS/include/csengine, in addition to the ones from
34 #   CS/libs/csengine which it currently mentions.
35 #
36 # - When PERL5.SDK.AVAILABLE is "yes", Jam reports that it doesn't know how to
37 #   locate or create <grist>csperlxs.c.
38
39 if $(MSVCGEN_CONFIG)
40 {
41
42 MSVCGEN = "$(PERL) $(TOP)/mk/msvcgen/msvcgen.pl" ;
43 MKVERRES = "$(SHELL) $(TOP)/libs/cssys/win32/mkverres.sh" ;
44 MKMETADATARES = "$(SHELL) $(TOP)/libs/cssys/win32/mkmetadatares.sh" ;
45 MERGERES = "$(SHELL) $(TOP)/libs/cssys/win32/mergeres.sh" ;
46
47 MSVCGEN_BUILD_ROOT = $(BUILDTOP)/out ;
48
49 MSVC_VERSION ?= 6 ;
50 if $(MSVC_VERSION) = 6
51 {
52   MSVCGEN_LOCATE_TARGET ?= $(MSVCGEN_BUILD_ROOT)/mk/visualc6 ;
53   MSVCGEN_LOCATE_FRAGMENT ?= $(MSVCGEN_BUILD_ROOT)/mk/fragment6 ;
54   MSVCGEN_TEMPLATEDIR ?= $(TOP)/mk/msvcgen/template6 ;
55   MSVCGEN_EXTRA_OPTS = ;
56   SSUFPRJ = dsp ;
57   SSUFWSP = dsw ;
58   SUFPRJ = .dsp ;
59   SUFWSP = .dsw ;
60 }
61 else if $(MSVC_VERSION) = 7
62 {
63   MSVCGEN_LOCATE_TARGET ?= $(MSVCGEN_BUILD_ROOT)/mk/visualc7 ;
64   MSVCGEN_LOCATE_FRAGMENT ?= $(MSVCGEN_BUILD_ROOT)/mk/fragment7 ;
65   MSVCGEN_TEMPLATEDIR ?= $(TOP)/mk/msvcgen/template7 ;
66   MSVCGEN_EXTRA_OPTS = --xml-protect ;
67   SSUFPRJ = vcproj ;
68   SUFPRJ = .vcproj ;
69   SSUFWSP = sln ;
70   SUFWSP = .sln ;
71 }
72 else
73 {
74   EXIT "No support for MSVC version $(MSVC_VERSION) yet!" ;
75 }
76   
77 #----------------------------------------------------------------------------
78 # Override some rules
79
80
81 ## MsvcProject target : sources : type : target-with-ext
82 rule MsvcProject
83 {
84   local rcpath resource msvcname target fragments fragroot files i ;
85
86   switch $(3)
87   {
88     case appgui :
89       msvcname = app$(<) ;
90     case appcon :
91       msvcname = app$(<) ;
92     case plugin :
93       msvcname = plg$(<) ;
94     case library :
95       msvcname = lib$(<) ;
96     case group :
97       msvcname = grp$(<) ;
98     case * :
99       exit "Unknown msvc projecttype: $(3) specified!" ;
100   }
101   $(<)_MSVCNAME = $(msvcname) ;
102       
103   fragroot = $(MSVCGEN_LOCATE_FRAGMENT)/$(msvcname).frag ;
104   NotFile $(fragroot) ;
105
106   fragments = [ FAppendSuffix $(msvcname) : .frag.cff ]
107               [ FAppendSuffix $(msvcname) : .frag.dpf ]
108               [ FAppendSuffix $(msvcname) : .frag.pjf ] ;
109   MakeLocate $(fragments) : $(MSVCGEN_LOCATE_FRAGMENT) ;
110   target = [ FAppendSuffix $(msvcname) : $(SUFPRJ) ] ;
111   MakeLocate $(target) : $(MSVCGEN_LOCATE_TARGET) ;
112   target += $(fragments) ;
113   $(<)_TARGET = $(target) ;
114
115   # Only include source and headers files for now.  In the future, we also
116   # want to include .cfg files and any other textual resources which which the
117   # user might care to read/view in the MSVC IDE.
118   for i in $(>)
119   {
120     i = $(i:G=$(LOCATE_SOURCE)) ;
121     switch $(i:S)
122     {
123       case .h   : files += $(i) ;
124       case .hpp : files += $(i) ;
125       case .H   : files += $(i) ;
126       case .c   : files += $(i) ;
127       case .cc  : files += $(i) ;
128       case .cpp : files += $(i) ;
129       case .m   : files += $(i) ;
130       case .mm  : files += $(i) ;
131       case .M   : files += $(i) ;
132     }
133   }
134   # Search at the correct place for the files
135   SEARCH on $(files) = $(SEARCH_SOURCE) ;
136
137   # Add resource file
138   if $(3) = "plugin" || $(3) = "appgui" || $(3) = "appcon"
139   {
140     resource = $(msvcname:S=.rc) ;
141     # @@@ Uber-ugly
142     rcpath = ../../../mk/visualc7/$(msvcname:S=.rc) ;
143     #files += $(resource) ;
144     Depends $(target) : $(resource) ;
145     LOCATE on $(resource) = $(MSVCGEN_LOCATE_TARGET) ;
146     SEARCH on $(resource) = $(MSVCGEN_LOCATE_FRAGMENT) ;
147     NAME on $(resource) = $(<) ;
148     #RCNAME on $(<) = $(resource) ;
149     $(<)_RCNAME = $(resource) ;
150     #ResourceGen $(resource) ;
151   
152     local versionrc = $(resource:S=.vrctmp) ;
153   
154     # normalize version list
155     local v1, v2, v3, v4 ;
156     v1 = $(PACKAGE.VERSION.LIST[1]) ;
157     if ! $(v1) { v1 = 0 ; }
158     v2 = $(PACKAGE.VERSION.LIST[2]) ;
159     if ! $(v2) { v2 = 0 ; }
160     v3 = $(PACKAGE.VERSION.LIST[3]) ;
161     if ! $(v3) { v3 = 0 ; }
162     v4 = $(PACKAGE.VERSION.LIST[4]) ;
163     if ! $(v4) { v4 = 0 ; }
164     PACKAGE.VERSION.LIST on $(versionrc) = $(v1) $(v2) $(v3) $(v4) ;
165         
166     # @@@ The "Help" rule is usually invoked after 'Plugin'/'Application',
167     # so "$(<)_help" is empty...
168     DESCRIPTION on $(versionrc) = $($(<)_help) ;
169         
170     LOCATE on $(versionrc) = $(MSVCGEN_LOCATE_FRAGMENT) ;
171     
172     GenerateWin32VersionRc $(versionrc) ;
173     Always $(versionrc) ;
174     Win32Resource $(<) : $(versionrc) ;
175     RmTemps $(target) : $(versionrc) ;
176     
177     if $(3) = "plugin" 
178     {
179       local metarc = $(resource:S=.mrctmp) ;
180     
181       LOCATE on $(metarc) = $(MSVCGEN_LOCATE_FRAGMENT) ;
182       SEARCH on $(metarc) = $(SEARCH_SOURCE) ;
183     
184       Depends $(metarc) : $($(<)_METAFILE) ;
185       GenerateWin32MetadataRc $(metarc) : $($(<)_METAFILE) ;
186       Always $(metarc) ;
187       Win32Resource $(<) : $(metarc) ;
188       RmTemps $(target) : $(metarc) ;
189     }
190   
191     Always $(resource) ;
192   }
193   
194   RAWNAME on $(target) = $(<) ;
195   PROJECTNAME on $(target) = $(msvcname) ;
196   TARGET on $(target) = $(4) ;
197   TYPE on $(target) = $(3) ;
198   FRAGMENT_ROOT on $(target) = $(fragroot) ;
199   DEPEND on $(target) += $(MSVC.DEPEND) $(MSVC.DEPEND.$(3)) ;
200   LIBRARIES on $(target) += $(MSVC.LIBRARY) $(MSVC.LIBRARY.$(3)) ;
201   LFLAGS on $(target) += $(MSVC.LFLAGS) $(MSVC.LFLAGS.$(3)) ;
202   CFLAGS on $(target) += $(MSVC.CFLAGS) $(MSVC.CFLAGS.$(3)) ;
203
204   Depends msvcgen : $(target) ;
205   Depends $(target) : $(files) $(MSVCGEN_LOCATE_FRAGMENT:G=dir) ;
206   MsvcProjectGen $(target) : $(files) $(rcpath) ;
207   Always $(target) ;
208
209   MSVCWorkspace csall : $(fragments) : $(fragroot) ;
210
211   Clean msvcclean : $(target) ;
212 }
213
214 #----------------------------------------------------------------------------
215
216 rule Application
217 {
218 #  _Options $(<) : $(3) ;
219
220   local projtype ;
221   if $(CONSOLEAPP_$(<)) = "yes"
222   {
223     projtype = appcon ;
224   }
225   else
226   {
227     projtype = appgui ;
228   }
229
230   MsvcProject $(<) : $(>) : $(projtype) : $(<:S=.exe) ;
231   CompileGroups $(<) : all apps ;
232 }
233
234 rule Plugin
235 {
236   local metafile ;
237   metafile = [ FAppendSuffix $(<) : $(SUFMETA) ] ;
238   SEARCH on $(metafile) = $(SEARCH_SOURCE) ;
239
240   $(<)_METAFILE = $(metafile) ;
241   
242   MsvcProject $(<) : $(>) : plugin : $(<:S=.dll) ;
243   CompileGroups $(<) : all plugins ;
244 }
245
246 rule Library
247 {
248   MsvcProject $(<) : $(>) : library : $(<:S=.lib) ;
249   CompileGroups $(<) : all libs ;
250 }
251
252 rule RegisterCompileGroups
253 {
254   local i ;
255   for i in $(<)
256   {
257     RegisterCompileGroup $(i) ;
258   }
259 }
260
261 rule RegisterCompileGroup
262 {
263   MsvcProject $(<) : $(>) : group ; 
264 }
265
266 rule CompileGroups
267 {
268   for i in $(>)
269   {
270     DEPEND on $($(i)_TARGET) += $($(<)_MSVCNAME) ;
271   }
272 }
273
274 rule LinkWith
275 {
276   DEPEND on $($(<)_TARGET) += lib$(>) ;
277 }
278
279 rule MsvcExternalLibrary
280 {
281   LIBRARIES on $($(<)_TARGET) += $(>) ;
282 }
283
284 rule CFlags
285 {
286   if $(>) != ""
287   {
288     CFLAGS on $($(<)_TARGET) += $(>) ;
289   }
290 }
291
292 rule LFlags
293 {
294   LFLAGS on $($(<)_TARGET) += $(>) ;
295 }
296
297 rule ExternalLibs
298 {
299   local i ;
300   
301   for i in $(>)
302   {
303     CFlags $(<) : $($(i).CFLAGS) ;
304     LFlags $(<) : $($(i).LFLAGS) ;
305     MsvcExternalLibrary $(<) : $($(i).MSVCLIBS) ;
306   }
307 }
308
309 rule MSVCWorkspace
310 {
311   local target ;
312
313   target = [ FAppendSuffix $(<) : $(SUFWSP) ] ;
314   MakeLocate $(target) : $(MSVCGEN_LOCATE_TARGET) ;
315
316   Depends msvcgen : $(target) ;
317   Depends $(target) : $(>[1]) ;
318   MsvcWorkspaceGen $(target) : $(3) ;
319
320   RmTemps $(target) : $(>) ;
321 }
322
323 rule Win32Resource
324 {
325   Depends $(<) : $($(<)_RCNAME) ;
326   Depends $($(<)_RCNAME) : $(>) ;
327   MergeRcs $($(<)_RCNAME) : $(>) ;
328 }
329
330 #----------------------------------------------------------------------------
331
332 actions MsvcProjectGen
333 {
334   $(MSVCGEN) \
335   --quiet \
336   --project \
337   $(MSVCGEN_EXTRA_OPTS) \
338   --project-extension=$(SSUFPRJ) \
339   --name=$(RAWNAME) \
340   --template=$(TYPE) \
341   --template-dir=$(MSVCGEN_TEMPLATEDIR) \
342   --project-name=$(PROJECTNAME) \
343   --output=$(<[1]) \
344   --target=$(TARGET) \
345   --fragment=$(FRAGMENT_ROOT) \
346   --depend=$(DEPEND) \
347   --library=$(LIBRARIES) \
348   --lflags='$(LFLAGS)' \
349   --cflags='$(CFLAGS)' \
350   --strip-root='$(TOP)/' \
351   --strip-root='$(MSVCGEN_BUILD_ROOT)/' \
352   $(>)
353 }
354
355 actions together MsvcWorkspaceGen
356 {
357   $(MSVCGEN) \
358   --quiet \
359   --workspace \
360   $(MSVCGEN_EXTRA_OPTS) \
361   --workspace-extension=$(SSUFWSP) \
362   --output=$(<) \
363   --template-dir=$(MSVCGEN_TEMPLATEDIR) \
364   $(>)
365 }
366
367 actions together MergeRcs
368 {
369   $(MERGERES) '$(<)' '$(TOP)' '../..' '$(>)'
370 }
371
372 #----------------------------------------------------------------------------
373
374 RegisterCompileGroups all apps plugins libs ;
375 NotFile msvcgen ;
376 Always msvcgen ;
377 Clean clean : $(MSVCGEN_LOCATE_TARGET:G=dir) ;
378 Clean clean : $(MSVCGEN_LOCATE_FRAGMENT:G=dir) ;
379 Clean clean : $(MSVCGEN_BUILD_ROOT) ;
380 Clean msvcclean : $(MSVCGEN_LOCATE_TARGET:G=dir) ;
381 Clean msvcclean : $(MSVCGEN_LOCATE_FRAGMENT:G=dir) ;
382
383 }