3 # Helper makefile for ReactOS modules
4 # Variables this makefile accepts:
5 # $TARGET_TYPE = Type of target:
6 # program = User mode program
7 # proglib = Executable program that have exported functions
8 # dynlink = Dynamic Link Library (DLL)
9 # library = Library that will be linked with other code
10 # driver_library = Import library for a driver
11 # driver = Kernel mode driver
12 # export_driver = Kernel mode driver that have exported functions
13 # hal = Hardware Abstraction Layer
14 # bootpgm = Boot program
15 # miniport = Kernel mode driver that does not link with ntoskrnl.exe or hal.dll
16 # gdi_driver = Kernel mode graphics driver that link with win32k.sys
17 # $TARGET_APPTYPE = Application type (windows,native,console)
18 # $TARGET_NAME = Base name of output file and .rc, .def, and .edf files
19 # $TARGET_OBJECTS = Object files that compose the module
20 # $TARGET_HEADERS = Header files that the object files depend on (optional)
21 # $TARGET_DEFNAME = Base name of .def and .edf files (optional)
22 # $TARGET_BASENAME = Base name of output file (overrides $TARGET_NAME if it exists) (optional)
23 # $TARGET_EXTENSION = Extesion of the output file (optional)
24 # $TARGET_DDKLIBS = DDK libraries that are to be imported by the module (optional)
25 # $TARGET_SDKLIBS = SDK libraries that are to be imported by the module (optional)
26 # $TARGET_LIBS = Other libraries that are to be imported by the module (optional)
27 # $TARGET_GCCLIBS = GCC libraries imported with -l (optional)
28 # $TARGET_LFLAGS = GCC flags when linking (optional)
29 # $TARGET_CFLAGS = GCC flags (optional)
30 # $TARGET_CPPFLAGS = G++ flags (optional)
31 # $TARGET_ASFLAGS = GCC assembler flags (optional)
32 # $TARGET_NFLAGS = NASM flags (optional)
33 # $TARGET_RCFLAGS = Windres flags (optional)
34 # $TARGET_CLEAN = Files that are part of the clean rule (optional)
35 # $TARGET_PATH = Relative path for *.def, *.edf, and *.rc (optional)
36 # $TARGET_BASE = Default base address (optional)
37 # $TARGET_ENTRY = Entry point (optional)
38 # $TARGET_DEFONLY = Use .def instead of .edf extension (no,yes) (optional)
39 # $TARGET_NORC = Do not include standard resource file (no,yes) (optional)
40 # $TARGET_LIBPATH = Destination path for import libraries (optional)
41 # $TARGET_INSTALLDIR = Destination path when installed (optional)
42 # $WINE_MODE = Compile using WINE headers (no,yes) (optional)
43 # $WINE_RC = Name of .rc file for WINE modules (optional)
45 include $(PATH_TO_TOP)/config
48 ifeq ($(TARGET_PATH),)
53 ifeq ($(TARGET_TYPE),program)
57 MK_DEFENTRY := _DEFINE_TARGET_APPTYPE
60 ifneq ($(WINE_MODE),yes)
61 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
62 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
63 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
65 MK_CFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
66 MK_CPPFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
67 MK_RCFLAGS := --include-dir $(PATH_TO_TOP)/include/wine --include-dir $(WINE_INCLUDE)
76 MK_RES_BASE := $(TARGET_NAME)
78 MK_RES_BASE := $(WINE_RC)
82 ifeq ($(TARGET_TYPE),proglib)
86 MK_DEFENTRY := _WinMain@16
89 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
90 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
91 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
94 MK_IMPLIBDEFPATH := $(SDK_PATH_LIB)
98 MK_RES_BASE := $(TARGET_NAME)
101 ifeq ($(TARGET_TYPE),dynlink)
105 MK_DEFENTRY := _DllMain@12
108 ifneq ($(WINE_MODE),yes)
109 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
110 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
111 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
113 MK_CFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
114 MK_CPPFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
115 MK_RCFLAGS := --include-dir $(PATH_TO_TOP)/include/wine --include-dir $(WINE_INCLUDE)
119 MK_IMPLIBDEFPATH := $(SDK_PATH_LIB)
121 MK_INSTALLDIR := system32
124 MK_RES_BASE := $(TARGET_NAME)
126 MK_RES_BASE := $(WINE_RC)
130 ifeq ($(TARGET_TYPE),library)
137 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
138 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
139 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
144 MK_INSTALLDIR := system32
145 MK_DISTDIR := # FIXME
149 ifeq ($(TARGET_TYPE),driver_library)
156 MK_CFLAGS := -I./ -I$(DDK_PATH_INC)
157 MK_CPPFLAGS := -I./ -I$(DDK_PATH_INC)
158 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
161 MK_IMPLIBDEFPATH := $(DDK_PATH_LIB)
163 MK_INSTALLDIR := $(DDK_PATH_INC)
164 MK_DISTDIR := # FIXME
168 ifeq ($(TARGET_TYPE),driver)
172 MK_DEFENTRY := _DriverEntry@8
173 MK_DDKLIBS := ntoskrnl.a hal.a
175 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
176 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
177 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
182 MK_INSTALLDIR := system32/drivers
183 MK_DISTDIR := drivers
184 MK_RES_BASE := $(TARGET_NAME)
187 ifeq ($(TARGET_TYPE),export_driver)
191 MK_DEFENTRY := _DriverEntry@8
192 MK_DDKLIBS := ntoskrnl.a hal.a
194 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
195 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
196 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
199 MK_IMPLIBDEFPATH := $(DDK_PATH_LIB)
201 MK_INSTALLDIR := system32/drivers
202 MK_DISTDIR := drivers
203 MK_RES_BASE := $(TARGET_NAME)
206 ifeq ($(TARGET_TYPE),hal)
210 MK_DEFENTRY := _DriverEntry@8
211 MK_DDKLIBS := ntoskrnl.a
213 MK_CFLAGS := -D__NTHAL__ -I./ -I$(DDK_PATH_INC)
214 MK_CPPFLAGS := -D__NTHAL__ -I./ -I$(DDK_PATH_INC)
215 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
220 MK_INSTALLDIR := system32
222 MK_RES_BASE := $(TARGET_NAME)
225 ifeq ($(TARGET_TYPE),bootpgm)
229 MK_DEFENTRY := _DriverEntry@8
232 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
233 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
234 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
239 MK_INSTALLDIR := system32
240 MK_DISTDIR := # FIXME
241 MK_RES_BASE := $(TARGET_NAME)
244 ifeq ($(TARGET_TYPE),miniport)
248 MK_DEFENTRY := _DriverEntry@8
251 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
252 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
253 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
258 MK_INSTALLDIR := system32/drivers
259 MK_DISTDIR := drivers
260 MK_RES_BASE := $(TARGET_NAME)
263 ifeq ($(TARGET_TYPE),gdi_driver)
267 MK_DEFENTRY := _DrvEnableDriver@12
268 MK_DDKLIBS := ntoskrnl.a hal.a win32k.a
270 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
271 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
272 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
275 MK_IMPLIBDEFPATH := $(DDK_PATH_LIB)
277 MK_INSTALLDIR := system32/drivers
278 MK_DISTDIR := drivers
279 MK_RES_BASE := $(TARGET_NAME)
283 ifeq ($(TARGET_TYPE),program)
284 ifeq ($(TARGET_APPTYPE),windows)
285 MK_DEFENTRY := _WinMainCRTStartup
286 MK_SDKLIBS := ntdll.a kernel32.a gdi32.a user32.a
287 TARGET_LFLAGS += -Wl,--subsystem,windows
290 ifeq ($(TARGET_APPTYPE),native)
291 MK_DEFENTRY := _NtProcessStartup@4
292 MK_SDKLIBS := ntdll.a
293 TARGET_LFLAGS += -Wl,--subsystem,native -nostartfiles
296 ifeq ($(TARGET_APPTYPE),console)
297 MK_DEFENTRY := _mainCRTStartup
299 TARGET_LFLAGS += -Wl,--subsystem,console
304 MK_RESOURCE := $(MK_RES_BASE).coff
307 ifneq ($(TARGET_INSTALLDIR),)
308 MK_INSTALLDIR := $(TARGET_INSTALLDIR)
312 ifeq ($(TARGET_LIBPATH),)
313 MK_IMPLIBPATH := $(MK_IMPLIBDEFPATH)
315 MK_IMPLIBPATH := $(TARGET_LIBPATH)
319 ifeq ($(TARGET_BASENAME),)
320 MK_BASENAME := $(TARGET_NAME)
322 MK_BASENAME := $(TARGET_BASENAME)
326 ifeq ($(TARGET_EXTENSION),)
327 MK_EXT := $(MK_DEFEXT)
329 MK_EXT := $(TARGET_EXTENSION)
333 ifeq ($(TARGET_NORC),yes)
336 MK_FULLRES := $(TARGET_PATH)/$(MK_RESOURCE)
340 ifeq ($(TARGET_DEFNAME),)
341 MK_DEFBASE := $(TARGET_NAME)
343 MK_DEFBASE := $(TARGET_DEFNAME)
346 MK_DEFNAME := $(TARGET_PATH)/$(MK_DEFBASE).def
347 ifeq ($(TARGET_DEFONLY),yes)
348 MK_EDFNAME := $(MK_DEFNAME)
350 MK_EDFNAME := $(TARGET_PATH)/$(MK_DEFBASE).edf
354 ifeq ($(MK_MODE),user)
355 MK_DEFBASE := 0x400000
356 ifneq ($(TARGET_SDKLIBS),)
357 MK_LIBS := $(addprefix $(SDK_PATH_LIB)/, $(TARGET_SDKLIBS))
359 MK_LIBS := $(addprefix $(SDK_PATH_LIB)/, $(MK_SDKLIBS))
364 ifeq ($(MK_MODE),kernel)
365 MK_DEFBASE := 0x10000
366 MK_LIBS := $(addprefix $(DDK_PATH_LIB)/, $(MK_DDKLIBS) $(TARGET_DDKLIBS))
370 ifeq ($(TARGET_BASE),)
371 TARGET_BASE := $(MK_DEFBASE)
375 ifeq ($(TARGET_ENTRY),)
376 TARGET_ENTRY := $(MK_DEFENTRY)
381 # Include details of the OS configuration
383 include $(PATH_TO_TOP)/config
386 TARGET_CFLAGS += $(MK_CFLAGS)
387 TARGET_CFLAGS += -pipe -march=$(ARCH)
394 TARGET_CPPFLAGS += $(MK_CPPFLAGS)
395 TARGET_CPPFLAGS += -pipe -march=$(ARCH)
397 TARGET_RCFLAGS += $(MK_RCFLAGS)
399 TARGET_ASFLAGS += $(MK_ASFLAGS)
400 TARGET_ASFLAGS += -pipe -march=$(ARCH)
402 TARGET_NFLAGS += $(MK_NFLAGS)
405 MK_GCCLIBS := $(addprefix -l, $(TARGET_GCCLIBS))
407 MK_FULLNAME := $(MK_BASENAME)$(MK_EXT)
408 MK_IMPLIB_FULLNAME := $(MK_BASENAME)$(MK_IMPLIB_EXT)
410 MK_NOSTRIPNAME := $(MK_BASENAME).nostrip$(MK_EXT)
412 # We don't want to link header files
413 MK_OBJECTS := $(filter-out %.h,$(TARGET_OBJECTS))
414 MK_STRIPPED_OBJECT := $(MK_BASENAME).stripped.o
416 ifeq ($(MK_IMPLIBONLY),yes)
418 TARGET_CLEAN += $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME)
420 all: $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME)
422 $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME): $(TARGET_OBJECTS)
424 --dllname $(MK_FULLNAME) \
425 --def $(MK_DEFNAME) \
426 --output-lib $(MK_IMPLIBPATH)/$(MK_BASENAME).a \
432 all: $(MK_FULLNAME) $(MK_NOSTRIPNAME)
435 ifeq ($(MK_IMPLIB),yes)
436 MK_EXTRACMD := --def $(MK_EDFNAME)
442 ifeq ($(MK_MODE),user)
444 ifeq ($(MK_EXETYPE),dll)
445 TARGET_LFLAGS += -mdll -Wl,--image-base,$(TARGET_BASE)
446 MK_EXTRACMD2 := -Wl,temp.exp
451 $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS)
452 ifeq ($(MK_EXETYPE),dll)
453 $(CC) -Wl,--base-file,base.tmp \
454 -Wl,--entry,$(TARGET_ENTRY) \
457 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
459 $(DLLTOOL) --dllname $(MK_FULLNAME) \
460 --base-file base.tmp \
461 --output-exp temp.exp $(MK_EXTRACMD)
464 $(CC) $(TARGET_LFLAGS) \
465 -Wl,--entry,$(TARGET_ENTRY) $(MK_EXTRACMD2) \
466 -o $(MK_NOSTRIPNAME) \
467 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
469 - $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym
471 $(MK_FULLNAME): $(MK_NOSTRIPNAME)
472 $(CP) $(MK_NOSTRIPNAME) $(MK_FULLNAME)
473 # $(STRIP) --strip-debug $(MK_FULLNAME)
477 # Kernel mode targets
478 ifeq ($(MK_MODE),kernel)
480 ifeq ($(MK_IMPLIB),yes)
481 MK_EXTRACMD := --def $(MK_EDFNAME)
486 $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS)
487 $(CC) -Wl,--base-file,base.tmp \
488 -Wl,--entry,$(TARGET_ENTRY) \
490 -nostartfiles -nostdlib \
492 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
494 $(DLLTOOL) --dllname $(MK_FULLNAME) \
495 --base-file base.tmp \
496 --output-exp temp.exp $(MK_EXTRACMD)
498 $(CC) $(TARGET_LFLAGS) \
499 -Wl,--subsystem,native \
500 -Wl,--image-base,$(TARGET_BASE) \
501 -Wl,--file-alignment,0x1000 \
502 -Wl,--section-alignment,0x1000 \
503 -Wl,--entry,$(TARGET_ENTRY) \
505 -mdll -nostartfiles -nostdlib \
506 -o $(MK_NOSTRIPNAME) \
507 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
509 $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym
511 $(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS) $(MK_NOSTRIPNAME)
512 $(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS)
513 $(STRIP) --strip-debug $(MK_STRIPPED_OBJECT)
514 $(CC) -Wl,--base-file,base.tmp \
515 -Wl,--entry,$(TARGET_ENTRY) \
517 -nostartfiles -nostdlib \
519 $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
521 $(DLLTOOL) --dllname $(MK_FULLNAME) \
522 --base-file base.tmp \
523 --output-exp temp.exp $(MK_EXTRACMD)
525 $(CC) $(TARGET_LFLAGS) \
526 -Wl,--subsystem,native \
527 -Wl,--image-base,$(TARGET_BASE) \
528 -Wl,--file-alignment,0x1000 \
529 -Wl,--section-alignment,0x1000 \
530 -Wl,--entry,$(TARGET_ENTRY) \
532 -mdll -nostartfiles -nostdlib \
534 $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
539 # Static library target
540 ifeq ($(MK_MODE),static)
542 $(MK_FULLNAME): $(TARGET_OBJECTS)
543 $(AR) -r $(MK_FULLNAME) $(TARGET_OBJECTS)
547 endif # MK_IMPLIBONLY
550 $(MK_FULLRES): $(PATH_TO_TOP)/include/reactos/buildno.h $(TARGET_PATH)/$(MK_RES_BASE).rc
552 ifeq ($(MK_IMPLIB),yes)
553 $(MK_IMPLIBPATH)/$(MK_BASENAME).a: $(MK_DEFNAME)
554 $(DLLTOOL) --dllname $(MK_FULLNAME) \
555 --def $(MK_DEFNAME) \
556 --output-lib $(MK_IMPLIBPATH)/$(MK_BASENAME).a \
559 implib: $(MK_IMPLIBPATH)/$(MK_BASENAME).a
564 # Be carefull not to clean non-object files
565 MK_CLEANFILES := $(filter %.o,$(MK_OBJECTS))
568 - $(RM) *.o $(MK_BASENAME).sym $(MK_BASENAME).a $(TARGET_PATH)/$(MK_RES_BASE).coff \
569 $(MK_FULLNAME) $(MK_NOSTRIPNAME) $(MK_CLEANFILES) \
570 junk.tmp base.tmp temp.exp \
573 ifneq ($(TARGET_HEADERS),)
574 $(TARGET_OBJECTS): $(TARGET_HEADERS)
577 # install and dist rules
579 ifeq ($(MK_IMPLIBONLY),yes)
581 # Don't install import libraries
590 install: $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME)
592 $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME): $(MK_FULLNAME) $(MK_BASENAME).sym
593 $(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME)
594 $(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_BASENAME).sym
597 dist: $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME)
599 $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME): $(MK_FULLNAME)
600 $(CP) $(MK_FULLNAME) $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME)
601 $(CP) $(MK_BASENAME).sym $(DIST_DIR)/symbols/$(MK_BASENAME).sym
604 endif # MK_IMPLIBONLY
607 .phony: all implib clean install dist
611 $(CC) $(TARGET_CFLAGS) -c $< -o $@
613 $(CC) $(TARGET_CPPFLAGS) -c $< -o $@
615 $(CC) $(TARGET_CPPFLAGS) -c $< -o $@
617 $(AS) $(TARGET_ASFLAGS) -c $< -o $@
619 $(AS) $(TARGET_ASFLAGS) -c $< -o $@
621 $(NASM_CMD) $(NFLAGS) $(TARGET_NFLAGS) $< -o $@
623 $(RC) $(TARGET_RCFLAGS) $(RCINC) $< -o $@
627 CFLAGS := $(TARGET_CFLAGS)