1 #!/bin/bash
  2 #
  3 # Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
  4 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5 #
  6 # This code is free software; you can redistribute it and/or modify it
  7 # under the terms of the GNU General Public License version 2 only, as
  8 # published by the Free Software Foundation.  Oracle designates this
  9 # particular file as subject to the "Classpath" exception as provided
 10 # by Oracle in the LICENSE file that accompanied this code.
 11 #
 12 # This code is distributed in the hope that it will be useful, but WITHOUT
 13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 14 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 15 # version 2 for more details (a copy is included in the LICENSE file that
 16 # accompanied this code).
 17 #
 18 # You should have received a copy of the GNU General Public License version
 19 # 2 along with this work; if not, write to the Free Software Foundation,
 20 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 21 #
 22 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 23 # or visit www.oracle.com if you need additional information or have any
 24 # questions.
 25 #
 26 
 27 # This script generates a libclang bundle. On linux by building it from source
 28 # using a devkit, which should match the devkit used to build the JDK. On Macos
 29 # prebuilt binaries are downloaded and repackaged. On Windows, the binary LLVM
 30 # distribution needs to be downloaded and installed manually first.
 31 #
 32 # Set MAKE_ARGS to add parameters to make. Ex:
 33 #
 34 # $ MAKE_ARGS=-j32 bash createLibclangBundle.sh
 35 #
 36 # The llvm/clang build is very resource intensive at the end so often needs
 37 # to be restarted a few times before it fully succeeds.
 38 #
 39 # The script tries to behave well on multiple invocations, only performing steps
 40 # not already done. To redo a step, manually delete the target files from that
 41 # step.
 42 
 43 LLVM_VERSION=9.0.0
 44 
 45 BUNDLE_NAME=libclang-$LLVM_VERSION.tar.gz
 46 
 47 SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
 48 OUTPUT_DIR="${SCRIPT_DIR}/../../build/libclang"
 49 SRC_DIR="$OUTPUT_DIR/src"
 50 BUILD_DIR="$OUTPUT_DIR/build"
 51 DOWNLOAD_DIR="$OUTPUT_DIR/download"
 52 INSTALL_DIR="$OUTPUT_DIR/install"
 53 IMAGE_DIR="$OUTPUT_DIR/image"
 54 
 55 OS_NAME=$(uname -s)
 56 case $OS_NAME in
 57   Linux)
 58     USAGE="$0 <devkit dir>"
 59 
 60     if [ "$1" = "" ]; then
 61       echo $USAGE
 62       exit 1
 63     fi
 64     DEVKIT_DIR="$1"
 65 
 66     LIB_SUFFIX=.so
 67 
 68     # Download source distros
 69     mkdir -p $DOWNLOAD_DIR
 70     cd $DOWNLOAD_DIR
 71     LLVM_FILE=llvm-$LLVM_VERSION.src.tar.xz
 72     if [ ! -f $LLVM_FILE ]; then
 73       wget http://releases.llvm.org/$LLVM_VERSION/$LLVM_FILE
 74     fi
 75     CLANG_FILE=cfe-$LLVM_VERSION.src.tar.xz
 76     if [ ! -f $CLANG_FILE ]; then
 77       wget http://releases.llvm.org/$LLVM_VERSION/$CLANG_FILE
 78     fi
 79 
 80 
 81     # Unpack src
 82     mkdir -p $SRC_DIR
 83     cd $SRC_DIR
 84     LLVM_DIRNAME=llvm-$LLVM_VERSION.src
 85     LLVM_DIR=$SRC_DIR/$LLVM_DIRNAME
 86     if [ ! -d $LLVM_DIRNAME ]; then
 87       echo "Unpacking $LLVM_FILE"
 88       tar xf $DOWNLOAD_DIR/$LLVM_FILE
 89     fi
 90     CLANG_DIRNAME=cfe-$LLVM_VERSION.src
 91     CLANG_DIR=$LLVM_DIRNAME/tools/$CLANG_DIRNAME
 92     if [ ! -d $CLANG_DIR ]; then
 93       echo "Unpacking $CLANG_FILE"
 94       (cd $LLVM_DIR/tools && tar xf $DOWNLOAD_DIR/$CLANG_FILE)
 95     fi
 96 
 97     # Build
 98     mkdir -p $BUILD_DIR
 99     cd $BUILD_DIR
