-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
cmake-1.1.tcl
477 lines (432 loc) · 20.8 KB
/
cmake-1.1.tcl
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
474
475
476
477
# -*- coding: utf-8; mode: tcl; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; truncate-lines: t -*- vim:fenc=utf-8:et:sw=4:ts=4:sts=4
#
# Usage:
# PortGroup cmake 1.1
namespace eval cmake {
# our directory:
variable currentportgroupdir [file dirname [dict get [info frame 0] file]]
}
options cmake.build_dir \
cmake.source_dir \
cmake.generator \
cmake.generator_blacklist \
cmake.build_type \
cmake.install_prefix \
cmake.install_rpath \
cmake.module_path \
cmake_share_module_dir \
cmake.out_of_source \
cmake.set_osx_architectures
## Explanation of and default values for the options defined above ##
# out-of-source builds are the default
default cmake.out_of_source yes
# cmake.build_dir defines where the build will take place
default cmake.build_dir {${workpath}/build}
# cmake.source_dir defines where CMake will look for the toplevel CMakeLists.txt file
default cmake.source_dir {${worksrcpath}}
# set CMAKE_OSX_ARCHITECTURES when necessary.
# This can be deactivated when (non-Apple) compilers are used
# that don't support the corresponding -arch options.
default cmake.set_osx_architectures yes
# cmake.build_type defines the type of build; it defaults to "MacPorts"
# which means only the compiler options set through configure.c*flags and configure.optflags
# are used, plus those set in the port's CMake files. Alternative pre-defined types are
# Release, Debug, RelWithDebInfo and MinSizeRel; "None" should work like "MacPorts".
default cmake.build_type MacPorts
# cmake-based ports may want to modify the install prefix
default cmake.install_prefix {${prefix}}
# minimal/initial value for the install rpath:
default cmake.install_rpath {${prefix}/lib}
# standard place to install extra CMake modules
default cmake_share_module_dir {${prefix}/share/cmake/Modules}
# extra locations to search for modules can be specified with
# cmake.module_path; they come after ${cmake_share_module_dir}
default cmake.module_path {}
# CMake provides several different generators corresponding to different utilities
# (and IDEs) used for building the sources. We support "Unix Makefiles" (the default)
# and Ninja, a leaner-and-meaner alternative.
#
# In the Portfile, use
#
# cmake.generator Ninja
# or
# cmake.generator "Unix Makefiles"
# or even
# cmake.generator "Eclipse CDT4 - Ninja"
# if maintaining the port means editing it using an IDE of choice.
#
# If ports package code that cannot be built with certain generators this
# fact can be signalled:
#
# cmake.generator_blacklist <generator-pattern>
# (patterns are case-insensitive, e.g. "*ninja*")
#
default cmake.generator "CodeBlocks - Unix Makefiles"
default cmake.generator_blacklist {}
# CMake generates Unix Makefiles that contain a special "fast" install target
# which skips the whole "let's see if there's anything left to (re)build before
# we install" you normally get with `make install`. That check should be
# redundant in normal destroot steps, because we just completed the build step.
default destroot.target install/fast
## ############################################################### ##
# make sure cmake is available:
# can use cmake or cmake-devel; default to cmake if not installed
depends_build-append path:bin/cmake:cmake
proc cmake::rpath_flags {} {
global prefix
if {[llength [option cmake.install_rpath]]} {
# make sure a single ${cmake.install_prefix} is included in the rpath
# careful, we are likely to be called more than once.
if {"[option cmake.install_prefix]/lib" ni [option cmake.install_rpath]} {
cmake.install_rpath-append [option cmake.install_prefix]/lib
}
return [list \
-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON \
-DCMAKE_INSTALL_RPATH="[join [option cmake.install_rpath] \;]"
]
}
# always build with full RPATH; this is the default on Mac.
# Let ports deactivate it explicitly if they need to.
return -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON
}
proc cmake::system_prefix_path {} {
global prefix
if {[option cmake.install_prefix] ne ${prefix}} {
return [list \
-DCMAKE_SYSTEM_PREFIX_PATH="${prefix}\;[option cmake.install_prefix]\;/usr"
]
} else {
return [list \
-DCMAKE_SYSTEM_PREFIX_PATH="${prefix}\;/usr"
]
}
}
proc cmake::module_path {} {
if {[llength [option cmake.module_path]]} {
set modpath "[join [concat [option cmake_share_module_dir] [option cmake.module_path]] \;]"
} else {
set modpath [option cmake_share_module_dir]
}
return [list \
-DCMAKE_MODULE_PATH="${modpath}" \
-DCMAKE_PREFIX_PATH="${modpath}"
]
}
proc cmake::build_dir {} {
if {[option cmake.out_of_source]} {
return [option cmake.build_dir]
}
return [option cmake.source_dir]
}
option_proc cmake.generator cmake::handle_generator
proc cmake::handle_generator {option action args} {
global cmake.generator destroot destroot.target build.cmd build.post_args
global depends_build destroot.post_args build.jobs subport
if {${action} eq "set"} {
switch -glob [lindex ${args} 0] {
"*Unix Makefiles*" {
ui_debug "Selecting the 'Unix Makefiles' generator ($args)"
depends_build-delete \
port:ninja
build.cmd make
build.post_args VERBOSE=ON
destroot.target install/fast
destroot.destdir \
DESTDIR=${destroot}
# unset the DESTDIR env. variable if it has been set before
destroot.env-delete \
DESTDIR=${destroot}
}
"*Ninja" {
ui_debug "Selecting the Ninja generator ($args)"
depends_build-append \
port:ninja
build.cmd ninja
# force Ninja to use the exact number of requested build jobs
build.post_args -j${build.jobs} -v
destroot.target install
# ninja needs the DESTDIR argument in the environment
destroot.destdir
destroot.env-append DESTDIR=${destroot}
}
default {
if {[llength $args] != 1} {
set msg "cmake.generator requires a single value (not \"${args}\")"
} else {
set msg "The \"${args}\" generator is not currently known/supported (cmake.generator is case-sensitive!)"
}
if {[file tail ${cmake::currentportgroupdir}] eq "group"} {
# we're not being run from the registry so we can raise errors
return -code error ${msg}
} else {
ui_error "${msg} (ignoring)"
}
}
}
}
}
default configure.dir {[cmake::build_dir]}
default build.dir {${configure.dir}}
default build.post_args VERBOSE=ON
# cache the configure.ccache variable (it will be overridden in the pre-configure step)
set cmake::ccache_cache ${configure.ccache}
# tell CMake to use ccache via the CMAKE_<LANG>_COMPILER_LAUNCHER variable
# and unset the global configure.ccache option which is not compatible
# with CMake.
# See https://stackoverflow.com/questions/1815688/how-to-use-ccache-with-cmake
proc cmake::ccaching {} {
global prefix
namespace upvar ::cmake ccache_cache cccache
if {${cccache} && [file exists ${prefix}/bin/ccache]} {
return [list \
-DCMAKE_C_COMPILER_LAUNCHER=${prefix}/bin/ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=${prefix}/bin/ccache]
}
}
configure.cmd ${prefix}/bin/cmake
# appropriate default settings for configure.pre_args
# variables are grouped thematically, with the more important ones
# at the beginning or end for somewhat easier at-a-glance verification.
# Policy 25=new: identify Apple Clang as AppleClang to ensure
# consistency in compiler feature determination
# Policy 60=new: don't rewrite ${prefix}/lib/libfoo.dylib as -lfoo
default configure.pre_args {[list \
-DCMAKE_BUILD_TYPE=${cmake.build_type} \
-DCMAKE_INSTALL_PREFIX="${cmake.install_prefix}" \
-DCMAKE_INSTALL_NAME_DIR="${cmake.install_prefix}/lib" \
{*}[cmake::system_prefix_path] \
{*}[cmake::ccaching] \
{-DCMAKE_C_COMPILER="$CC"} \
{-DCMAKE_CXX_COMPILER="$CXX"} \
-DCMAKE_POLICY_DEFAULT_CMP0025=NEW \
-DCMAKE_POLICY_DEFAULT_CMP0060=NEW \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_COLOR_MAKEFILE=ON \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_MAKE_PROGRAM=${build.cmd} \
{*}[cmake::module_path] \
{*}[cmake::rpath_flags] \
-Wno-dev
]}
# make sure configure.args is set but don't reset it
configure.args-append
default configure.post_args {[option cmake.source_dir]}
# CMake honors set environment variables CFLAGS, CXXFLAGS, and LDFLAGS when it
# is first run in a build directory to initialize CMAKE_C_FLAGS,
# CMAKE_CXX_FLAGS, CMAKE_[EXE|SHARED|MODULE]_LINKER_FLAGS. However, be aware
# that a CMake script can always override these flags when it runs, as they
# are frequently set internally in functions of other CMake build variables!
#
# Attention: If you want to be sure that no compiler flags are passed via
# configure.args, you have to manually clear configure.optflags, as it is set
# to "-Os" by default and added to all language-specific flags. If you want to
# turn off optimization, explicitly set configure.optflags to "-O0".
# TODO: Handle configure.objcflags (cf. to CMake upstream ticket #4756
# "CMake needs an Objective-C equivalent of CMAKE_CXX_FLAGS"
# <https://public.kitware.com/Bug/view.php?id=4756>)
# TODO: Handle the Fortran-specific configure.* variables:
# configure.fflags, configure.fcflags, configure.f90flags
# TODO: Handle the Java-specific configure.classpath variable.
pre-configure {
# create the build directory as the first step
file mkdir ${configure.dir}
# check and bail early if we'd be using an incompatible cmake generator
foreach genpattern ${cmake.generator_blacklist} {
if {[string match -nocase ${genpattern} ${cmake.generator}]} {
ui_error "port:${subport} doesn't support CMake's ${cmake.generator} generator"
return -code error "unsupported CMake generator requested (port:${subport})"
}
}
# The environment variable CPPFLAGS is not considered by CMake.
# (CMake upstream ticket #12928 "CMake silently ignores CPPFLAGS"
# <https://www.cmake.org/Bug/view.php?id=12928>).
#
# But adding -I${prefix}/include to CFLAGS/CXXFLAGS is a bad idea.
# If any other flags are needed, we need to add them.
# In addition, CMake provides build-type-specific flags for
# Release (-O3 -DNDEBUG), Debug (-g), MinSizeRel (-Os -DNDEBUG), and
# RelWithDebInfo (-O2 -g -DNDEBUG). If the configure.optflags have been
# set (-Os by default), we have to remove the optimisation flags from
# the concerned Release build type so that configure.optflags
# gets honored (Debug used by the +debug variant does not set
# optimisation flags by default).
# We use a custom BUILD_TYPE (MacPorts) so we can simply append all desired
# arguments to the CFLAGS and CXXFLAGS env. variables, which will be used
# to set CMAKE_C_FLAGS and CMAKE_CXX_FLAGS, and those will control the build.
if {![variant_isset debug]} {
configure.cflags-append -DNDEBUG
configure.cxxflags-append -DNDEBUG
}
# process ${configure.cppflags} because CMake ignores $CPPFLAGS
if {${configure.cppflags} ne ""} {
set cppflags [split ${configure.cppflags}]
# reset configure.cppflags; we don't want options in double in CPPFLAGS and CFLAGS/CXXFLAGS
configure.cppflags
# copy the cppflags arguments one by one into cflags and family
# CMake does have an INCLUDE_DIRECTORIES variable but setting it from the commandline
# doesn't have the intended effect (any longer).
foreach flag ${cppflags} {
configure.cflags-append ${flag}
configure.cxxflags-append ${flag}
# append to the ObjC flags too, even if CMake ignores them:
configure.objcflags-append ${flag}
configure.objcxxflags-append ${flag}
}
ui_debug "CPPFLAGS=\"${cppflags}\" inserted into CFLAGS=\"${configure.cflags}\" CXXFLAGS=\"${configure.cxxflags}\""
}
configure.pre_args-prepend "-G \"[join ${cmake.generator}]\""
# undo a counterproductive action from the debug PG:
configure.args-delete -DCMAKE_BUILD_TYPE=debugFull
# The configure.ccache variable has been cached so we can restore it in the post-configure
# (pre-configure and post-configure are always run in a single `port` invocation.)
configure.ccache no
# surprising but intended behaviour that's impossible to work around more gracefully:
# overriding configure.ccache fails if the user set it directly from the commandline
if {[tbool configure.ccache]} {
ui_error "Please don't use configure.ccache=yes on the commandline for port:${subport}, use configureccache=yes"
return -code error "invalid invocation (port:${subport})"
}
if {${cmake::ccache_cache}} {
ui_info " (using ccache)"
}
}
post-configure {
# restore configure.ccache:
if {[info exists cmake::ccache_cache]} {
configure.ccache ${cmake::ccache_cache}
ui_debug "configure.ccache restored to ${cmake::ccache_cache}"
}
# either compile_commands.json was created because of -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# in which case touch'ing it won't change anything. Or else it wasn't created, in which case
# we'll create a file that corresponds, i.e. containing an empty json array.
if {![file exists ${build.dir}/compile_commands.json]} {
if {![catch {set fd [open "${build.dir}/compile_commands.json" "w"]} err]} {
puts ${fd} "\[\n\]"
close ${fd}
}
}
}
proc cmake.save_configure_cmd {{save_log_too ""}} {
if {${save_log_too} ne ""} {
pre-configure {
configure.pre_args-prepend "-cf '${configure.cmd} "
configure.post_args-append "|& tee ${workpath}/.macports.${subport}.configure.log'"
configure.cmd "/bin/csh"
ui_debug "configure command set to `${configure.cmd} ${configure.pre_args} ${configure.args} ${configure.post_args}`"
}
}
post-configure {
if {![catch {set fd [open "${workpath}/.macports.${subport}.configure.cmd" "w"]} err]} {
foreach var [array names ::env] {
puts ${fd} "${var}=$::env(${var})"
}
puts ${fd} "[join [lrange [split ${configure.env} " "] 0 end] "\n"]"
# the following variables are no longer set in the environment at this point:
puts ${fd} "CPP=\"${configure.cpp}\""
# these are particularly relevant because referenced in the configure.pre_args:
puts ${fd} "CC=\"${configure.cc}\""
puts ${fd} "CXX=\"${configure.cxx}\""
if {${configure.objcxx} ne ${configure.cxx}} {
puts ${fd} "OBJCXX=\"${configure.objcxx}\""
}
puts ${fd} "CFLAGS=\"${configure.cflags}\""
puts ${fd} "CXXFLAGS=\"${configure.cxxflags}\""
if {${configure.objcflags} ne ${configure.cflags}} {
puts ${fd} "OBJCFLAGS=\"${configure.objcflags}\""
}
if {${configure.objcxxflags} ne ${configure.cxxflags}} {
puts ${fd} "OBJCXXFLAGS=\"${configure.objcxxflags}\""
}
puts ${fd} "LDFLAGS=\"${configure.ldflags}\""
if {${configure.optflags} ne ""} {
puts ${fd} "configure.optflags=\"${configure.optflags}\""
}
puts ${fd} "\ncd ${worksrcpath}"
puts ${fd} "${configure.cmd} [join ${configure.pre_args}] [join ${configure.args}] [join ${configure.post_args}]"
close ${fd}
unset fd
}
if {[file exists ${build.dir}/CMakeCache.txt]} {
# keep a backup of the CMake cache file
file copy -force ${build.dir}/CMakeCache.txt ${build.dir}/CMakeCache-MacPorts.txt
}
}
}
platform darwin {
set cmake._archflag_vars {cc_archflags cxx_archflags ld_archflags objc_archflags objcxx_archflags \
universal_cflags universal_cxxflags universal_ldflags universal_objcflags universal_objcxxflags}
pre-configure {
# cmake will add the correct -arch flag(s) based on the value of CMAKE_OSX_ARCHITECTURES.
if {[variant_exists universal] && [variant_isset universal]} {
if {[info exists universal_archs_supported]} {
merger_arch_compiler no
merger_arch_flag no
if {${cmake.set_osx_architectures}} {
global merger_configure_args
foreach arch ${universal_archs_to_use} {
lappend merger_configure_args(${arch}) -DCMAKE_OSX_ARCHITECTURES=${arch}
}
}
} elseif {${cmake.set_osx_architectures}} {
configure.universal_args-append \
-DCMAKE_OSX_ARCHITECTURES="[join ${configure.universal_archs} \;]"
}
} elseif {${cmake.set_osx_architectures}} {
configure.args-append \
-DCMAKE_OSX_ARCHITECTURES="${configure.build_arch}"
}
# Setting our own -arch flags is unnecessary (in the case of a non-universal build) or even
# harmful (in the case of a universal build, because it causes the compiler identification to
# fail; see https://public.kitware.com/pipermail/cmake-developers/2015-September/026586.html).
# Save all archflag-containing variables before changing any of them, because some of them
# declare their default value based on the value of another.
foreach archflag_var ${cmake._archflag_vars} {
global cmake._saved_${archflag_var}
set cmake._saved_${archflag_var} [option configure.${archflag_var}]
}
foreach archflag_var ${cmake._archflag_vars} {
configure.${archflag_var}
}
configure.args-append -DCMAKE_OSX_DEPLOYMENT_TARGET="${macosx_deployment_target}"
if {${configure.sdkroot} != ""} {
configure.args-append -DCMAKE_OSX_SYSROOT="${configure.sdkroot}"
} else {
configure.args-append -DCMAKE_OSX_SYSROOT="/"
}
}
post-configure {
# Although cmake wants us not to set -arch flags ourselves when we run cmake,
# ports might have need to access these variables at other times.
foreach archflag_var ${cmake._archflag_vars} {
global cmake._saved_${archflag_var}
configure.${archflag_var} {*}[set cmake._saved_${archflag_var}]
}
}
}
configure.universal_args-delete --disable-dependency-tracking
variant debug description "Enable debug binaries" {
pre-configure {
# this PortGroup uses a custom CMAKE_BUILD_TYPE giving complete control over
# the compiler flags. We use that here: replace the default -O2 with -O0, add
# debugging options and do otherwise an exactly identical build.
configure.cflags-replace -O2 -O0
configure.cxxflags-replace -O2 -O0
configure.objcflags-replace -O2 -O0
configure.objcxxflags-replace -O2 -O0
configure.ldflags-replace -O2 -O0
# get most if not all possible debug info
if {[string match *clang* ${configure.cxx}] || [string match *clang* ${configure.cc}]} {
set cmake::debugopts "-g -fno-limit-debug-info -DDEBUG"
} else {
set cmake::debugopts "-g -DDEBUG"
}
configure.cflags-append ${cmake::debugopts}
configure.cxxflags-append ${cmake::debugopts}
configure.objcflags-append ${cmake::debugopts}
configure.objcxxflags-append ${cmake::debugopts}
configure.ldflags-append ${cmake::debugopts}
# try to ensure that info won't get stripped
configure.args-append -DCMAKE_STRIP:FILEPATH=/bin/echo
}
}