forked from bcpierce00/unison
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile.OCaml
473 lines (393 loc) · 15.4 KB
/
Makefile.OCaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# Unison file synchronizer: src/Makefile.OCaml
# See ../LICENSE for terms.
####################################################################
# Makefile rules for compiling ocaml programs #
####################################################################
####################################################################
### Compilers
OCAMLC=$(TOOL_PREFIX)ocamlc
OCAMLOPT=$(TOOL_PREFIX)ocamlopt
####################################################################
### Try to automatically guess OS
ifeq (${OSCOMP},cross) # Cross-compilation under Linux
TOOL_PREFIX=x86_64-w64-mingw32-
endif
# Cygwin is for doing POSIX builds in Windows.
# MinGW is for doing native Windows builds in a minimal POSIX environment.
# MSVC is for native Windows builds without POSIX env (yet this Makefile
# requires a minimal POSIX environment anyway).
OCAML_OSTYPE:=$(shell $(OCAMLC) -config-var os_type)
ifeq (${OCAML_OSTYPE},Win32) # Native Windows build
OSARCH=Win32
else ifeq (${OCAML_OSTYPE},Cygwin) # POSIX build for Windows
OSARCH=Cygwin
else
OSARCH:=$(shell uname)
# Darwin is reported for macOS
# SunOS is reported for Solaris, OpenSolaris and derivatives (illumos)
endif
####################################################################
### Try to automatically guess UI style
ifneq ($(strip $(UISTYLE)),)
$(error UISTYLE is no longer used. See build instructions)
endif
OCAMLLIBDIR:=$(shell $(OCAMLC) -config-var standard_library)
# For Windows, an additional UI style modifier is available, `UI_WINOS`
# Legal values are
# UI_WINOS= # *default*; builds unison purely as a Windows console ('text') or GUI ('gtk3') application
# UI_WINOS=hybrid # (with UISTYLE=gtk3) builds unison as a hybrid application (GUI application attached to a text console)
# * ref: <https://github.com/bcpierce00/unison/issues/778>
#
LABLGTK3LIB=$(OCAMLLIBDIR)/lablgtk3
ifeq ($(wildcard $(LABLGTK3LIB)),$(LABLGTK3LIB))
HAS_LABLGTK3=true
else
LABLGTK3LIB=$(abspath $(OCAMLLIBDIR)/../lablgtk3)
ifeq ($(wildcard $(LABLGTK3LIB)),$(LABLGTK3LIB))
HAS_LABLGTK3=true
endif
endif
.PHONY: guimaybe
ifeq ($(HAS_LABLGTK3), true)
guimaybe: gui
else
guimaybe:
$(info GUI library lablgtk not found. GTK GUI will not be built.)
endif
.PHONY: macuimaybe
ifeq ($(OSARCH), Darwin)
macuimaybe: macui
else
macuimaybe:
$(info Not on macOS. macOS native GUI will not be built.)
endif
####################################################################
### Default parameters
.PHONY: buildinfodebug
buildinfodebug:
$(info $(building_for))
$(info NATIVE = $(NATIVE))
buildexecutable: buildinfodebug
# Generate backtrace information for exceptions
CAMLFLAGS+=-g
ifneq ($(strip $(CFLAGS)),)
CAMLCFLAGS+=-ccopt '$(CFLAGS)'
endif
ifneq ($(strip $(CPPFLAGS)),)
CAMLCFLAGS+=-ccopt '$(CPPFLAGS)'
endif
ifneq ($(strip $(LDFLAGS)),)
CAMLLDFLAGS+=-cclib '$(LDFLAGS)'
endif
ifneq ($(strip $(LDLIBS)),)
CLIBS+=-cclib '$(LDLIBS)'
endif
INCLFLAGS=-I lwt -I ubase -I system
DEP_INCLFLAGS=-I lwt -I ubase -I system
CAMLFLAGS+=$(INCLFLAGS)
CAMLFLAGS+=-I system/$(SYSTEM) -I lwt/$(SYSTEM)
# The messy situation requiring the use of OUTPUT_SEL was fixed in OCaml 4.13.
# All usages of OUTPUT_SEL should be removed when 4.13 becomes a requirement.
ifeq ($(OSARCH),Win32)
# Native Win32 build
EXEC_EXT=.exe
ifeq ($(shell $(OCAMLC) -config-var ext_obj),.obj)
OBJ_EXT=.obj
else
OBJ_EXT=.o
endif
ifeq ($(shell $(OCAMLC) -config-var ccomp_type),msvc)
OUTPUT_SEL=-Fo
CLIBS+=-cclib shell32.lib -cclib user32.lib -cclib "-link win32rc/unison.res"
buildexecutable: win32rc/unison.res
else
OUTPUT_SEL=-o
CLIBS+=-cclib "-link win32rc/unison.res.lib"
buildexecutable: win32rc/unison.res.lib
endif
# Make Windows GUI come up with no console window
ifneq ($(UI_WINOS), hybrid)
LDFLAGS_GUI+=-subsystem windows
# -subsystem is a flexlink arg;
# respective gcc args: -mwindows or -Wl,--subsystem,windows
# respective MSVC linker arg: /SUBSYSTEM:WINDOWS
endif
CWD=.
COBJS+=system/system_win_stubs$(OBJ_EXT) lwt/lwt_unix_stubs$(OBJ_EXT)
WINOBJS=system/system_win.cmo
SYSTEM=win
building_for = Building for Windows
else
# Unix build, or Cygwin POSIX (GNU C) build
OBJ_EXT=.o
OUTPUT_SEL="-o "
WINOBJS=
SYSTEM=generic
# This is not strictly necessary as Cygwin can do a generic Unix build
# (and is actually meant to).
ifeq ($(OSARCH),Cygwin)
CWD=.
EXEC_EXT=.exe
CLIBS+=-cclib win32rc/unison.res.lib
buildexecutable: win32rc/unison.res.lib
building_for = Building for Cygwin
else
CWD=$(shell pwd)
EXEC_EXT=
# openpty is in the libutil library
ifneq ($(OSARCH),SunOS)
ifneq ($(OSARCH),Darwin)
CLIBS+=-cclib -lutil
endif
endif
ifeq ($(OSARCH),SunOS)
# ACL functions
CLIBS+=-cclib -lsec
endif
building_for = Building for Unix
endif
endif
ubase/projectInfo.ml: Makefile.ProjectInfo
echo 'let myName = "'$(NAME)'";;' > $@
echo 'let myVersion = "'$(VERSION)'";;' >> $@
echo 'let myMajorVersion = "'$(MAJORVERSION)'";;' >> $@
clean::
$(RM) ubase/projectInfo.ml
####################################################################
### Compilation boilerplate
ifeq ($(NATIVE), true)
## Set up for native code compilation
CAMLC=$(OCAMLOPT)
CAMLOBJS=$(subst .cmo,.cmx, $(subst .cma,.cmxa, $(OCAMLOBJS)))
CAMLLIBS=$(subst .cma,.cmxa, $(OCAMLLIBS))
else
## Set up for bytecode compilation
CAMLC=$(OCAMLC)
# -output-complete-exe is available since OCaml 4.10
ifneq ($(strip $(shell $(OCAMLC) -output-complete-exe 2>&1)),)
CAMLLDFLAGS+=-custom
else
CAMLLDFLAGS+=-output-complete-exe # can safely strip the binary
endif
CAMLOBJS=$(OCAMLOBJS)
CAMLLIBS=$(OCAMLLIBS)
endif
WINDRES := $(or ${TOOL_PREFIX},$(filter i686-w64-mingw32- x86_64-w64-mingw32-,$(CC:gcc${EXEC_EXT}=)))windres
##$(info windres='${WINDRES}')
####################################################################
### Unison objects and libraries
# OCaml objects for the bytecode version
# File extensions will be substituted for the native code version
OCAMLOBJS += \
ubase/umarshal.cmo \
ubase/rx.cmo \
\
unicode_tables.cmo unicode.cmo bytearray.cmo \
system/system_generic.cmo $(WINOBJS) \
system/$(SYSTEM)/system_impl.cmo \
system.cmo \
\
ubase/projectInfo.cmo ubase/myMap.cmo ubase/safelist.cmo \
ubase/util.cmo ubase/uarg.cmo \
ubase/prefs.cmo ubase/trace.cmo ubase/proplist.cmo \
\
lwt/pqueue.cmo lwt/lwt.cmo lwt/lwt_util.cmo \
lwt/$(SYSTEM)/lwt_unix_impl.cmo lwt/lwt_unix.cmo \
\
features.cmo uutil.cmo case.cmo pred.cmo terminal.cmo \
fileutil.cmo name.cmo path.cmo fspath.cmo fs.cmo fingerprint.cmo \
abort.cmo osx.cmo fswatch.cmo propsdata.cmo \
props.cmo fileinfo.cmo os.cmo lock.cmo clroot.cmo common.cmo \
tree.cmo checksum.cmo transfer.cmo xferhint.cmo \
remote.cmo external.cmo negotiate.cmo globals.cmo fswatchold.cmo \
fpcache.cmo update.cmo copy.cmo stasher.cmo \
files.cmo sortri.cmo recon.cmo transport.cmo \
strings.cmo uicommon.cmo uitext.cmo test.cmo
OCAMLOBJS+=main.cmo
# OCaml libraries for the bytecode version
# File extensions will be substituted for the native code version
OCAMLLIBS+=unix.cma str.cma
INCLFLAGS+=-I +unix -I +str
# C objects for both bytecode and native versions
COBJS += osxsupport$(OBJ_EXT) pty$(OBJ_EXT) bytearray_stubs$(OBJ_EXT) \
hash_compat$(OBJ_EXT) props_xattr$(OBJ_EXT) props_acl$(OBJ_EXT)
####################################################################
### User Interface setup
## Text UI
OCAMLOBJS_TUI+=linktext.cmo
## Mac UI
OCAMLOBJS_MAC+=uimacbridge.cmo
OCAMLLIBS_MAC+=threads.cma
INCLFLAGS_MAC+=-I +threads
## Graphic UI
OCAMLFIND := $(shell command -v ocamlfind 2> /dev/null)
ifndef OCAMLFIND
CAMLFLAGS_GUI+=-I +lablgtk3 -I +cairo2
else
CAMLFLAGS_GUI+=$(shell $(OCAMLFIND) query -i-format lablgtk3 )
CAMLFLAGS_GUI+=$(shell $(OCAMLFIND) query -i-format cairo2 )
endif
OCAMLOBJS_GUI+=pixmaps.cmo uigtk3.cmo linkgtk3.cmo
OCAMLLIBS_GUI+=lablgtk3.cma cairo.cma
ifneq ($(strip $(LDFLAGS_GUI)),)
CAMLLDFLAGS_GUI+=-cclib "$(LDFLAGS_GUI)"
endif
####################################################################
### Unison executables
NAME_GUI = $(NAME)-gui
.PHONY: tui
tui: buildexecutable $(NAME)$(EXEC_EXT)
.PHONY: gui
gui: buildexecutable $(NAME_GUI)$(EXEC_EXT)
.PHONY: macui
macui: buildexecutable macexecutable
UIMACDIR=uimac
ifeq ($(OSARCH),Darwin)
ifeq ($(strip $(XCODEFLAGS)),)
XCODEFLAGS=-arch $(shell uname -m) ## Prevent Xcode from trying to build universal binaries by default
endif
endif
# Note: The OCaml library names changed starting with OCaml 5.1.0
.PHONY: macexecutable
macexecutable:
(cd $(UIMACDIR); \
LIB_SUFFIX=$$(ocaml -e 'if Sys.ocaml_release.major > 5 || Sys.ocaml_release.major = 5 && Sys.ocaml_release.minor >= 1 then print_string "nat"' 2> /dev/null); \
printf "MARKETING_VERSION = $(VERSION)\nOCAMLLIBDIR = $(OCAMLLIBDIR)\nOCAMLLIB_UNIX = -lunix$${LIB_SUFFIX}\nOCAMLLIB_STR = -lcamlstr$${LIB_SUFFIX}" > ExternalSettings.xcconfig)
(cd $(UIMACDIR); xcodebuild $(XCODEFLAGS) SYMROOT=build)
$(CC) $(CFLAGS) $(UIMACDIR)/cltool.c -o $(UIMACDIR)/build/Default/Unison.app/Contents/MacOS/cltool -framework Carbon
codesign --remove-signature $(UIMACDIR)/build/Default/Unison.app
codesign --force --sign - $(UIMACDIR)/build/Default/Unison.app/Contents/MacOS/cltool
codesign --force --sign - --entitlements $(UIMACDIR)/build/uimac*.build/Default/uimac.build/Unison.app.xcent $(UIMACDIR)/build/Default/Unison.app
codesign --verify --deep --strict $(UIMACDIR)/build/Default/Unison.app
# cltool was added into the .app after it was signed, so the signature is now
# broken. It must be removed, cltool separately signed, and then the entire
# .app (re-)signed.
clean::
-(cd $(UIMACDIR); xcodebuild clean 2> /dev/null) || true
-(cd $(UIMACDIR); $(RM) -r build ExternalSettings.xcconfig)
####################################################################
### Filesystem monitoring
NAME_FSM = $(NAME)-fsmonitor
ifeq ($(OSARCH),Linux)
FSMDIR = fsmonitor/linux
endif
ifeq ($(OSARCH),SunOS)
FSMDIR = fsmonitor/solaris
endif
ifeq ($(OSARCH),Win32)
FSMDIR = fsmonitor/windows
endif
.PHONY: fsmonitor
ifdef FSMDIR
fsmonitor: buildexecutable $(NAME_FSM)$(EXEC_EXT)
-include $(FSMDIR)/Makefile
else
fsmonitor:
$(info fsmonitor implementation is not available or not configured for this system. fsmonitor will not be built.)
endif
DEP_INCLFLAGS+=-I fsmonitor -I fsmonitor/linux -I fsmonitor/solaris -I fsmonitor/windows
####################################################################
### Dependencies
# Include an automatically generated list of dependencies
-include .depend
# Additional dependencies depending on the system
system.cmo fspath.cmo fs.cmo: system/$(SYSTEM)/system_impl.cmo
system.cmx fspath.cmx fs.cmx: system/$(SYSTEM)/system_impl.cmx
lwt/lwt_unix.cmo: lwt/$(SYSTEM)/lwt_unix_impl.cmo
lwt/lwt_unix.cmx: lwt/$(SYSTEM)/lwt_unix_impl.cmx
lwt/win/lwt_win.cmo: lwt/win/lwt_unix_impl.cmo system/system_win.cmo
lwt/win/lwt_win.cmx: lwt/win/lwt_unix_impl.cmx system/system_win.cmx
.PHONY: depend
depend:
ocamlc -depend $(DEP_INCLFLAGS) *.mli *.ml */*.ml */*.mli */*/*.ml */*/*.mli > .depend
.PHONY: dependgraph
dependgraph: depend
echo 'digraph G {' > .depend.dot.tmp
echo '{ rank = same; "Fileinfo"; "Props"; "Fspath"; "Os"; "Path"; }'\
>>.depend.dot.tmp
echo '{ rank = same; "Uitext"; "Uigtk"; }'>>.depend.dot.tmp
echo '{ rank = same; "Recon"; "Update"; "Transport"; "Files"; }'\
>>.depend.dot.tmp
echo '{ rank = same; "Tree"; "Safelist"; }'>>.depend.dot.tmp
echo '{ rank = same; "Uarg"; "Prefs"; }'>>.depend.dot.tmp
echo 'Attempting to use ocamldot and dot to produce a dependency graph:'
-ocamldot .depend | tail -n +2 >> .depend.dot.tmp
-dot -Tps -o DEPENDENCIES.ps .depend.dot.tmp
####################################################################
### Compilation
win32rc/unison.res: win32rc/unison.rc win32rc/U.ico
rc win32rc/unison.rc
win32rc/unison.res.lib: win32rc/unison.rc win32rc/U.ico
$(WINDRES) win32rc/unison.rc win32rc/unison.res
$(WINDRES) win32rc/unison.res win32rc/unison.res.lib
%.ml: %.mll
-$(RM) $@
ocamllex $<
%.cmi : %.mli
@echo "$(CAMLC): $< ---> $@"
$(CAMLC) $(CAMLFLAGS) -c $(CWD)/$<
%.cmo: %.ml
@echo "$(OCAMLC): $< ---> $@"
$(OCAMLC) $(CAMLFLAGS) -c $(CWD)/$<
%.cmx: %.ml
@echo "$(OCAMLOPT): $< ---> $@"
$(OCAMLOPT) $(CAMLFLAGS) -c $(CWD)/$<
%$(OBJ_EXT): %.c
@echo "$(CAMLC): $< ---> $@"
$(CAMLC) $(CAMLFLAGS) $(CAMLCFLAGS) -ccopt $(OUTPUT_SEL)$(CWD)/$@ -c $(CWD)/$<
# Need secondary expansion to bypass the immediate evaluation of pre-requisites
.SECONDEXPANSION:
$(NAME)$(EXEC_EXT): OCAMLOBJS += $(OCAMLOBJS_TUI)
$(NAME_GUI)$(EXEC_EXT): OCAMLOBJS += $(OCAMLOBJS_GUI)
$(NAME_GUI)$(EXEC_EXT): OCAMLLIBS += $(OCAMLLIBS_GUI)
$(NAME_GUI)$(EXEC_EXT): CAMLFLAGS += $(CAMLFLAGS_GUI)
$(NAME_GUI)$(EXEC_EXT): CAMLLDFLAGS += $(CAMLLDFLAGS_GUI)
$(NAME_FSM)$(EXEC_EXT): OCAMLOBJS = $(FSMOCAMLOBJS)
$(NAME_FSM)$(EXEC_EXT): OCAMLLIBS = $(FSMOCAMLLIBS)
$(NAME_FSM)$(EXEC_EXT): CAMLFLAGS += -I fsmonitor -I $(FSMDIR)
$(NAME_FSM)$(EXEC_EXT): COBJS = $(FSMCOBJS)
$(NAME)$(EXEC_EXT) $(NAME_GUI)$(EXEC_EXT) $(NAME_FSM)$(EXEC_EXT): $$(CAMLOBJS) $$(COBJS)
@echo Linking $@
$(CAMLC) -verbose $(CAMLFLAGS) $(CAMLLDFLAGS) -o $@ $(CAMLCFLAGS) $(CAMLLIBS) $^ $(CLIBS)
$(NAME)-blob.o: OCAMLOBJS += $(OCAMLOBJS_MAC)
$(NAME)-blob.o: OCAMLLIBS += $(OCAMLLIBS_MAC)
$(NAME)-blob.o: INCLFLAGS += $(INCLFLAGS_MAC)
# Unfortunately -output-obj does not put .o files into the output, only .cmx
# files, so we have to use $(LD) to take care of COBJS.
# [2023-07] The limitations of -output-obj have been overcome by a new option
# -output-complete-obj, available since OCaml 4.02.2. Still, this option can't
# be used here because there is a bug which breaks linking on macOS when using
# threads (needed by uimacbridge): https://github.com/ocaml/ocaml/issues/7933
$(NAME)-blob.o: $$(CAMLOBJS) $(COBJS)
@echo Linking $@
$(CAMLC) -dstartup -output-obj -verbose -cclib -keep_private_externs $(CAMLFLAGS) -o u-b.o $(CAMLCFLAGS) $(CAMLLDFLAGS) $(CAMLLIBS) $(CLIBS) $(CAMLOBJS)
$(LD) -r -keep_private_externs -o $@ u-b.o $(COBJS)
$(RM) u-b.o
####################################################################
### Misc
clean::
-$(RM) $(NAME) $(NAME).exe
-$(RM) $(NAME_GUI) $(NAME_GUI).exe
-$(RM) $(NAME_FSM) $(NAME_FSM).exe
-$(RM) $(NAME)-blob.o
-$(RM) -r *.cmi *.cmo *.cmx *.cma *.cmxa TAGS tags
-$(RM) -r *.o core gmon.out *~ .*~
-$(RM) -r *.obj *.lib *.exp
-$(RM) -r *.tmp *.bak?.tmp .*.bak?.tmp
-$(RM) system/*.cm[iox] system/*.o system/*.obj system/win/*~
-$(RM) system/generic/*.cm[iox] system/generic/*.o system/generic/*.obj system/generic/*~
-$(RM) system/win/*.cm[iox] system/win/*.o system/win/*.obj system/win/*~
-$(RM) win32rc/unison.res win32rc/unison.res.lib
-$(RM) fsmonitor/*.cm[iox] fsmonitor/*.o fsmonitor/*.obj fsmonitor/*~
ifdef FSMDIR
-$(RM) $(FSMDIR)/*.cm[iox] $(FSMDIR)/*.o $(FSMDIR)/*~
endif
-$(RM) .depend.dot.tmp DEPENDENCIES.ps
-$(RM) ubase/*.cm[ioxa] ubase/*.cmxa ubase/*.a ubase/*.o ubase/*~ ubase/*.bak
-$(RM) lwt/*.cm[ioxa] lwt/*.cmxa lwt/*.a lwt/*.o lwt/*.obj lwt/*~ lwt/*.bak
-$(RM) lwt/generic/*.cm[ioxa] lwt/generic/*.cmxa lwt/generic/*.a lwt/generic/*.o lwt/generic/*.obj lwt/generic/*~ lwt/generic/*.bak
-$(RM) lwt/win/*.cm[ioxa] lwt/win/*.cmxa lwt/win/*.a lwt/win/*.o lwt/win/*.obj lwt/win/*~ lwt/win/*.bak
.PHONY: paths
paths:
@echo PATH = '$(PATH)'
@echo OCAMLLIBDIR = '$(OCAMLLIBDIR)'