1#########################################################################
2#
3#  This file is part of the Yices SMT Solver.
4#  Copyright (C) 2017 SRI International.
5#
6#  Yices is free software: you can redistribute it and/or modify
7#  it under the terms of the GNU General Public License as published by
8#  the Free Software Foundation, either version 3 of the License, or
9#  (at your option) any later version.
10#
11#  Yices is distributed in the hope that it will be useful,
12#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#  GNU General Public License for more details.
15#
16#  You should have received a copy of the GNU General Public License
17#  along with Yices.  If not, see <http://www.gnu.org/licenses/>.
18#
19#########################################################################
20
21#
22# Top-level Makefile
23#
24# Determine the architecture and top directory.
25# Import architecture files from top-dir/configs/make.include.$(ARCH)
26#
27
28SHELL=/bin/sh
29
30YICES_TOP_DIR=$(shell pwd)
31
32#
33# Version numbers: <version>.<minor>.<patch-level>
34# - this determines the name of the distribution tarfile
35# - the number is also used in the shared library
36#   for linux:  the soname is libyices.so.<major>.<minor>
37#   for darwin: the compatibility version is <major>.<minor>.0
38#               the version is set to <major>.<minor>.<patch-level>
39#
40# Conventions we should follow:
41# <major> increases for major new releases.
42# <minor> increases when we make changes that loose
43#         backward compatibility.
44# <patch-level> increases for bug fixes or other improvements
45#         that maintain backward compatibility.
46#
47# Example: if P is linked against libyices.so version 2.0.0
48# - P should still work (without recompliling) with libyices 2.0.1
49# - P should not work anymore with libyices 2.1.0 or 3.0.0
50#
51# N.B There are also an occurrences in:
52# src/include/yices.h
53# doc/manual/manual.tex
54# doc/sphinx/source/conf.py
55# doc/yices*.1 man files
56#
57MAJOR = 2
58MINOR = 6
59PATCH_LEVEL = 2
60
61YICES_VERSION = $(MAJOR).$(MINOR).$(PATCH_LEVEL)
62
63
64#
65# Find platform (also default configuration)
66#
67ARCH=$(shell ./config.sub `./config.guess`)
68POSIXOS=$(shell ./autoconf/os)
69
70ifeq (,$(POSIXOS))
71  $(error "Problem running ./autoconf/os")
72else
73ifeq (unknown,$(POSIXOS))
74  $(error "Unknown OS")
75endif
76endif
77
78
79#
80# OPTION: select an alternative configuration file
81#
82# 1) On Mac OS X Leopard/intel (darwin9.X.Y), the default configuration is
83#    in file  make.include.i386-apple-darwin9.X.Y
84#    This builds Yices as a 32bit executable.
85#
86#    It's possible to use an alternative configuration file
87#       make.include.x86_64-apple-darwin9.Y.Z on the same system.
88#    This is intended to build Yices as 64bit code.
89#
90#    To select the alternative configuration use 'make OPTION=64bits ..'
91#
92# 1a) Since Mac OS X Snow Leopard (darwin10.X.Y) and newer, the default
93#     is reversed. The default configuration is in file
94#        make.include.x86_64-apple-darwin10.X.Y
95#     This builds Yices for 64bit by default.
96#
97#     To build for 32bit on the same system, use the alternative
98#     configuration file  make.include.i386-apple-darwin10.X.Y
99#
100#     To select the alternative configuration use 'make OPTION=32bits ...'
101#
102# 2) On Linux/x86_64, we compile in 64 bit mode by default,
103#    using configuration file make.include.x86_64-unknown-linux-gnu
104#
105#    It may be possible to build in 32 bit mode on the same machine,
106#    provided the compiler understand option -m32 and the necessary
107#    32bit libraries are present. The corresponding Yices configuration
108#    is make.include.i686-unknown-linux-gnu
109#
110#    To select this 32bit configuration, use 'make OPTION=32bits ...'
111#
112# 3) On cygwin, the default configuration is make.include.i686-pc-cygwin.
113#    Two alternatives are supported:
114#         make.include.i686-pc-mingw32    (mingw32/Windows 32bit native)
115#    and  make.include.x86_64-pc-mingw32  (Windows 64bit native)
116#
117#    To select the Windows 32bit configuration, use
118#          'make OPTION=no-cygwin ...'
119#       or 'make OPTION=mingw32 ...'
120#
121#    To select the Windows 64bit configuration, use
122#         'make OPTION=mingw64'
123#
124#    Issue: 2013/12/11: this Makefile is not robust for
125#    cross-compilation on Cygwin (to produce Windows 64 code).
126#    The simplest way to configure for this cross-compilation is
127#       ./configure --host=x86_64-w64-mingw32 ....
128#
129#    This generates ./configs/makefile.include.x86_64-w64-mingw32.
130#    But OPTION=mingw64 gives ./configs/makefile.include.x86_64-pc-mingw32
131#
132#
133# 4) On solaris, the default is make.include.sparc-sun-solaris2.x
134#    (should be 32bits).
135#
136#    The alternative is make.include.sparc64-sun-solaris2.x
137#    (should be for 64bits build). To select it, give OPTION=64bits.
138#
139# Check README for details on generating these alternative configurations.
140#
141ifneq ($(OPTION),)
142  ifeq ($(POSIXOS),linux)
143    ifeq ($(OPTION),32bits)
144      newarch=$(subst x86_64,i686,$(ARCH))
145    endif
146  else
147  ifeq ($(POSIXOS),darwin)
148    ifeq ($(OPTION),64bits)
149      newarch=$(subst i386,x86_64,$(ARCH))
150    else
151    ifeq ($(OPTION),32bits)
152      newarch=$(subst x86_64,i386,$(ARCH))
153    endif
154    endif
155  else
156  ifeq ($(POSIXOS),cygwin)
157    ifeq ($(OPTION),32bits)
158      newarch=$(subst x86_64,i686,$(ARCH))
159    else
160    ifeq ($(OPTION),no-cygwin)
161      newarch=$(subst cygwin,mingw32,$(subst x86_64,i686,$(ARCH)))
162      alternate=$(subst pc,w64,$(subst unknown,w64,$(newarch)))
163      POSIXOS=mingw
164    else
165    ifeq ($(OPTION),mingw32)
166      newarch=$(subst cygwin,mingw32,$(subst x86_64,i686,$(ARCH)))
167      alternate=$(subst pc,w64,$(subst unknown,w64,$(newarch)))
168      POSIXOS=mingw
169    else
170    ifeq ($(OPTION),mingw64)
171      newarch=$(subst cygwin,mingw32,$(subst i686,x86_64,$(ARCH)))
172      alternate=$(subst pc,w64,$(subst unknown,w64,$(newarch)))
173      POSIXOS=mingw
174    endif
175    endif
176    endif
177    endif
178  else
179  ifeq ($(POSIXOS),sunos)
180    ifeq ($(OPTION),64bits)
181      newarch=$(subst sparc,sparc64,$(ARCH))
182    endif
183  endif
184  ifeq ($(POSIXOS),freebsd)
185    ifeq ($(OPTION),32bits)
186      newarch=$(subst x86_64,i386,$(ARCH))
187    endif
188  endif
189  endif
190  endif
191  endif
192
193  ifeq ($(newarch),)
194    $(error "option $(OPTION) not supported on platform $(ARCH)")
195  endif
196  ARCH := $(newarch)
197endif
198
199
200#
201# Check whether make.include exists
202#
203# Note: we don't want to run ./configure from here.
204# The user may need to give options to the ./configure
205# script.
206#
207make_include = configs/make.include.$(ARCH)
208known_make_includes = $(filter-out %.in, $(wildcard configs/make.include.*))
209
210YICES_MAKE_INCLUDE := $(findstring $(make_include), $(known_make_includes))
211
212ifeq (,$(YICES_MAKE_INCLUDE))
213  #
214  # Try alternate name (--host= ...)
215  #
216  ifneq (,$(alternate))
217     make_alternate = configs/make.include.$(alternate)
218     YICES_MAKE_INCLUDE := $(findstring $(make_alternate), $(known_make_includes))
219     ifeq (,$(YICES_MAKE_INCLUDE))
220        $(error Could not find $(make_include) nor $(make_alternate). Run ./configure)
221     else
222        $(info Could not find $(make_include). Using $(make_alternate) instead)
223     endif
224  else
225    $(error Could not find $(make_include). Run ./configure)
226  endif
227endif
228
229
230#
231# Check build mode
232#
233default_mode=release
234allowed_modes=release debug devel profile gcov valgrind purify quantify gperftools
235MODE ?= $(default_mode)
236
237YICES_MODE := $(filter $(allowed_modes), $(MODE))
238
239ifeq (,$(YICES_MODE))
240  $(error "Invalid build mode: $(MODE)")
241endif
242
243
244#
245# Default target: build binaries/libraries
246#
247default: dist
248
249#
250# Just print the configuration
251#
252show-config: checkgmake
253	@ echo "ARCH is $(ARCH)"
254	@ echo "POSIXOS is $(POSIXOS)"
255	@ echo "YICES_TOP_DIR is $(YICES_TOP_DIR)"
256	@ echo "YICES_MAKE_INCLUDE is $(YICES_MAKE_INCLUDE)"
257	@ echo "YICES_MODE is $(YICES_MODE)"
258	@ echo "YICES_VERSION is $(YICES_VERSION)"
259
260checkgmake:
261	@ ./gmaketest --make=$(MAKE) || \
262	  (echo "GNU-Make is required to compile Yices. Aborting."; exit1)
263
264
265#
266# Invoke submake that will do the real work
267# the quotes around the 'YICES_TOP_DIR= ...' help if the directory
268# name include spaces
269#
270# We must have doc as an explicit target since we have a ./doc directory.
271# Without it 'make doc' does nothing. To be safe, I've also added bin,
272# lib, obj, etc. so that the Makefile will work event if directories
273# or files with these names are present.
274#
275.DEFAULT doc all bin lib obj dist static-bin static-lib static-obj static-dist install test static-test: checkgmake
276	@ echo "Mode:     $(YICES_MODE)"
277	@ echo "Platform: $(ARCH)"
278	@ $(MAKE) -f Makefile.build \
279	'YICES_MODE=$(YICES_MODE)' \
280	'ARCH=$(ARCH)' \
281	'POSIXOS=$(POSIXOS)' \
282	'YICES_TOP_DIR=$(YICES_TOP_DIR)' \
283	'YICES_MAKE_INCLUDE=$(YICES_MAKE_INCLUDE)' \
284	'YICES_VERSION=$(YICES_VERSION)' \
285	'MAJOR=$(MAJOR)' \
286	'MINOR=$(MINOR)' \
287	'PATCH_LEVEL=$(PATCH_LEVEL)' \
288	$@
289
290
291.PHONY: checkgmake show-config doc all bin lib obj dist \
292        static-bin static-lib static-obj static-dist install \
293        test static-test default
294