1# Capstone Disassembly Engine 2# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 3 4include config.mk 5include pkgconfig.mk # package version 6include functions.mk 7 8# Verbose output? 9V ?= 0 10 11ifeq ($(PKG_EXTRA),) 12PKG_VERSION = $(PKG_MAJOR).$(PKG_MINOR) 13else 14PKG_VERSION = $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA) 15endif 16 17ifeq ($(CROSS),) 18CC ?= cc 19AR ?= ar 20RANLIB ?= ranlib 21STRIP ?= strip 22else 23CC = $(CROSS)gcc 24AR = $(CROSS)ar 25RANLIB = $(CROSS)ranlib 26STRIP = $(CROSS)strip 27endif 28 29ifneq (,$(findstring yes,$(CAPSTONE_DIET))) 30CFLAGS ?= -Os 31CFLAGS += -DCAPSTONE_DIET 32else 33CFLAGS ?= -O3 34endif 35 36ifneq (,$(findstring yes,$(CAPSTONE_X86_ATT_DISABLE))) 37CFLAGS += -DCAPSTONE_X86_ATT_DISABLE 38endif 39 40CFLAGS += -fPIC -Wall -Iinclude 41 42ifeq ($(CAPSTONE_USE_SYS_DYN_MEM),yes) 43CFLAGS += -DCAPSTONE_USE_SYS_DYN_MEM 44endif 45 46ifeq ($(CAPSTONE_HAS_OSXKERNEL), yes) 47CFLAGS += -DCAPSTONE_HAS_OSXKERNEL 48SDKROOT ?= $(shell xcodebuild -version -sdk macosx Path) 49CFLAGS += -mmacosx-version-min=10.5 \ 50 -isysroot$(SDKROOT) \ 51 -I$(SDKROOT)/System/Library/Frameworks/Kernel.framework/Headers \ 52 -mkernel \ 53 -fno-builtin 54endif 55 56CFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch)) 57LDFLAGS += $(foreach arch,$(LIBARCHS),-arch $(arch)) 58 59PREFIX ?= /usr 60DESTDIR ?= 61ifndef BUILDDIR 62BLDIR = . 63OBJDIR = . 64else 65BLDIR = $(abspath $(BUILDDIR)) 66OBJDIR = $(BLDIR)/obj 67endif 68INCDIR = $(DESTDIR)$(PREFIX)/include 69 70UNAME_S := $(shell uname -s) 71 72LIBDIRARCH ?= lib 73# Uncomment the below line to installs x86_64 libs to lib64/ directory. 74# Or better, pass 'LIBDIRARCH=lib64' to 'make install/uninstall' via 'make.sh'. 75#LIBDIRARCH ?= lib64 76LIBDIR = $(DESTDIR)$(PREFIX)/$(LIBDIRARCH) 77BINDIR = $(DESTDIR)$(PREFIX)/bin 78 79LIBDATADIR = $(LIBDIR) 80 81# Don't redefine $LIBDATADIR when global environment variable 82# USE_GENERIC_LIBDATADIR is set. This is used by the pkgsrc framework. 83 84ifndef USE_GENERIC_LIBDATADIR 85ifeq ($(UNAME_S), FreeBSD) 86LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata 87endif 88ifeq ($(UNAME_S), DragonFly) 89LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata 90endif 91endif 92 93INSTALL_BIN ?= install 94INSTALL_DATA ?= $(INSTALL_BIN) -m0644 95INSTALL_LIB ?= $(INSTALL_BIN) -m0755 96 97LIBNAME = capstone 98 99 100DEP_ARM = 101DEP_ARM += arch/ARM/ARMGenAsmWriter.inc 102DEP_ARM += arch/ARM/ARMGenDisassemblerTables.inc 103DEP_ARM += arch/ARM/ARMGenInstrInfo.inc 104DEP_ARM += arch/ARM/ARMGenRegisterInfo.inc 105DEP_ARM += arch/ARM/ARMGenSubtargetInfo.inc 106 107LIBOBJ_ARM = 108ifneq (,$(findstring arm,$(CAPSTONE_ARCHS))) 109 CFLAGS += -DCAPSTONE_HAS_ARM 110 LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMDisassembler.o 111 LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMInstPrinter.o 112 LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMMapping.o 113 LIBOBJ_ARM += $(OBJDIR)/arch/ARM/ARMModule.o 114endif 115 116DEP_ARM64 = 117DEP_ARM64 += arch/AArch64/AArch64GenAsmWriter.inc 118DEP_ARM64 += arch/AArch64/AArch64GenInstrInfo.inc 119DEP_ARM64 += arch/AArch64/AArch64GenSubtargetInfo.inc 120DEP_ARM64 += arch/AArch64/AArch64GenDisassemblerTables.inc 121DEP_ARM64 += arch/AArch64/AArch64GenRegisterInfo.inc 122 123LIBOBJ_ARM64 = 124ifneq (,$(findstring aarch64,$(CAPSTONE_ARCHS))) 125 CFLAGS += -DCAPSTONE_HAS_ARM64 126 LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64BaseInfo.o 127 LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64Disassembler.o 128 LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64InstPrinter.o 129 LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64Mapping.o 130 LIBOBJ_ARM64 += $(OBJDIR)/arch/AArch64/AArch64Module.o 131endif 132 133 134DEP_MIPS = 135DEP_MIPS += arch/Mips/MipsGenAsmWriter.inc 136DEP_MIPS += arch/Mips/MipsGenDisassemblerTables.inc 137DEP_MIPS += arch/Mips/MipsGenInstrInfo.inc 138DEP_MIPS += arch/Mips/MipsGenRegisterInfo.inc 139DEP_MIPS += arch/Mips/MipsGenSubtargetInfo.inc 140 141LIBOBJ_MIPS = 142ifneq (,$(findstring mips,$(CAPSTONE_ARCHS))) 143 CFLAGS += -DCAPSTONE_HAS_MIPS 144 LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsDisassembler.o 145 LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsInstPrinter.o 146 LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsMapping.o 147 LIBOBJ_MIPS += $(OBJDIR)/arch/Mips/MipsModule.o 148endif 149 150 151DEP_PPC = 152DEP_PPC += arch/PowerPC/PPCGenAsmWriter.inc 153DEP_PPC += arch/PowerPC/PPCGenInstrInfo.inc 154DEP_PPC += arch/PowerPC/PPCGenSubtargetInfo.inc 155DEP_PPC += arch/PowerPC/PPCGenDisassemblerTables.inc 156DEP_PPC += arch/PowerPC/PPCGenRegisterInfo.inc 157 158LIBOBJ_PPC = 159ifneq (,$(findstring powerpc,$(CAPSTONE_ARCHS))) 160 CFLAGS += -DCAPSTONE_HAS_POWERPC 161 LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCDisassembler.o 162 LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCInstPrinter.o 163 LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCMapping.o 164 LIBOBJ_PPC += $(OBJDIR)/arch/PowerPC/PPCModule.o 165endif 166 167 168DEP_SPARC = 169DEP_SPARC += arch/Sparc/SparcGenAsmWriter.inc 170DEP_SPARC += arch/Sparc/SparcGenInstrInfo.inc 171DEP_SPARC += arch/Sparc/SparcGenSubtargetInfo.inc 172DEP_SPARC += arch/Sparc/SparcGenDisassemblerTables.inc 173DEP_SPARC += arch/Sparc/SparcGenRegisterInfo.inc 174 175LIBOBJ_SPARC = 176ifneq (,$(findstring sparc,$(CAPSTONE_ARCHS))) 177 CFLAGS += -DCAPSTONE_HAS_SPARC 178 LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcDisassembler.o 179 LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcInstPrinter.o 180 LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcMapping.o 181 LIBOBJ_SPARC += $(OBJDIR)/arch/Sparc/SparcModule.o 182endif 183 184 185DEP_SYSZ = 186DEP_SYSZ += arch/SystemZ/SystemZGenAsmWriter.inc 187DEP_SYSZ += arch/SystemZ/SystemZGenInstrInfo.inc 188DEP_SYSZ += arch/SystemZ/SystemZGenSubtargetInfo.inc 189DEP_SYSZ += arch/SystemZ/SystemZGenDisassemblerTables.inc 190DEP_SYSZ += arch/SystemZ/SystemZGenRegisterInfo.inc 191 192LIBOBJ_SYSZ = 193ifneq (,$(findstring systemz,$(CAPSTONE_ARCHS))) 194 CFLAGS += -DCAPSTONE_HAS_SYSZ 195 LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZDisassembler.o 196 LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZInstPrinter.o 197 LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZMapping.o 198 LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZModule.o 199 LIBOBJ_SYSZ += $(OBJDIR)/arch/SystemZ/SystemZMCTargetDesc.o 200endif 201 202 203# by default, we compile full X86 instruction sets 204X86_REDUCE = 205ifneq (,$(findstring yes,$(CAPSTONE_X86_REDUCE))) 206X86_REDUCE = _reduce 207CFLAGS += -DCAPSTONE_X86_REDUCE -Os 208endif 209 210DEP_X86 = 211DEP_X86 += arch/X86/X86GenAsmWriter$(X86_REDUCE).inc 212DEP_X86 += arch/X86/X86GenAsmWriter1$(X86_REDUCE).inc 213DEP_X86 += arch/X86/X86GenDisassemblerTables$(X86_REDUCE).inc 214DEP_X86 += arch/X86/X86GenInstrInfo$(X86_REDUCE).inc 215DEP_X86 += arch/X86/X86GenRegisterInfo.inc 216 217LIBOBJ_X86 = 218ifneq (,$(findstring x86,$(CAPSTONE_ARCHS))) 219 CFLAGS += -DCAPSTONE_HAS_X86 220 LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86DisassemblerDecoder.o 221 LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Disassembler.o 222 LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86IntelInstPrinter.o 223# assembly syntax is irrelevant in Diet mode, when this info is suppressed 224ifeq (,$(findstring yes,$(CAPSTONE_DIET))) 225ifeq (,$(findstring yes,$(CAPSTONE_X86_ATT_DISABLE))) 226 LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86ATTInstPrinter.o 227endif 228endif 229 LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Mapping.o 230 LIBOBJ_X86 += $(OBJDIR)/arch/X86/X86Module.o 231endif 232 233 234DEP_XCORE = 235DEP_XCORE += arch/XCore/XCoreGenAsmWriter.inc 236DEP_XCORE += arch/XCore/XCoreGenInstrInfo.inc 237DEP_XCORE += arch/XCore/XCoreGenDisassemblerTables.inc 238DEP_XCORE += arch/XCore/XCoreGenRegisterInfo.inc 239 240LIBOBJ_XCORE = 241ifneq (,$(findstring xcore,$(CAPSTONE_ARCHS))) 242 CFLAGS += -DCAPSTONE_HAS_XCORE 243 LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreDisassembler.o 244 LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreInstPrinter.o 245 LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreMapping.o 246 LIBOBJ_XCORE += $(OBJDIR)/arch/XCore/XCoreModule.o 247endif 248 249 250LIBOBJ = 251LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o 252LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_X86) $(LIBOBJ_XCORE) 253LIBOBJ += $(OBJDIR)/MCInst.o 254 255 256PKGCFGDIR ?= $(LIBDATADIR)/pkgconfig 257API_MAJOR=$(shell echo `grep -e CS_API_MAJOR include/capstone.h | grep -v = | awk '{print $$3}'` | awk '{print $$1}') 258VERSION_EXT = 259 260IS_APPLE := $(shell $(CC) -dM -E - < /dev/null | grep -cm 1 -e __apple_build_version__ -e __APPLE_CC__) 261ifeq ($(IS_APPLE),1) 262EXT = dylib 263VERSION_EXT = $(API_MAJOR).$(EXT) 264$(LIBNAME)_LDFLAGS += -dynamiclib -install_name lib$(LIBNAME).$(VERSION_EXT) -current_version $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA) -compatibility_version $(PKG_MAJOR).$(PKG_MINOR) 265AR_EXT = a 266# Homebrew wants to make sure its formula does not disable FORTIFY_SOURCE 267# However, this is not really necessary because 'CAPSTONE_USE_SYS_DYN_MEM=yes' by default 268ifneq ($(HOMEBREW_CAPSTONE),1) 269ifneq ($(CAPSTONE_USE_SYS_DYN_MEM),yes) 270# remove string check because OSX kernel complains about missing symbols 271CFLAGS += -D_FORTIFY_SOURCE=0 272endif 273endif 274else 275$(LIBNAME)_LDFLAGS += -shared 276# Cygwin? 277IS_CYGWIN := $(shell $(CC) -dumpmachine | grep -i cygwin | wc -l) 278ifeq ($(IS_CYGWIN),1) 279EXT = dll 280AR_EXT = lib 281# Cygwin doesn't like -fPIC 282CFLAGS := $(CFLAGS:-fPIC=) 283# On Windows we need the shared library to be executable 284else 285# mingw? 286IS_MINGW := $(shell $(CC) --version | grep -i mingw | wc -l) 287ifeq ($(IS_MINGW),1) 288EXT = dll 289AR_EXT = lib 290# mingw doesn't like -fPIC either 291CFLAGS := $(CFLAGS:-fPIC=) 292# On Windows we need the shared library to be executable 293else 294# Linux, *BSD 295EXT = so 296VERSION_EXT = $(EXT).$(API_MAJOR) 297AR_EXT = a 298$(LIBNAME)_LDFLAGS += -Wl,-soname,lib$(LIBNAME).$(VERSION_EXT) 299endif 300endif 301endif 302 303ifeq ($(CAPSTONE_SHARED),yes) 304ifeq ($(IS_MINGW),1) 305LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT) 306else ifeq ($(IS_CYGWIN),1) 307LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT) 308else # *nix 309LIBRARY = $(BLDIR)/lib$(LIBNAME).$(EXT) 310CFLAGS += -fvisibility=hidden 311endif 312endif 313 314ifeq ($(CAPSTONE_STATIC),yes) 315ifeq ($(IS_MINGW),1) 316ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT) 317else ifeq ($(IS_CYGWIN),1) 318ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT) 319else 320ARCHIVE = $(BLDIR)/lib$(LIBNAME).$(AR_EXT) 321endif 322endif 323 324PKGCFGF = $(BLDIR)/$(LIBNAME).pc 325 326.PHONY: all clean install uninstall dist 327 328all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF) 329ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY))) 330 @V=$(V) CC=$(CC) $(MAKE) -C cstool 331ifndef BUILDDIR 332 cd tests && $(MAKE) 333else 334 cd tests && $(MAKE) BUILDDIR=$(BLDIR) 335endif 336 $(call install-library,$(BLDIR)/tests/) 337endif 338 339ifeq ($(CAPSTONE_SHARED),yes) 340$(LIBRARY): $(LIBOBJ) 341ifeq ($(V),0) 342 $(call log,LINK,$(@:$(BLDIR)/%=%)) 343 @$(create-library) 344else 345 $(create-library) 346endif 347endif 348 349$(LIBOBJ): *.h include/*.h config.mk 350 351$(LIBOBJ_ARM): $(DEP_ARM) 352$(LIBOBJ_ARM64): $(DEP_ARM64) 353$(LIBOBJ_MIPS): $(DEP_MIPS) 354$(LIBOBJ_PPC): $(DEP_PPC) 355$(LIBOBJ_SPARC): $(DEP_SPARC) 356$(LIBOBJ_SYSZ): $(DEP_SYSZ) 357$(LIBOBJ_X86): $(DEP_X86) 358$(LIBOBJ_XCORE): $(DEP_XCORE) 359 360ifeq ($(CAPSTONE_STATIC),yes) 361$(ARCHIVE): $(LIBOBJ) 362 @rm -f $(ARCHIVE) 363ifeq ($(V),0) 364 $(call log,AR,$(@:$(BLDIR)/%=%)) 365 @$(create-archive) 366else 367 $(create-archive) 368endif 369endif 370 371$(PKGCFGF): 372ifeq ($(V),0) 373 $(call log,GEN,$(@:$(BLDIR)/%=%)) 374 @$(generate-pkgcfg) 375else 376 $(generate-pkgcfg) 377endif 378 379install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY) 380 mkdir -p $(LIBDIR) 381 $(call install-library,$(LIBDIR)) 382ifeq ($(CAPSTONE_STATIC),yes) 383 $(INSTALL_DATA) $(ARCHIVE) $(LIBDIR) 384endif 385 mkdir -p $(INCDIR)/$(LIBNAME) 386 $(INSTALL_DATA) include/*.h $(INCDIR)/$(LIBNAME) 387 mkdir -p $(PKGCFGDIR) 388 $(INSTALL_DATA) $(PKGCFGF) $(PKGCFGDIR)/ 389 mkdir -p $(BINDIR) 390 $(INSTALL_LIB) cstool/cstool $(BINDIR) 391 392uninstall: 393 rm -rf $(INCDIR)/$(LIBNAME) 394 rm -f $(LIBDIR)/lib$(LIBNAME).* 395 rm -f $(PKGCFGDIR)/$(LIBNAME).pc 396 rm -f $(BINDIR)/cstool 397 398clean: 399 rm -f $(LIBOBJ) 400 rm -f $(BLDIR)/lib$(LIBNAME).* $(BLDIR)/$(LIBNAME).pc 401 rm -f $(PKGCFGF) 402 $(MAKE) -C cstool clean 403 404ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY))) 405 cd tests && $(MAKE) clean 406 rm -f $(BLDIR)/tests/lib$(LIBNAME).$(EXT) 407endif 408 409ifdef BUILDDIR 410 rm -rf $(BUILDDIR) 411endif 412 413ifeq (,$(findstring yes,$(CAPSTONE_BUILD_CORE_ONLY))) 414 cd bindings/python && $(MAKE) clean 415 cd bindings/java && $(MAKE) clean 416 cd bindings/ocaml && $(MAKE) clean 417endif 418 419 420TAG ?= HEAD 421ifeq ($(TAG), HEAD) 422DIST_VERSION = latest 423else 424DIST_VERSION = $(TAG) 425endif 426 427dist: 428 git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz 429 git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip 430 431 432TESTS = test_basic test_detail test_arm test_arm64 test_mips test_ppc test_sparc 433TESTS += test_systemz test_x86 test_xcore test_iter 434TESTS += test_basic.static test_detail.static test_arm.static test_arm64.static 435TESTS += test_mips.static test_ppc.static test_sparc.static 436TESTS += test_systemz.static test_x86.static test_xcore.static 437TESTS += test_skipdata test_skipdata.static test_iter.static 438check: 439 @for t in $(TESTS); do \ 440 echo Check $$t ... ; \ 441 LD_LIBRARY_PATH=./tests ./tests/$$t > /dev/null && echo OK || echo FAILED; \ 442 done 443 444$(OBJDIR)/%.o: %.c 445 @mkdir -p $(@D) 446ifeq ($(V),0) 447 $(call log,CC,$(@:$(OBJDIR)/%=%)) 448 @$(compile) 449else 450 $(compile) 451endif 452 453 454ifeq ($(CAPSTONE_SHARED),yes) 455define install-library 456 $(INSTALL_LIB) $(LIBRARY) $1 457 $(if $(VERSION_EXT), 458 cd $1 && \ 459 mv lib$(LIBNAME).$(EXT) lib$(LIBNAME).$(VERSION_EXT) && \ 460 ln -s lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT)) 461endef 462else 463define install-library 464endef 465endif 466 467 468define create-archive 469 $(AR) q $(ARCHIVE) $(LIBOBJ) 470 $(RANLIB) $(ARCHIVE) 471endef 472 473 474define create-library 475 $(CC) $(LDFLAGS) $($(LIBNAME)_LDFLAGS) $(LIBOBJ) -o $(LIBRARY) 476endef 477 478 479define generate-pkgcfg 480 echo 'Name: capstone' > $(PKGCFGF) 481 echo 'Description: Capstone disassembly engine' >> $(PKGCFGF) 482 echo 'Version: $(PKG_VERSION)' >> $(PKGCFGF) 483 echo 'libdir=$(LIBDIR)' >> $(PKGCFGF) 484 echo 'includedir=$(INCDIR)/capstone' >> $(PKGCFGF) 485 echo 'archive=$${libdir}/libcapstone.a' >> $(PKGCFGF) 486 echo 'Libs: -L$${libdir} -lcapstone' >> $(PKGCFGF) 487 echo 'Cflags: -I$${includedir}' >> $(PKGCFGF) 488endef 489