1#!@PERL_PATH@
2# -*- cperl -*-
3#
4# Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License, version 2.0,
8# as published by the Free Software Foundation.
9#
10# This program is also distributed with certain software (including
11# but not limited to OpenSSL) that is licensed under separate terms,
12# as designated in a particular file or component or in included license
13# documentation.  The authors of MySQL hereby grant you an additional
14# permission to link the program and your derivative works with the
15# separately licensed software that they have included with MySQL.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20# GNU General Public License, version 2.0, for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program; if not, write to the Free Software
24# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
25
26##############################################################################
27#
28#  This script reports various configuration settings that may be needed
29#  when using the MySQL client library.
30#
31#  This script try to match the shell script version as close as possible,
32#  but in addition being compatible with ActiveState Perl on Windows.
33#
34#  All unrecognized arguments to this script are passed to mysqld.
35#
36#  NOTE: This script will only be used on Windows until solved how to
37#        handle @LIBS@ and other strings inserted that might contain
38#        several arguments, possibly with spaces in them.
39#
40#  NOTE: This script was deliberately written to be as close to the shell
41#        script as possible, to make the maintenance of both in parallel
42#        easier.
43#
44##############################################################################
45
46use File::Basename;
47use Getopt::Long;
48use Cwd;
49use strict;
50
51my @exclude_cflags =
52  qw/DDBUG_OFF DSAFE_MUTEX DFORCE_INIT_OF_VARS
53     DEXTRA_DEBUG DHAVE_purify O O[0-9] xO[0-9] W[-A-Za-z]*
54     unroll2 ip mp restrict/;
55
56my @exclude_libs = qw/lmtmalloc static-libcxa i-static static-intel/;
57
58my $cwd = cwd();
59my $basedir;
60
61my $socket  = '@MYSQL_UNIX_ADDR@';
62my $version = '@VERSION@';
63
64sub which
65{
66  my $file = shift;
67
68  my $IFS = $^O eq "MSWin32" ? ";" : ":";
69
70  foreach my $dir ( split($IFS, $ENV{PATH}) )
71  {
72    if ( -f "$dir/$file" or -f "$dir/$file.exe" )
73    {
74      return "$dir/$file";
75    }
76  }
77  print STDERR "which: no $file in ($ENV{PATH})\n";
78  exit 1;
79}
80
81# ----------------------------------------------------------------------
82# If we can find the given directory relatively to where mysql_config is
83# we should use this instead of the incompiled one.
84# This is to ensure that this script also works with the binary MySQL
85# version
86# ----------------------------------------------------------------------
87
88sub fix_path
89{
90  my $default = shift;
91  my @dirs = @_;
92
93  foreach my $dirname ( @dirs )
94  {
95    my $path = "$basedir/$dirname";
96    if ( -d $path )
97    {
98      return $path;
99    }
100  }
101  return $default;
102}
103
104sub get_full_path
105{
106  my $file = shift;
107
108  # if the file is a symlink, try to resolve it
109  if ( $^O ne "MSWin32" and -l $file )
110  {
111    $file = readlink($file);
112  }
113
114  if ( $file =~ m,^/, )
115  {
116    # Do nothing, absolute path
117  }
118  elsif ( $file =~ m,/, )
119  {
120    # Make absolute, and remove "/./" in path
121    $file = "$cwd/$file";
122    $file =~ s,/\./,/,g;
123  }
124  else
125  {
126    # Find in PATH
127    $file = which($file);
128  }
129
130  return $file;
131}
132
133##############################################################################
134#
135#  Form a command line that can handle spaces in paths and arguments
136#
137##############################################################################
138
139sub quote_options {
140  my @cmd;
141  foreach my $opt ( @_ )
142  {
143    next unless $opt;           # If undefined or empty, just skip
144    push(@cmd, "\"$opt\"");       # Quote argument
145  }
146  return join(" ", @cmd);
147}
148
149##############################################################################
150#
151#  Main program
152#
153##############################################################################
154
155my $me = get_full_path($0);
156$basedir = dirname(dirname($me)); # Remove "/bin/mysql_config" part
157
158my $ldata   = '@localstatedir@';
159my $execdir = '@libexecdir@';
160my $bindir  = '@bindir@';
161
162# ----------------------------------------------------------------------
163# If installed, search for the compiled in directory first (might be "lib64")
164# ----------------------------------------------------------------------
165
166my $pkglibdir = fix_path('@pkglibdir@',"libmysql/relwithdebinfo",
167                         "libmysql/release","libmysql/debug","lib/mysql","lib");
168
169my $pkgincludedir = fix_path('@pkgincludedir@', "include/mysql", "include");
170
171# Assume no argument with space in it
172my @ldflags = split(" ",'@LDFLAGS@');
173
174my $port;
175if ( '@MYSQL_TCP_PORT_DEFAULT@' == 0 ) {
176  $port = 0;
177} else {
178  $port = '@MYSQL_TCP_PORT@';
179}
180
181# ----------------------------------------------------------------------
182# Create options
183# We intentionally add a space to the beginning and end of lib strings, simplifies replace later
184# ----------------------------------------------------------------------
185
186my (@lib_opts,@lib_r_opts,@lib_e_opts);
187if ( $^O eq "MSWin32" )
188{
189  my $linkpath   = "$pkglibdir";
190  # user32 is only needed for debug or embedded
191  my @winlibs = ("wsock32.lib","advapi32.lib","user32.lib");
192  @lib_opts   = ("$linkpath/perconaserverclient.lib",@winlibs);
193  @lib_r_opts = @lib_opts;
194  @lib_e_opts = ("$linkpath/mysqlserver.lib",@winlibs);
195}
196else
197{
198  my $linkpath   = "-L$pkglibdir @RPATH_OPTION@";
199  @lib_opts   = ($linkpath,"-lperconaserverclient");
200  @lib_r_opts = ($linkpath,"-lperconaserverclient_r");
201  @lib_e_opts = ($linkpath,"-lmysqld");
202}
203
204my $flags;
205$flags->{libs} =
206  [@ldflags,@lib_opts,'@ZLIB_DEPS@','@NON_THREADED_LIBS@','@openssl_libs@','@STATIC_NSS_FLAGS@'];
207$flags->{libs_r} =
208  [@ldflags,@lib_r_opts,'@ZLIB_DEPS@','@LIBS@','@openssl_libs@'];
209$flags->{embedded_libs} =
210  [@ldflags,@lib_e_opts,'@LIBDL@','@ZLIB_DEPS@','@LIBS@','@WRAPLIBS@','@openssl_libs@'];
211
212$flags->{include} = ["-I$pkgincludedir"];
213$flags->{cflags}  = [@{$flags->{include}},split(" ",'@CFLAGS@')];
214$flags->{cxxflags}= [@{$flags->{include}},split(" ",'@CXXFLAGS@')];
215
216# ----------------------------------------------------------------------
217# Remove some options that a client doesn't have to care about
218# ----------------------------------------------------------------------
219
220my $filter = join("|", @exclude_cflags);
221my @tmp = @{$flags->{cflags}};          # Copy the flag list
222$flags->{cflags} = [];                  # Clear it
223foreach my $cflag ( @tmp )
224{
225  push(@{$flags->{cflags}}, $cflag) unless $cflag =~ m/^($filter)$/o;
226}
227@tmp = @{$flags->{cxxflags}};           # Copy the flag list
228$flags->{cxxflags} = [];                # Clear it
229foreach my $cxxflag ( @tmp )
230{
231  push(@{$flags->{cxxflags}}, $cxxflag) unless $cxxflag =~ m/^($filter)$/o;
232}
233
234# Same for --libs(_r)
235$filter = join("|", @exclude_libs);
236foreach my $lib_type ( "libs","libs_r","embedded_libs" )
237{
238  my @tmp = @{$flags->{$lib_type}};          # Copy the flag list
239  $flags->{$lib_type} = [];                  # Clear it
240  foreach my $lib ( @tmp )
241  {
242    push(@{$flags->{$lib_type}}, $lib) unless $lib =~ m/^($filter)$/o;
243  }
244}
245
246my $include =       quote_options(@{$flags->{include}});
247my $cflags  =       quote_options(@{$flags->{cflags}});
248my $cxxflags=       quote_options(@{$flags->{cxxflags}});
249my $libs    =       quote_options(@{$flags->{libs}});
250my $libs_r  =       quote_options(@{$flags->{libs_r}});
251my $embedded_libs = quote_options(@{$flags->{embedded_libs}});
252
253##############################################################################
254#
255#  Usage information, output if no option is given
256#
257##############################################################################
258
259sub usage
260{
261  print <<EOF;
262Usage: $0 [OPTIONS]
263Options:
264        --cflags         [$cflags]
265        --cxxflags       [$cxxflags]
266        --include        [$include]
267        --libs           [$libs]
268        --libs_r         [$libs_r]
269        --socket         [$socket]
270        --port           [$port]
271        --version        [$version]
272        --libmysqld-libs [$embedded_libs]
273EOF
274  exit 1;
275}
276
277@ARGV or usage();
278
279##############################################################################
280#
281#  Get options and output the values
282#
283##############################################################################
284
285GetOptions(
286           "cflags"  => sub { print "$cflags\n" },
287           "cxxflags"=> sub { print "$cxxflags\n" },
288           "include" => sub { print "$include\n" },
289           "libs"    => sub { print "$libs\n" },
290           "libs_r"  => sub { print "$libs_r\n" },
291           "socket"  => sub { print "$socket\n" },
292           "port"    => sub { print "$port\n" },
293           "version" => sub { print "$version\n" },
294           "embedded-libs|embedded|libmysqld-libs" =>
295             sub { print "$embedded_libs\n" },
296           ) or usage();
297
298exit 0
299