1#!/bin/sh 2# 3# Copyright (C) 2017 and later: Unicode, Inc. and others. 4# License & terms of use: http://www.unicode.org/copyright.html 5# 6# Copyright (C) 2011-2014 IBM Corporation and Others. All Rights Reserved. 7# 8# This is designed for building and running single-source-file ICU programs. 9# 10# You can always download the latest from http://source.icu-project.org/repos/icu/tools/trunk/scripts/icurun 11# Or, as an unofficial link, http://bit.ly/icu-run 12# 13# In its simplest usage, simply type: 14# 15# icurun yourprogram.c 16# (or .cpp if it is a C++ program) 17# 18# The tool will compile and then run the program 19# 20# FINDING ICU 21# To find ICU, the following search order is used by priority: 22# 23# 1) "-i <path>" .. the <path> will be searched for either a direct path to icu-config, 24# or a directory containing it, or a directory containing '/bin' containing it. 25# In other words, if icu-config is /opt/local/bin/icu-config, any of the following will work: 26# -i /opt/local 27# -i /opt/local/bin 28# -i /opt/local/bin/icu-config 29# 30# Additionally, /icu/source is a built ICU source directory, either of the following will work: 31# 32# -i /icu 33# -i /icu/source 34# 35# Also, if /build is an out-of-source build, this will work: 36# 37# -i /build 38# 39# 2) If there is an executable ~/.icurunrc script, it can set the variable "ICU_CONFIG" to point 40# directly to the icu-config file. 41# An example ~/.icurunrc script contains just this line: 42# 43# ICU_CONFIG=/home/srl/E/II/bin/icu-config 44# 45# 3) ICU_CONFIG can be set in the environment to point to icu-config ( it's overridden by the .icurunrc script ) 46# 47# 4) if "icu-config" is on the PATH, it will be used. 48# 49# 50# RUNNING 51# Any additional arguments following the file will be passed to the application. 52# 53# TODO 54# * should support pkg-config, which is preferred over icu-config, although icu-config makes this usage 55# easier 56# 57# * need to test the $PATH and $ICU_CONFIG usage models 58 59SCRIPTVER='$Revision$' 60 61 62ICU_OVERRIDE="" 63 64usage() 65{ 66 echo "Script Version ${SCRIPTVER}" 67 echo "Usage: $0 [ -i /path/to/icu | -i /path/to/icu-config ] file.c{pp} [ program args ...]" 68} 69 70if [ $# -lt 1 ]; 71then 72 usage 73 exit 1 74fi 75 76if [ "$1" = "-?" -o $1 = "-h" ]; 77then 78 usage 79 exit 0 80fi 81 82 83if [ $1 = "-i" ]; 84then 85 shift 86 ICU_OVERRIDE=$1 87 shift 88fi 89 90if [ $1 = "-O" ]; 91then 92 shift 93 XTRA_OPTS=$1 94 shift 95fi 96 97if [ ! -x "${ICU_CONFIG}" ]; 98then 99 ICU_CONFIG=`which icu-config 2>/dev/null || echo` 100fi 101 102 103# now, search 104if [ -x ~/.icurunrc ]; 105then 106 . ~/.icurunrc 107fi 108 109IN_SOURCE= 110ICU_CONFIG_OPTS= 111 112if [ "x${ICU_OVERRIDE}" != "x" ]; 113then 114 if [ -f "${ICU_OVERRIDE}" -a -x "${ICU_OVERRIDE}" ]; 115 then 116 ICU_CONFIG="${ICU_OVERRIDE}" 117 elif [ -x "${ICU_OVERRIDE}/icu-config" ]; 118 then 119 ICU_CONFIG="${ICU_OVERRIDE}/icu-config" 120 elif [ -x "${ICU_OVERRIDE}/bin/icu-config" ]; 121 then 122 ICU_CONFIG="${ICU_OVERRIDE}/bin/icu-config" 123 elif [ -x "${ICU_OVERRIDE}/source/config/icu-config" ]; 124 then 125 ICU_CONFIG="${ICU_OVERRIDE}/source/config/icu-config" 126 IN_SOURCE="${ICU_OVERRIDE}/source" 127 elif [ -x "${ICU_OVERRIDE}/config/icu-config" ]; 128 then 129 ICU_CONFIG="${ICU_OVERRIDE}/config/icu-config" 130 IN_SOURCE="${ICU_OVERRIDE}" 131 else 132 echo "$0: Don't know what to do with $ICU_OVERRIDE - not an executable or a directory containing ICU source or install" >&2 133 exit 1 134 fi 135fi 136 137if [ ! -x "${ICU_CONFIG}" ]; 138then 139 echo "$0: Error: \"${ICU_CONFIG}\" is not an icu-config script. Goodbye." >&2 140 exit 1 141fi 142 143if ! fgrep -q -s noverify "${ICU_CONFIG}" ; 144then 145 rm -rf "${ICU_CONFIG}".junk 146 grep -v '^sanity$' < "${ICU_CONFIG}" > "${ICU_CONFIG}".junk 147 chmod u+rwx "${ICU_CONFIG}".junk 148 ICU_CONFIG="${ICU_CONFIG}.junk" 149else 150 SANITY_OPTS=--noverify 151fi 152 153if [ -d "${IN_SOURCE}" ]; 154then 155 echo "ICU workspace dir:" "${IN_SOURCE}" 156 # revisit 157 if [ -f "${IN_SOURCE}/common/unicode/utypes.h" ]; 158 then 159 top_srcdir="${IN_SOURCE}" 160 else 161 top_srcdir=`sed -n -e 's%^top_srcdir = \(.*\)%\1%p' < "${IN_SOURCE}/Makefile"` 162 if [ ! -d "${top_srcdir}" ]; 163 then 164 echo "Sorry: cannot find top_srcdir from ${IN_SOURCE}/Makefile" 165 exit 1 166 fi 167 fi 168 if [ ! -f "${top_srcdir}/common/unicode/utypes.h" ]; 169 then 170 echo Sorry: cannot find "${top_srcdir}/common/unicode/utypes.h" 171 exit 1 172 fi 173 echo "ICU top level source dir:" "${top_srcdir}" 174 175 ICU_CONFIG_OPTS=${SANITY_OPTS} 176 LINKOPTS="--ldflags-libsonly --ldflags-system --ldflags-icuio" 177 OURLIBPATH=${IN_SOURCE}/lib:${IN_SOURCE}/stubdata:${IN_SOURCE}/tools/ctestfw 178 SRC_OPTS="-I${top_srcdir}/common -I${top_srcdir}/i18n -I${top_srcdir}/io -I${top_srcdir}/tools/ctestfw -I${top_srcdir}/tools/toolutil -I${IN_SOURCE}/common -L${IN_SOURCE}/lib -L${IN_SOURCE}/stubdata -L${IN_SOURCE}/tools/ctestfw" 179 INVOKE=`${ICU_CONFIG} ${ICU_CONFIG_OPTS} --invoke`:"${OURLIBPATH}" 180else 181 # no cppflags for in-source 182 CPPOPTS="--cppflags" 183 LINKOPTS="--ldflags --ldflags-icuio" 184 INVOKE=`${ICU_CONFIG} ${ICU_CONFIG_OPTS} --invoke` 185fi 186 187echo 'ICU ' version: `${ICU_CONFIG} ${ICU_CONFIG_OPTS} --version` prefix: `${ICU_CONFIG} ${ICU_CONFIG_OPTS} --prefix` 188 189FILE=$1 190shift 191 192if [ ! -f "${FILE}" ]; 193then 194 echo "$0: Can't open ${FILE}" >&2 195 usage 196 exit 1 197fi 198 199 200 201case "${FILE}" in 202 *.cpp) 203 COMP=`${ICU_CONFIG} ${ICU_CONFIG_OPTS} --cxx --cxxflags ${CPPOPTS} ${LINKOPTS}` 204 OUT=`basename ${FILE} .cpp` 205 ;; 206 207 *.c) 208 COMP=`${ICU_CONFIG} ${ICU_CONFIG_OPTS} --cc --cflags ${CPPOPTS} ${LINKOPTS}` 209 OUT=`basename ${FILE} .c` 210 ;; 211 212 *) 213 echo "$0: error, don't know what to do with ${FILE}" >&2 214 exit 1 215 ;; 216esac 217 218echo "# ${COMP}" "${SRC_OPTS}" -o "${OUT}" "${FILE}" "${XTRA_OPTS}" 219( ${COMP} ${SRC_OPTS} -o "${OUT}" "${FILE}" ${XTRA_OPTS} || (rm -f "${OUT}" ; exit 1) ) && ( echo "# ${INVOKE} ${LEAK_CHECKER} ./${OUT}" "$@" ; "${SHELL}" -c "${INVOKE} ${LEAK_CHECKER} ./${OUT} $*") 220