Fix clang version detection in src/pal/tools/gen-buildsys-clang.sh (#11398)
[platform/upstream/coreclr.git] / src / pal / tools / gen-buildsys-clang.sh
1 #!/usr/bin/env bash
2 #
3 # This file invokes cmake and generates the build system for Clang.
4 #
5
6 if [ $# -lt 4 ]
7 then
8   echo "Usage..."
9   echo "gen-buildsys-clang.sh <path to top level CMakeLists.txt> <ClangMajorVersion> <ClangMinorVersion> <Architecture> [build flavor] [coverage] [ninja] [cmakeargs]"
10   echo "Specify the path to the top level CMake file - <ProjectK>/src/NDP"
11   echo "Specify the clang version to use, split into major and minor version"
12   echo "Specify the target architecture." 
13   echo "Optionally specify the build configuration (flavor.) Defaults to DEBUG." 
14   echo "Optionally specify 'coverage' to enable code coverage build."
15   echo "Target ninja instead of make. ninja must be on the PATH."
16   echo "Pass additional arguments to CMake call."
17   exit 1
18 fi
19
20 # Set up the environment to be used for building with clang.
21 if command -v "clang-$2.$3" > /dev/null
22     then
23         export CC="$(command -v clang-$2.$3)"
24         export CXX="$(command -v clang++-$2.$3)"
25 elif command -v "clang$2$3" > /dev/null
26     then
27         export CC="$(command -v clang$2$3)"
28         export CXX="$(command -v clang++$2$3)"
29 elif command -v clang > /dev/null
30     then
31         export CC="$(command -v clang)"
32         export CXX="$(command -v clang++)"
33 else
34     echo "Unable to find Clang Compiler"
35     exit 1
36 fi
37
38 build_arch="$4"
39 buildtype=DEBUG
40 code_coverage=OFF
41 build_tests=OFF
42 generator="Unix Makefiles"
43 __UnprocessedCMakeArgs=""
44
45 for i in "${@:5}"; do
46     upperI="$(echo $i | awk '{print toupper($0)}')"
47     case $upperI in
48       # Possible build types are DEBUG, CHECKED, RELEASE, RELWITHDEBINFO, MINSIZEREL.
49       DEBUG | CHECKED | RELEASE | RELWITHDEBINFO | MINSIZEREL)
50       buildtype=$upperI
51       ;;
52       COVERAGE)
53       echo "Code coverage is turned on for this build."
54       code_coverage=ON
55       ;;
56       INCLUDE_TESTS)
57       echo "Including tests directory in build."
58       build_tests=ON
59       ;;
60       NINJA)
61       generator=Ninja
62       ;;
63       *)
64       __UnprocessedCMakeArgs="${__UnprocessedCMakeArgs}${__UnprocessedCMakeArgs:+ }$i"
65     esac
66 done
67
68 OS=`uname`
69
70 # Locate llvm
71 # This can be a little complicated, because the common use-case of Ubuntu with
72 # llvm-3.5 installed uses a rather unusual llvm installation with the version
73 # number postfixed (i.e. llvm-ar-3.5), so we check for that first.
74 # On FreeBSD the version number is appended without point and dash (i.e.
75 # llvm-ar35).
76 # Additionally, OSX doesn't use the llvm- prefix.
77 if [ $OS = "Linux" -o $OS = "FreeBSD" -o $OS = "OpenBSD" -o $OS = "NetBSD" -o $OS = "SunOS" ]; then
78   llvm_prefix="llvm-"
79 elif [ $OS = "Darwin" ]; then
80   llvm_prefix=""
81 else
82   echo "Unable to determine build platform"
83   exit 1
84 fi
85
86 desired_llvm_major_version=$2
87 desired_llvm_minor_version=$3
88 if [ $OS = "FreeBSD" ]; then
89     desired_llvm_version="$desired_llvm_major_version$desired_llvm_minor_version"
90 elif [ $OS = "OpenBSD" ]; then
91     desired_llvm_version=""
92 elif [ $OS = "NetBSD" ]; then
93     desired_llvm_version=""
94 elif [ $OS = "SunOS" ]; then
95     desired_llvm_version=""
96 else
97   desired_llvm_version="-$desired_llvm_major_version.$desired_llvm_minor_version"
98 fi
99 locate_llvm_exec() {
100   if command -v "$llvm_prefix$1$desired_llvm_version" > /dev/null 2>&1
101   then
102     echo "$(command -v $llvm_prefix$1$desired_llvm_version)"
103   elif command -v "$llvm_prefix$1" > /dev/null 2>&1
104   then
105     echo "$(command -v $llvm_prefix$1)"
106   else
107     exit 1
108   fi
109 }
110
111 llvm_ar="$(locate_llvm_exec ar)"
112 [[ $? -eq 0 ]] || { echo "Unable to locate llvm-ar"; exit 1; }
113 llvm_link="$(locate_llvm_exec link)"
114 [[ $? -eq 0 ]] || { echo "Unable to locate llvm-link"; exit 1; }
115 llvm_nm="$(locate_llvm_exec nm)"
116 [[ $? -eq 0 ]] || { echo "Unable to locate llvm-nm"; exit 1; }
117 if [ $OS = "Linux" -o $OS = "FreeBSD" -o $OS = "OpenBSD" -o $OS = "NetBSD" -o $OS = "SunOS" ]; then
118   llvm_objdump="$(locate_llvm_exec objdump)"
119   [[ $? -eq 0 ]] || { echo "Unable to locate llvm-objdump"; exit 1; }
120 fi
121
122 cmake_extra_defines=
123 if [[ -n "$LLDB_LIB_DIR" ]]; then
124     cmake_extra_defines="$cmake_extra_defines -DWITH_LLDB_LIBS=$LLDB_LIB_DIR"
125 fi
126 if [[ -n "$LLDB_INCLUDE_DIR" ]]; then
127     cmake_extra_defines="$cmake_extra_defines -DWITH_LLDB_INCLUDES=$LLDB_INCLUDE_DIR"
128 fi
129 if [[ -n "$CROSSCOMPONENT" ]]; then
130     cmake_extra_defines="$cmake_extra_defines -DCLR_CROSS_COMPONENTS_BUILD=1"
131 fi
132 if [[ -n "$CROSSCOMPILE" ]]; then
133     if ! [[ -n "$ROOTFS_DIR" ]]; then
134         echo "ROOTFS_DIR not set for crosscompile"
135         exit 1
136     fi
137     if [[ -z $CONFIG_DIR ]]; then
138         CONFIG_DIR="$1/cross/$build_arch"
139     fi
140     cmake_extra_defines="$cmake_extra_defines -C $CONFIG_DIR/tryrun.cmake"
141     cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$CONFIG_DIR/toolchain.cmake"
142     cmake_extra_defines="$cmake_extra_defines -DCLR_UNIX_CROSS_BUILD=1"
143 fi
144 if [ $OS == "Linux" ]; then
145     linux_id_file="/etc/os-release"
146     if [[ -n "$CROSSCOMPILE" ]]; then
147         linux_id_file="$ROOTFS_DIR/$linux_id_file"
148     fi
149     if [[ -e $linux_id_file ]]; then
150         source $linux_id_file
151         cmake_extra_defines="$cmake_extra_defines -DCLR_CMAKE_LINUX_ID=$ID"
152     fi
153 fi
154 if [ "$build_arch" == "armel" ]; then
155     cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
156 fi
157
158 clang_version=$( $CC --version | head -1 | sed 's/[^0-9]*\([0-9]*\.[0-9]*\).*/\1/' )
159 # Use O1 option when the clang version is smaller than 3.9
160 # Otherwise use O3 option in release build
161 if [[ ( ${clang_version%.*} -eq 3  &&  ${clang_version#*.} -lt 9 ) &&
162       (  "$build_arch" == "arm" || "$build_arch" == "armel" ) ]]; then
163     overridefile=clang-compiler-override-arm.txt
164 else
165     overridefile=clang-compiler-override.txt
166 fi
167
168 cmake \
169   -G "$generator" \
170   "-DCMAKE_USER_MAKE_RULES_OVERRIDE=$1/src/pal/tools/$overridefile" \
171   "-DCMAKE_AR=$llvm_ar" \
172   "-DCMAKE_LINKER=$llvm_link" \
173   "-DCMAKE_NM=$llvm_nm" \
174   "-DCMAKE_OBJDUMP=$llvm_objdump" \
175   "-DCMAKE_BUILD_TYPE=$buildtype" \
176   "-DCMAKE_ENABLE_CODE_COVERAGE=$code_coverage" \
177   "-DCMAKE_EXPORT_COMPILE_COMMANDS=1 " \
178   "-DCLR_CMAKE_BUILD_TESTS=$build_tests" \
179   $cmake_extra_defines \
180   $__UnprocessedCMakeArgs \
181   "$1"