100 
101     #init cmake
102     if [ ! -e cmake ]; then
103       cmake -G 'Unix Makefiles' \
104             -DCMAKE_INSTALL_PREFIX=../install \
105             -DCMAKE_BUILD_TYPE=Release \
106             -DCMAKE_C_COMPILER=$DEVKIT_DIR/bin/gcc \
107             -DCMAKE_CXX_COMPILER=$DEVKIT_DIR/bin/g++ \
108             -DCMAKE_C_FLAGS="-static-libgcc" \
109             -DCMAKE_CXX_FLAGS="-static-libgcc -static-libstdc++" \
110             -DLLVM_ENABLE_TERMINFO=no \
111             $LLVM_DIR
112     fi
113 
114     # Run with nice to keep system usable during build.
115     nice make $MAKE_ARGS libclang
116     nice make $MAKE_ARGS install
117     ;;
118   Darwin)
119     LIB_SUFFIX=".dylib"
120 
121     # Download binaries
122     mkdir -p $DOWNLOAD_DIR
123     cd $DOWNLOAD_DIR
124     LLVM_FILE=clang+llvm-$LLVM_VERSION-x86_64-darwin-apple.tar.xz
125     if [ ! -f $LLVM_FILE ]; then
126       echo http://releases.llvm.org/$LLVM_VERSION/$LLVM_FILE
127       curl -O http://releases.llvm.org/$LLVM_VERSION/$LLVM_FILE
128     fi
129 
130     # Extract binaries
131     cd $OUTPUT_DIR
132     LLVM_DIRNAME=clang+llvm-$LLVM_VERSION-x86_64-darwin-apple
133     LLVM_DIR=$OUTPUT_DIR/$LLVM_DIRNAME
134     INSTALL_DIR=$LLVM_DIR
135     if [ ! -d $LLVM_DIRNAME ]; then
136       echo "Unpacking $LLVM_FILE"
137       tar xf $DOWNLOAD_DIR/$LLVM_FILE
138     fi
139     ;;
140   CYGWIN*)
141     if [ "$1" = "" ]; then
142       echo "Download and install http://releases.llvm.org/$LLVM_VERSION/LLVM-$LLVM_VERSION-win64.exe"
143       echo "Then run: $0 <path to install dir>"
144       exit 1
145     fi
146     INSTALL_DIR="$(cygpath -m -s "$1")"
147     echo "Copying from $INSTALL_DIR"
148     LIB_SUFFIX=".lib"
149 
150     if [ ! -e $IMAGE_DIR/bin/libclang.dll ]; then
151       echo "Copying libclang.dll to image"
152       mkdir -p $IMAGE_DIR/bin
153       cp -a $INSTALL_DIR/bin/libclang.* $IMAGE_DIR/bin/
154     fi
155     ;;
156   *)
157     echo " Unsupported OS: $OS_NAME"
158     exit 1
159     ;;
160 esac
161 
162 mkdir -p $IMAGE_DIR
163 # Extract what we need into an image
164 if [ ! -e $IMAGE_DIR/lib/libclang$LIB_SUFFIX ]; then
165   echo "Copying libclang$LIB_SUFFIX to image"
166   mkdir -p $IMAGE_DIR/lib
167   cp -a $INSTALL_DIR/lib/libclang.* $IMAGE_DIR/lib/
168 fi
169 if [ ! -e $IMAGE_DIR/include/clang-c ]; then
170   echo "Copying include to image"
171   mkdir -p $IMAGE_DIR/include
172   cp -a $INSTALL_DIR/include/. $IMAGE_DIR/include/
173 fi
174 if [ ! -e $IMAGE_DIR/lib/clang/$LLVM_VERSION/include/stddef.h ]; then
175   echo "Copying lib/clang/*/include to image"
176   mkdir -p $IMAGE_DIR/lib/clang/$LLVM_VERSION/include
177   cp -a $INSTALL_DIR/lib/clang/$LLVM_VERSION/include/. \
178      $IMAGE_DIR/lib/clang/$LLVM_VERSION/include/
179 fi
180 
181 # Create bundle
182 if [ ! -e $OUTPUT_DIR/$BUNDLE_NAME ]; then
183   echo "Creating $OUTPUT_DIR/$BUNDLE_NAME"
184   cd $IMAGE_DIR
185   tar zcf $OUTPUT_DIR/$BUNDLE_NAME *
186 fi