1#!/usr/bin/perl
2
3# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License, version 2.0,
7# as published by the Free Software Foundation.
8#
9# This program is also distributed with certain software (including
10# but not limited to OpenSSL) that is licensed under separate terms,
11# as designated in a particular file or component or in included license
12# documentation.  The authors of MySQL hereby grant you an additional
13# permission to link the program and your derivative works with the
14# separately licensed software that they have included with MySQL.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19# GNU General Public License, version 2.0, for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24
25# -*- cperl -*-
26#
27# MySQL Cluster compile script to bridge the gap between
28# different build systems in different versions of MySQL Server
29#
30# This script is intended for internal use
31#
32use strict;
33use Cwd 'abs_path';
34use File::Basename;
35use Getopt::Long;
36
37# Only add the command line options handled by this script,
38# thus acting like a filter and passing all other arguments
39# straight through
40my $opt_debug;
41my $opt_build_type;
42my $opt_build = 1;
43my $opt_just_print;
44
45Getopt::Long::Configure("pass_through");
46GetOptions(
47
48  # Build MySQL Server and NDB with debug
49  'debug!' => \$opt_debug,
50  'with-debug:s' => sub { $opt_debug = 1; },
51  'build-type=s' => \$opt_build_type,
52  'build!' => \$opt_build,
53  'c|just-configure' => sub { $opt_build = 0; },
54  'n|just-print' => \$opt_just_print,
55) or exit(1);
56
57# Find source root directory, assume this script is
58# in <srcroot>/storage/ndb/
59my $opt_srcdir = dirname(dirname(dirname(abs_path($0))));
60die unless -d $opt_srcdir; # Sanity check that the srcdir exist
61if ($^O eq "cygwin") {
62  # Convert posix path to Windows mixed path since cmake
63  # is most likely a windows binary
64  $opt_srcdir= `cygpath -m $opt_srcdir`;
65  chomp $opt_srcdir;
66}
67
68# Check that cmake exists and figure out it's version
69my $cmake_version_id;
70{
71  my $version_text = `cmake --version`;
72  print $version_text;
73  die "Could not find cmake" if ($?);
74  if ( $version_text =~ /^cmake version ([0-9]*)\.([0-9]*)\.*([^\s]*)/ )
75  {
76    #print "1: $1 2: $2 3: $3\n";
77    $cmake_version_id= $1*10000 + $2*100 + $3;
78    #print "cmake_version_id: $cmake_version_id\n";
79  }
80  die "Could not parse cmake version" unless ($cmake_version_id);
81}
82
83
84#
85# Configure
86#
87{
88  # Remove old CMakeCache.txt(ignore if not exists) to
89  # force fresh configure
90  unlink("CMakeCache.txt");
91
92  my @args;
93
94  # Hardcoded options controlling how to build MySQL Server
95  push(@args, "-DWITH_SSL=bundled");
96
97  if ($opt_debug)
98  {
99    push(@args, "-DWITH_DEBUG=1");
100    push(@args, "-DMYSQL_MAINTAINER_MODE=0");
101  }
102
103  # Hardcoded options controlling how to build NDB
104  push(@args, "-DWITH_PLUGIN_NDBCLUSTER=1");
105  push(@args, "-DWITH_NDB_TEST=1");
106
107  # The cmake generator to use
108  if ($opt_build_type)
109  {
110    push(@args, "-G \"$opt_build_type\"");
111  }
112
113  # Sets installation directory,  bindir, libdir, libexecdir etc.
114  # The equivalent CMake variables are given without prefix
115  # e.g if --prefix is /usr and --bindir is /usr/bin
116  # then cmake variable (INSTALL_BINDIR) must be just "bin"
117  my $opt_prefix;
118  sub set_installdir
119  {
120    my($path, $varname) = @_;
121    my $prefix_length = length($opt_prefix);
122    if (($prefix_length > 0) && (index($path,$opt_prefix) == 0))
123    {
124      # path is under the prefix, remove the prefix and
125      # maybe following "/"
126      $path = substr($path, $prefix_length);
127      if(length($path) > 0)
128      {
129        my $char = substr($path, 0, 1);
130        if($char eq "/")
131        {
132          $path= substr($path, 1);
133        }
134      }
135      if(length($path) > 0)
136      {
137        push(@args, "-D$varname=$path");
138      }
139    }
140  }
141
142  # Process --configure style arguments which need special conversion
143  my $opt_bindir;
144  my $opt_libdir;
145  my $opt_libexecdir;
146  my $opt_includedir;
147  my $opt_with_zlib_dir;
148  my $opt_with_ssl;
149  my $opt_localstatedir;
150  my $opt_mysql_maintainer_mode;
151  my $opt_with_gcov;
152  my $opt_with_comment;
153  my $opt_with_plugins;
154  my $opt_without_plugin;
155  my $opt_extra_charsets;
156  my $opt_with_extra_charsets;
157  Getopt::Long::Configure("pass_through");
158  GetOptions(
159    'prefix=s' => \$opt_prefix,
160    'srcdir=s' => \$opt_srcdir,
161    'bindir=s' => \$opt_bindir,
162    'libdir=s' => \$opt_libdir,
163    'libexecdir=s' => \$opt_libexecdir,
164    'includedir=s' => \$opt_includedir,
165    'with-zlib-dir=s' => \$opt_with_zlib_dir,
166    'with-ssl:s' => \$opt_with_ssl,
167    'localstatedir=s' => \$opt_localstatedir,
168    'mysql-maintainer-mode=s' => \$opt_mysql_maintainer_mode,
169    'with-gcov' => \$opt_with_gcov,
170    'with-comment=s' => \$opt_with_comment,
171    'with-plugins=s' => \$opt_with_plugins,
172    'without-plugin=s' => \$opt_without_plugin,
173    'with-extra-charsets=s' => \$opt_with_extra_charsets,
174    'extra-charsets=s' => \$opt_extra_charsets,
175  ) or exit(1);
176
177  if($opt_prefix)
178  {
179    push(@args, "-DCMAKE_INSTALL_PREFIX=$opt_prefix");
180  }
181  if($opt_bindir)
182  {
183    set_installdir($opt_bindir, "INSTALL_BINDIR");
184  }
185  if($opt_libdir)
186  {
187    set_installdir($opt_libdir, "INSTALL_LIBDIR");
188  }
189  if($opt_libexecdir)
190  {
191    set_installdir($opt_libexecdir, "INSTALL_SBINDIR");
192  }
193  if($opt_includedir)
194  {
195    set_installdir($opt_includedir, "INSTALL_INCLUDEDIR");
196  }
197  if($opt_with_zlib_dir)
198  {
199    $opt_with_zlib_dir = "system"
200      if ($opt_with_zlib_dir ne "bundled");
201    push(@args, "-DWITH_ZLIB=$opt_with_zlib_dir");
202  }
203  if($opt_with_ssl)
204  {
205    push(@args, "-DWITH_SSL=".($opt_with_ssl ? "yes" : "bundled"));
206  }
207  if ($opt_localstatedir)
208  {
209    push(@args, "-DMYSQL_DATADIR=$opt_localstatedir");
210  }
211  if ($opt_mysql_maintainer_mode)
212  {
213    push(@args, "-DMYSQL_MAINTAINER_MODE=" .
214                 ($opt_mysql_maintainer_mode =~ /enable/ ? "1" : "0"));
215  }
216  if ($opt_with_gcov)
217  {
218    push(@args, "-DENABLE_GCOV=ON");
219  }
220  if ($opt_with_comment)
221  {
222    push(@args, "\"-DWITH_COMMENT=$opt_with_comment\"");
223  }
224  if($opt_with_plugins)
225  {
226    my @plugins= split(/,/, $opt_with_plugins);
227    foreach my $p (@plugins)
228    {
229      $p =~ s/-/_/g;
230      push(@args, "-DWITH_".uc($p)."=1");
231    }
232  }
233  if($opt_without_plugin)
234  {
235    push(@args, "-DWITHOUT_".uc($opt_without_plugin)."=1");
236  }
237  if ($opt_extra_charsets)
238  {
239    push(@args, "-DWITH_CHARSETS=$opt_extra_charsets");
240  }
241  if($opt_with_extra_charsets)
242  {
243    push(@args, "-DWITH_EXTRA_CHARSETS=$opt_with_extra_charsets");
244  }
245
246
247  # Default conversion of remaining args in ARGV from
248  # 1) --arg          -> -DARG=1
249  # 2) --arg=value    -> -DARG=value
250  # 3) arg=value      -> environment variable arg=value
251  foreach my $option (@ARGV)
252  {
253    if ($option =~  /^--/)
254    {
255      # Remove leading --
256      $option = substr($option, 2);
257
258      my @v  = split('=', $option);
259      my $name = shift(@v);
260      $name = uc($name);
261      $name =~ s/-/_/g;
262      if (@v)
263      {
264        push(@args, "-D$name=".join('=', @v));
265      }
266      else
267      {
268        push(@args, "-D$name=1");
269      }
270    }
271    else
272    {
273
274      # This must be environment variable
275      my @v  = split('=', $option);
276      my $name = shift(@v);
277      if(@v)
278      {
279        $ENV{$name} = join('=', @v);
280      }
281      else
282      {
283        die "unhandled argument '$option' found";
284      }
285    }
286  }
287
288  # The source directory to build from
289  die "srcdir already contains CMakeCache.txt, this will not work!"
290    if (-f "$opt_srcdir/CMakeCache.txt");
291  push(@args, $opt_srcdir);
292
293  cmd("cmake", @args);
294}
295
296if (!$opt_build)
297{
298  print "Configuration completed, skipping build(used --no-build)\n";
299  exit(0);
300}
301
302
303#
304# Build
305#
306{
307  if ($cmake_version_id >= 20800)
308  {
309    # Use the universal "cmake --build <dir>" way of building
310    # which is available from cmake 2.8 and works on all platforms
311    my @args;
312    push(@args, "--build");
313    push(@args, ".");
314
315    if ($^O eq "cygwin" or $^O eq "MSWin32")
316    {
317      # Choose to build RelWitDebInfo by default on Windows
318      my $config = 'RelWithDebInfo';
319      if ($opt_debug)
320      {
321	$config = 'Debug';
322      }
323      push(@args, "--config");
324      push(@args, $config);
325    }
326
327    cmd("cmake", @args);
328
329  }
330  else
331  {
332    # Use make to build, not supported on Windows
333    die "You need to install cmake with version > 2.8"
334      if ($^O eq "cygwin" or $^O eq "MSWin32");
335
336    cmd("make");
337  }
338}
339
340sub cmd {
341  my ($cmd, @a)= @_;
342
343  if ($opt_just_print){
344    print "$cmd ", join(' ', @a), "\n";
345    return;
346  }
347
348  print "compile-cluster: calling '$cmd ", join(' ', @a), "'\n";
349  system($cmd, @a)
350    and print("command failed: $!\n")
351      and exit(1);
352}
353
354exit(0);
355