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 # $TARGET_PCH = Filename of header to use to generate a PCH if supported by the compiler (optional)
43 # $WINE_MODE = Compile using WINE headers (no,yes) (optional)
44 # $WINE_RC = Name of .rc file for WINE modules (optional)
46 include $(PATH_TO_TOP)/config
49 ifeq ($(TARGET_PATH),)
54 ifeq ($(TARGET_TYPE),program)
58 MK_DEFENTRY := _DEFINE_TARGET_APPTYPE
61 ifneq ($(WINE_MODE),yes)
62 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
63 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
64 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
66 MK_CFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
67 MK_CPPFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
68 MK_RCFLAGS := --include-dir $(PATH_TO_TOP)/include/wine --include-dir $(WINE_INCLUDE)
77 MK_RES_BASE := $(TARGET_NAME)
79 MK_RES_BASE := $(WINE_RC)
83 ifeq ($(TARGET_TYPE),proglib)
87 MK_DEFENTRY := _WinMain@16
90 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
91 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
92 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
95 MK_IMPLIBDEFPATH := $(SDK_PATH_LIB)
99 MK_RES_BASE := $(TARGET_NAME)
102 ifeq ($(TARGET_TYPE),dynlink)
106 MK_DEFENTRY := _DllMain@12
109 ifneq ($(WINE_MODE),yes)
110 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
111 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
112 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
114 MK_CFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
115 MK_CPPFLAGS := -I$(PATH_TO_TOP)/include/wine -I./ -I$(WINE_INCLUDE)
116 MK_RCFLAGS := --include-dir $(PATH_TO_TOP)/include/wine --include-dir $(WINE_INCLUDE)
120 MK_IMPLIBDEFPATH := $(SDK_PATH_LIB)
122 MK_INSTALLDIR := system32
125 MK_RES_BASE := $(TARGET_NAME)
127 MK_RES_BASE := $(WINE_RC)
131 ifeq ($(TARGET_TYPE),library)
138 MK_CFLAGS := -I./ -I$(SDK_PATH_INC)
139 MK_CPPFLAGS := -I./ -I$(SDK_PATH_INC)
140 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
145 MK_INSTALLDIR := system32
146 MK_DISTDIR := # FIXME
150 ifeq ($(TARGET_TYPE),driver_library)
157 MK_CFLAGS := -I./ -I$(DDK_PATH_INC)
158 MK_CPPFLAGS := -I./ -I$(DDK_PATH_INC)
159 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
162 MK_IMPLIBDEFPATH := $(DDK_PATH_LIB)
164 MK_INSTALLDIR := $(DDK_PATH_INC)
165 MK_DISTDIR := # FIXME
169 ifeq ($(TARGET_TYPE),driver)
173 MK_DEFENTRY := _DriverEntry@8
174 MK_DDKLIBS := ntoskrnl.a hal.a
176 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
177 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
178 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
183 MK_INSTALLDIR := system32/drivers
184 MK_DISTDIR := drivers
185 MK_RES_BASE := $(TARGET_NAME)
188 ifeq ($(TARGET_TYPE),export_driver)
192 MK_DEFENTRY := _DriverEntry@8
193 MK_DDKLIBS := ntoskrnl.a hal.a
195 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
196 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
197 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
200 MK_IMPLIBDEFPATH := $(DDK_PATH_LIB)
202 MK_INSTALLDIR := system32/drivers
203 MK_DISTDIR := drivers
204 MK_RES_BASE := $(TARGET_NAME)
207 ifeq ($(TARGET_TYPE),hal)
211 MK_DEFENTRY := _DriverEntry@8
212 MK_DDKLIBS := ntoskrnl.a
214 MK_CFLAGS := -D__NTHAL__ -I./ -I$(DDK_PATH_INC)
215 MK_CPPFLAGS := -D__NTHAL__ -I./ -I$(DDK_PATH_INC)
216 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
221 MK_INSTALLDIR := system32
223 MK_RES_BASE := $(TARGET_NAME)
226 ifeq ($(TARGET_TYPE),bootpgm)
230 MK_DEFENTRY := _DriverEntry@8
233 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
234 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
235 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
240 MK_INSTALLDIR := system32
241 MK_DISTDIR := # FIXME
242 MK_RES_BASE := $(TARGET_NAME)
245 ifeq ($(TARGET_TYPE),miniport)
249 MK_DEFENTRY := _DriverEntry@8
252 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
253 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
254 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
259 MK_INSTALLDIR := system32/drivers
260 MK_DISTDIR := drivers
261 MK_RES_BASE := $(TARGET_NAME)
264 ifeq ($(TARGET_TYPE),gdi_driver)
268 MK_DEFENTRY := _DrvEnableDriver@12
269 MK_DDKLIBS := ntoskrnl.a hal.a win32k.a
271 MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
272 MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC)
273 MK_RCFLAGS := --include-dir $(SDK_PATH_INC)
276 MK_IMPLIBDEFPATH := $(DDK_PATH_LIB)
278 MK_INSTALLDIR := system32/drivers
279 MK_DISTDIR := drivers
280 MK_RES_BASE := $(TARGET_NAME)
284 ifeq ($(TARGET_TYPE),program)
285 ifeq ($(TARGET_APPTYPE),windows)
286 MK_DEFENTRY := _WinMainCRTStartup
287 MK_SDKLIBS := ntdll.a kernel32.a gdi32.a user32.a
288 TARGET_LFLAGS += -Wl,--subsystem,windows
291 ifeq ($(TARGET_APPTYPE),native)
292 MK_DEFENTRY := _NtProcessStartup@4
293 MK_SDKLIBS := ntdll.a
294 TARGET_LFLAGS += -Wl,--subsystem,native -nostartfiles
297 ifeq ($(TARGET_APPTYPE),console)
298 MK_DEFENTRY := _mainCRTStartup
300 TARGET_LFLAGS += -Wl,--subsystem,console
304 ifeq ($(TARGET_TYPE),proglib)
305 ifeq ($(TARGET_APPTYPE),windows)
306 MK_DEFENTRY := _WinMainCRTStartup
307 MK_SDKLIBS := ntdll.a kernel32.a gdi32.a user32.a
308 TARGET_LFLAGS += -Wl,--subsystem,windows
311 ifeq ($(TARGET_APPTYPE),native)
312 MK_DEFENTRY := _NtProcessStartup@4
313 MK_SDKLIBS := ntdll.a
314 TARGET_LFLAGS += -Wl,--subsystem,native -nostartfiles
317 ifeq ($(TARGET_APPTYPE),console)
318 MK_DEFENTRY := _mainCRTStartup
320 TARGET_LFLAGS += -Wl,--subsystem,console
325 MK_RESOURCE := $(MK_RES_BASE).coff
328 ifneq ($(TARGET_INSTALLDIR),)
329 MK_INSTALLDIR := $(TARGET_INSTALLDIR)
333 ifeq ($(TARGET_LIBPATH),)
334 MK_IMPLIBPATH := $(MK_IMPLIBDEFPATH)
336 MK_IMPLIBPATH := $(TARGET_LIBPATH)
340 ifeq ($(TARGET_BASENAME),)
341 MK_BASENAME := $(TARGET_NAME)
343 MK_BASENAME := $(TARGET_BASENAME)
347 ifeq ($(TARGET_EXTENSION),)
348 MK_EXT := $(MK_DEFEXT)
350 MK_EXT := $(TARGET_EXTENSION)
354 ifeq ($(TARGET_NORC),yes)
357 MK_FULLRES := $(TARGET_PATH)/$(MK_RESOURCE)
361 ifeq ($(TARGET_DEFNAME),)
362 MK_DEFBASE := $(TARGET_NAME)
364 MK_DEFBASE := $(TARGET_DEFNAME)
367 MK_DEFNAME := $(TARGET_PATH)/$(MK_DEFBASE).def
368 ifeq ($(TARGET_DEFONLY),yes)
369 MK_EDFNAME := $(MK_DEFNAME)
371 MK_EDFNAME := $(TARGET_PATH)/$(MK_DEFBASE).edf
375 ifeq ($(MK_MODE),user)
376 MK_DEFBASE := 0x400000
377 ifneq ($(TARGET_SDKLIBS),)
378 MK_LIBS := $(addprefix $(SDK_PATH_LIB)/, $(TARGET_SDKLIBS))
380 MK_LIBS := $(addprefix $(SDK_PATH_LIB)/, $(MK_SDKLIBS))
385 ifeq ($(MK_MODE),kernel)
386 MK_DEFBASE := 0x10000
387 MK_LIBS := $(addprefix $(DDK_PATH_LIB)/, $(MK_DDKLIBS) $(TARGET_DDKLIBS))
391 ifeq ($(TARGET_BASE),)
392 TARGET_BASE := $(MK_DEFBASE)
396 ifeq ($(TARGET_ENTRY),)
397 TARGET_ENTRY := $(MK_DEFENTRY)
402 # Include details of the OS configuration
404 include $(PATH_TO_TOP)/config
407 TARGET_CFLAGS += $(MK_CFLAGS)
408 TARGET_CFLAGS += -pipe -march=$(ARCH)
415 TARGET_CPPFLAGS += $(MK_CPPFLAGS)
416 TARGET_CPPFLAGS += -pipe -march=$(ARCH)
418 TARGET_RCFLAGS += $(MK_RCFLAGS)
420 TARGET_ASFLAGS += $(MK_ASFLAGS)
421 TARGET_ASFLAGS += -pipe -march=$(ARCH)
423 TARGET_NFLAGS += $(MK_NFLAGS)
426 MK_GCCLIBS := $(addprefix -l, $(TARGET_GCCLIBS))
428 MK_FULLNAME := $(MK_BASENAME)$(MK_EXT)
429 MK_IMPLIB_FULLNAME := $(MK_BASENAME)$(MK_IMPLIB_EXT)
431 MK_NOSTRIPNAME := $(MK_BASENAME).nostrip$(MK_EXT)
433 # We don't want to link header files
434 MK_OBJECTS := $(filter-out %.h,$(TARGET_OBJECTS))
435 MK_STRIPPED_OBJECT := $(MK_BASENAME).stripped.o
437 ifeq ($(MK_IMPLIBONLY),yes)
439 TARGET_CLEAN += $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME)
441 all: $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME)
443 $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME): $(TARGET_OBJECTS)
445 --dllname $(MK_FULLNAME) \
446 --def $(MK_DEFNAME) \
447 --output-lib $(MK_IMPLIBPATH)/$(MK_BASENAME).a \
453 all: $(MK_FULLNAME) $(MK_NOSTRIPNAME)
456 ifeq ($(MK_IMPLIB),yes)
457 MK_EXTRACMD := --def $(MK_EDFNAME)
463 ifeq ($(MK_MODE),user)
465 ifeq ($(MK_EXETYPE),dll)
466 TARGET_LFLAGS += -mdll -Wl,--image-base,$(TARGET_BASE)
467 MK_EXTRACMD2 := -Wl,temp.exp
472 $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS)
473 ifeq ($(MK_EXETYPE),dll)
474 $(CC) -Wl,--base-file,base.tmp \
475 -Wl,--entry,$(TARGET_ENTRY) \
478 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
480 $(DLLTOOL) --dllname $(MK_FULLNAME) \
481 --base-file base.tmp \
482 --output-exp temp.exp $(MK_EXTRACMD)
485 $(CC) $(TARGET_LFLAGS) \
486 -Wl,--entry,$(TARGET_ENTRY) $(MK_EXTRACMD2) \
487 -o $(MK_NOSTRIPNAME) \
488 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
490 - $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym
492 $(MK_FULLNAME): $(MK_NOSTRIPNAME)
493 $(CP) $(MK_NOSTRIPNAME) $(MK_FULLNAME)
494 # $(STRIP) --strip-debug $(MK_FULLNAME)
498 # Kernel mode targets
499 ifeq ($(MK_MODE),kernel)
501 ifeq ($(MK_IMPLIB),yes)
502 MK_EXTRACMD := --def $(MK_EDFNAME)
507 $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS)
508 $(CC) -Wl,--base-file,base.tmp \
509 -Wl,--entry,$(TARGET_ENTRY) \
511 -nostartfiles -nostdlib \
513 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
515 $(DLLTOOL) --dllname $(MK_FULLNAME) \
516 --base-file base.tmp \
517 --output-exp temp.exp $(MK_EXTRACMD)
519 $(CC) $(TARGET_LFLAGS) \
520 -Wl,--subsystem,native \
521 -Wl,--image-base,$(TARGET_BASE) \
522 -Wl,--file-alignment,0x1000 \
523 -Wl,--section-alignment,0x1000 \
524 -Wl,--entry,$(TARGET_ENTRY) \
526 -mdll -nostartfiles -nostdlib \
527 -o $(MK_NOSTRIPNAME) \
528 $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
530 $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym
532 $(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS) $(MK_NOSTRIPNAME)
533 $(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS)
534 $(STRIP) --strip-debug $(MK_STRIPPED_OBJECT)
535 $(CC) -Wl,--base-file,base.tmp \
536 -Wl,--entry,$(TARGET_ENTRY) \
538 -nostartfiles -nostdlib \
540 $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
542 $(DLLTOOL) --dllname $(MK_FULLNAME) \
543 --base-file base.tmp \
544 --output-exp temp.exp $(MK_EXTRACMD)
546 $(CC) $(TARGET_LFLAGS) \
547 -Wl,--subsystem,native \
548 -Wl,--image-base,$(TARGET_BASE) \
549 -Wl,--file-alignment,0x1000 \
550 -Wl,--section-alignment,0x1000 \
551 -Wl,--entry,$(TARGET_ENTRY) \
553 -mdll -nostartfiles -nostdlib \
555 $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
560 # Static library target
561 ifeq ($(MK_MODE),static)
563 $(MK_FULLNAME): $(TARGET_OBJECTS)
564 $(AR) -r $(MK_FULLNAME) $(TARGET_OBJECTS)
568 endif # MK_IMPLIBONLY
571 $(MK_FULLRES): $(PATH_TO_TOP)/include/reactos/buildno.h $(TARGET_PATH)/$(MK_RES_BASE).rc
573 ifeq ($(MK_DEPENDS),yes)
579 ifeq ($(MK_IMPLIB),yes)
580 $(MK_IMPLIBPATH)/$(MK_BASENAME).a: $(MK_DEFNAME)
581 $(DLLTOOL) --dllname $(MK_FULLNAME) \
582 --def $(MK_DEFNAME) \
583 --output-lib $(MK_IMPLIBPATH)/$(MK_BASENAME).a \
586 implib: $(MK_IMPLIBPATH)/$(MK_BASENAME).a
591 # Be carefull not to clean non-object files
592 MK_CLEANFILES := $(filter %.o,$(MK_OBJECTS))
595 - $(RM) *.o depend.d *.pch $(MK_BASENAME).sym $(MK_BASENAME).a $(TARGET_PATH)/$(MK_RES_BASE).coff \
596 $(MK_FULLNAME) $(MK_NOSTRIPNAME) $(MK_CLEANFILES) \
597 junk.tmp base.tmp temp.exp \
600 ifneq ($(TARGET_HEADERS),)
601 $(TARGET_OBJECTS): $(TARGET_HEADERS)
604 # install and dist rules
606 ifeq ($(MK_IMPLIBONLY),yes)
608 # Don't install import libraries
617 install: $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME)
619 $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME): $(MK_FULLNAME) $(MK_BASENAME).sym
620 $(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME)
621 $(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_BASENAME).sym
624 dist: $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME)
626 $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME): $(MK_FULLNAME)
627 $(CP) $(MK_FULLNAME) $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME)
628 $(CP) $(MK_BASENAME).sym $(DIST_DIR)/symbols/$(MK_BASENAME).sym
630 endif # MK_IMPLIBONLY
633 .phony: all depends implib clean install dist depends
636 # Precompiled header support
637 # When using PCHs, use dependency tracking to keep the .pch files up-to-date.
640 ifeq ($(ROS_USE_PCH),yes)
641 ifneq ($(TARGET_PCH),)
642 MK_PCHNAME = $(TARGET_PCH).pch
644 # GCC generates wrong dependencies for header files.
645 MK_PCHFAKE = $(TARGET_PCH:.h=.o)
647 - $(RTOUCH) $(MK_PCHFAKE)
649 $(MK_PCHNAME): depend.d
650 - $(RTOUCH) $(MK_PCHNAME)
651 - $(CC) $(TARGET_CFLAGS) $(TARGET_PCH)
653 depend.d: $(MK_PCHFAKE)
655 - $(CC) $(TARGET_CFLAGS) $(TARGET_PCH) -M -MF depend.d
663 %.o: %.c $(MK_PCHNAME)
664 $(CC) $(TARGET_CFLAGS) -c $< -o $@
666 $(CC) $(TARGET_CPPFLAGS) -c $< -o $@
668 $(CC) $(TARGET_CPPFLAGS) -c $< -o $@
670 $(AS) $(TARGET_ASFLAGS) -c $< -o $@
672 $(AS) $(TARGET_ASFLAGS) -c $< -o $@
674 $(NASM_CMD) $(NFLAGS) $(TARGET_NFLAGS) $< -o $@
676 $(RC) $(TARGET_RCFLAGS) $(RCINC) $< -o $@
680 CFLAGS := $(TARGET_CFLAGS)