/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Building Boost for Drill on MacOs/Linux
--------------------------------

These instructions are using Boost version 1.60.0

Assuming there is a BOOST_BUILD_DIR 

$ cd $BOOST_BUILD_DIR
$ tar zxf boost_1_60_0.tar.gz
$ cd $BOOST_BUILD_DIR/boost_1_60_0
$ ./bootstrap.sh --prefix=$BOOST_BUILD_DIR/boost_1_60_0/
$ ./b2 tools/bcp
$ cd $BOOST_BUILD_DIR/drill_boost_1_60_0

# Use boost bcp to rename the boost namespace to drill_boost
# the following builds a subset of boost without icu. You may need to add more modules to include icu. 
# bcp documentation can be found here: http://www.boost.org/doc/libs/1_60_0/tools/bcp/doc/html/index.html

$ $BOOST_BUILD_DIR/boost_1_60_0/dist/bin/bcp --namespace=drill_boost --namespace-alias --boost=$BOOST_BUILD_DIR/boost_1_60_0/ shared_ptr random context chrono date_time regex system timer thread asio smart_ptr bind config build regex config assign functional multiprecision algorithm $BOOST_BUILD_DIR/drill_boost_1_60_0 

$ cd $BOOST_BUILD_DIR/drill_boost_1_60_0
$ ./bootstrap.sh --prefix=$BOOST_BUILD_DIR/drill_boost_1_60_0/

# change the variant to debug for a debug build
  # For linux 
  $ ./b2 --build-dir=$BOOST_BUILD_DIR/drill_boost_1_60_0/build variant=release link=static threading=multi cxxflags="-fPIC"
  # For MacOS
  $ ./b2 --build-dir=$BOOST_BUILD_DIR/drill_boost_1_60_0/build variant=release link=static threading=multi 


# To build the Drill client library , export the following to make sure boost is picked up correctly
$ export BOOST_INCLUDEDIR=$BOOST_BUILD_DIR/drill_boost_1_60_0
$ export BOOST_LIBRARYDIR=$BOOST_BUILD_DIR/drill_boost_1_60_0/stage/lib
$ export Boost_NO_SYSTEM_PATHS=ON

# Then follow the usual CMake build steps.


