1# targeting native build, cross-compile is surely broken
2AC_INIT(codec_g72x, 1.3, http://groups.google.com/group/asterisk-g729)
3saved_cflags="$CFLAGS"
4AC_CONFIG_HEADERS([config.h])
5AC_CANONICAL_HOST
6AC_PROG_INSTALL
7AM_INIT_AUTOMAKE
8AC_PROG_CC
9AM_PROG_CC_C_O
10AC_DISABLE_STATIC
11AM_PROG_LIBTOOL
12AC_CONFIG_MACRO_DIR([m4])
13
14#echo cflags: "${saved_cflags}"
15#echo host_os: "${host_os}"
16#echo build_cpu: "${build_cpu}"
17#echo prefix: "${prefix}"
18#echo default_prefix: "${ac_default_prefix}"
19case "${host_os}" in
20    freebsd*)
21        ac_default_prefix=/usr/local
22        ;;
23    *)
24        ac_default_prefix=/usr
25        ;;
26esac
27
28# tested on raspberry Pi, may be not valid for other ARM devices
29case "${host}" in
30  armv6l-*-linux-gnueabihf*)
31    cflags="-mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -O3 -Wall"
32    march="armv6zk"
33    ;;
34esac
35
36if test "${prefix}" = "NONE"; then
37    prefix="${ac_default_prefix}"
38fi
39if test "${prefix}" != "/usr"; then
40    CPPFLAGS="$CPPFLAGS -I${prefix}/include"
41fi
42#echo new prefix: "${prefix}"
43
44ASTERISK_VERSION="160";
45
46AC_ARG_WITH(asterisk-includes,
47    AS_HELP_STRING([--with-asterisk-includes=PATH], [Path to Asterisk includes (defaults to PREFIX/include, so try --prefix first)]),
48    [ASTERISK_CFLAGS="-I\"$withval\""])
49AC_ARG_WITH(asterisk14,
50    AS_HELP_STRING([--with-asterisk14], [Build for Asterisk 1.4]),
51    [ASTERISK_VERSION="14"])
52AC_ARG_WITH(asterisk16,
53    AS_HELP_STRING([--with-asterisk16], [Build for Asterisk 1.6]),
54    [ASTERISK_VERSION="16"])
55AC_ARG_WITH(asterisk18,
56    AS_HELP_STRING([--with-asterisk18], [Build for Asterisk 1.8]),
57    [ASTERISK_VERSION="18"])
58AC_ARG_WITH(asterisk100,
59    AS_HELP_STRING([--with-asterisk100], [Build for Asterisk 10, 11, 12]),
60    [ASTERISK_VERSION="100"])
61AC_ARG_WITH(asterisk130,
62    AS_HELP_STRING([--with-asterisk130], [Build for Asterisk 13]),
63    [ASTERISK_VERSION="130"])
64AC_ARG_WITH(asterisk140,
65    AS_HELP_STRING([--with-asterisk140], [Build for Asterisk 14]),
66    [ASTERISK_VERSION="140"])
67AC_ARG_WITH(asterisk150,
68    AS_HELP_STRING([--with-asterisk150], [Build for Asterisk 15]),
69    [ASTERISK_VERSION="150"])
70AC_ARG_WITH(asterisk160,
71    AS_HELP_STRING([--with-asterisk160], [Build for Asterisk 16 (the default)]),
72    [ASTERISK_VERSION="160"])
73
74AC_ARG_WITH(ipp,
75    AS_HELP_STRING([--with-ipp=PATH], [Path to Intel IPP (/path/to/ipp)]),
76    [ipp_root="$withval"])
77
78AC_ARG_WITH(g729nofp,
79    AS_HELP_STRING([--with-g729nofp], [Use integer (no floating point) version of G.729 IPP codec (marginally faster on AMD Geode CPU)]),
80    [G72X_9_NOFP="-DG72X_9_NOFP"])
81
82AC_ARG_WITH(bcg729,
83    AS_HELP_STRING([--with-bcg729], [Build against Bcg729 library; without G.723.1]),
84    [G72X_BCG729="-DG72X_BCG729"; CPPFLAGS="$CPPFLAGS -I/usr/local/include"; LDFLAGS="$LDFLAGS -L/usr/local/lib"])
85
86# http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-intel-ipp-understanding-cpu-optimized-code-used-in-intel-ipp/
87# http://software.intel.com/sites/products/documentation/doclib/ipp_sa/71/ipp_userguide_lnx/GUID-BABCDBB5-E674-4ECF-AE3A-4945274FDA80.htm
88# IPP cores are:
89# 32-bit
90# px - pentium mmx
91# a6 - pentium3 sse (removed in IPP 6.0)
92# w7 - pentium4 sse2
93# t7 - pentium4 prescott sse3 (removed in IPP 7.0)
94# v8 - core2 ssse3
95# p8 - core2 penryn sse4.1, core i7 nehalem sse4.2 & westmere aes-ni mini-dispatcher
96# s8 - atom ssse3
97# g9 - sandy bridge avx
98# h9 - haswell avx2
99# 64-bit
100# mx - older amd64 w/o sse3?
101# m7 - pentium4 prescott sse3 em64t
102# u8 - core2 ssse3
103# y8 - core2 penryn sse4.1, core i7 nehalem sse4.2 & westmere aes-ni mini-dispatcher
104# n8 - atom ssse3
105# e9 - sandy bridge avx
106# l9 - haswell avx2
107# i7 - itanium
108
109#              sse3   ssse3  sse4.1
110# k8 w/o sse3
111# k8            +
112# k10           +
113# prescott      +
114# core2         +      +
115# penryn        +      +      +
116# atom          +      +      +
117
118AC_CHECK_HEADERS([asterisk/asterisk.h], [ASTERISK_ASTERISK_H=-DASTERISK_ASTERISK_H])
119
120AX_CHECK_COMPILER_FLAGS(-march=native,    [march=native])
121AX_CHECK_COMPILER_FLAGS(-mavx,            [mavx=-mavx],            [mavx=""])
122AX_CHECK_COMPILER_FLAGS(-march=core2,     [march_core2=core2],     [march_core2=nocona])
123AX_CHECK_COMPILER_FLAGS(-march=atom,      [march_atom=atom],       [march_core2=$march_core2; mtune_generic=-mtune=generic])
124AX_CHECK_COMPILER_FLAGS(-march=k8-sse3,   [march_k8_sse3=k8-sse3], [march_k8_sse3=k8])
125AX_CHECK_COMPILER_FLAGS(-march=barcelona, [march_k10=barcelona],   [march_k10=$march_k8_sse3])
126AX_CHECK_COMPILER_FLAGS(-march=geode,     [march_geode=geode],     [march_geode=k6-3; mtune_generic=-mtune=generic])
127
128if test "$CC" = "icc"; then
129    if test -z "$CFLAGS"; then
130        AC_MSG_ERROR([For ICC please set CFLAGS])
131    fi
132    flto=-ipo
133else
134    AX_CHECK_COMPILER_FLAGS(-flto, [flto="-flto"; fwholeprg="-fwhole-program"])
135fi
136
137AC_ARG_ENABLE([barcelona],
138    AS_HELP_STRING([--enable-barcelona],
139    [Optimize for AMD K10/Opteron/Phenom (enables SSE3)]),
140    [march=$march_k10; ipp_core=t7; ipp_core64=m7; cflags="-msse3 -mfpmath=sse"])
141AC_ARG_ENABLE([opteron-sse3],
142    AS_HELP_STRING([--enable-opteron-sse3],
143    [Optimize for AMD K8/Opteron/Athlon64 (enables SSE3)]),
144    [march=$march_k8_sse3; ipp_core=t7; ipp_core64=m7; cflags="-msse3 -mfpmath=sse"])
145AC_ARG_ENABLE([opteron],
146    AS_HELP_STRING([--enable-opteron],
147    [Optimize for AMD K8/Opteron/Athlon64 (enables SSE2)]),
148    [march=k8; ipp_core=w7; ipp_core64=mx; cflags="-msse2 -mfpmath=sse"])
149AC_ARG_ENABLE([athlon],
150    AS_HELP_STRING([--enable-athlon], [Optimize for AMD K7/Athlon-XP (enables SSE)]),
151    [march=athlon-xp; ipp_core=a6; cflags="-msse -mfpmath=sse"])
152AC_ARG_ENABLE([geode],
153    AS_HELP_STRING([--enable-geode], [Optimize for AMD Geode LX]),
154    [march=$march_geode; ipp_core=px; ipp_cdefs=-DIPPCORE_NO_SSE; cflags="$mtune_generic"])
155
156AC_ARG_ENABLE([avx],
157    AS_HELP_STRING([--enable-avx], [Optimize for Intel Sandy Bridge (enables AVX)]),
158    [march=$march_core2; ipp_core=g9; ipp_core64=e9; cflags="$mavx"])
159AC_ARG_ENABLE([penryn],
160    AS_HELP_STRING([--enable-penryn], [Optimize for Intel Core2 Penryn and Core i7 Nehalem/Westmere (enables SSE4.1)]),
161    [march=$march_core2; ipp_core=p8; ipp_core64=y8; cflags="-msse3 -mfpmath=sse"])
162AC_ARG_ENABLE([core2],
163    AS_HELP_STRING([--enable-core2], [Optimize for Intel Core2 (enables SSE3 and SSSE3)]),
164    [march=$march_core2; ipp_core=v8; ipp_core64=u8; cflags="-msse3 -mfpmath=sse"])
165AC_ARG_ENABLE([atom],
166    AS_HELP_STRING([--enable-atom], [Optimize for Intel Atom (enables SSE4.1)]),
167    [march=$march_core2; ipp_core=s8; ipp_core64=n8; cflags="-mtune=generic -msse3 -mfpmath=sse"])
168AC_ARG_ENABLE([nocona],
169    AS_HELP_STRING([--enable-nocona], [Optimize for Intel Pentium4 Prescott and Nocona (enables SSE3)]),
170    [march=nocona; ipp_core=t7; ipp_core64=m7; cflags="-msse3 -mfpmath=sse"])
171AC_ARG_ENABLE([pentium4],
172    AS_HELP_STRING([--enable-pentium4], [Optimize for Intel Pentium4 (enables SSE2)]),
173    [march=pentium4; ipp_core=w7; cflags="-msse2 -mfpmath=sse"])
174AC_ARG_ENABLE([pentiumm],
175    AS_HELP_STRING([--enable-pentiumm], [Optimize for Intel PentiumM (enables SSE2)]),
176    [march=pentium-m; ipp_core=w7; cflags="-msse2 -mfpmath=sse"])
177AC_ARG_ENABLE([pentium3],
178    AS_HELP_STRING([--enable-pentium3], [Optimize for Intel Pentium3 (enables SSE)]),
179    [march=pentium3; ipp_core=a6; cflags="-msse -mfpmath=sse"])
180AC_ARG_ENABLE([pentium2],
181    AS_HELP_STRING([--enable-pentium2], [Optimize for Intel Pentium2]),
182    [march=pentium2; ipp_core=px; ipp_cdefs=-DIPPCORE_NO_SSE; cflags=""])
183AC_ARG_ENABLE([pentium],
184    AS_HELP_STRING([--enable-pentium], [Optimize for Intel Pentium]),
185    [march=pentium-mmx; ipp_core=px; ipp_cdefs=-DIPPCORE_NO_SSE; cflags=""])
186
187if test -z "$G72X_BCG729"; then
188    if test -z "$ipp_core"; then
189        AC_CHECK_FILE([/proc/cpuinfo],
190            [cpu_features="`grep -iE ^flags /proc/cpuinfo|cut -f2 -d:|head -1`"],
191            [AC_MSG_ERROR([unable to determine CPU features, use --enable-pentium/etc. to choose the core])])
192        for f in $cpu_features; do
193            eval "cpu_feature_$f=1"
194        done
195        AC_MSG_CHECKING([host CPU features])
196        if grep -iE '^model name.* Atom' /proc/cpuinfo >/dev/null; then
197            ipp_core=s8; ipp_core64=n8;
198        elif test -n "$cpu_feature_avx"; then
199            ipp_core=g9; ipp_core64=e9;
200        elif test -n "$cpu_feature_sse4_1"; then
201            ipp_core=p8; ipp_core64=y8;
202        elif test -n "$cpu_feature_ssse3"; then
203            ipp_core=v8; ipp_core64=u8;
204        elif test -n "$cpu_feature_pni"; then
205            ipp_core=t7; ipp_core64=m7;
206        elif test -n "$cpu_feature_sse2"; then
207            ipp_core=w7; ipp_core64=mx;
208        elif test -n "$cpu_feature_sse"; then
209            ipp_core=a6;
210        elif test -n "$cpu_feature_mmx"; then
211            ipp_core=px;
212        else
213            AC_MSG_ERROR([unable to choose IPP core, use --enable-pentium/etc. to select one])
214        fi
215
216        if test "$ipp_core" = "px"; then
217            ipp_cdefs=-DIPPCORE_NO_SSE
218        fi
219        AC_MSG_RESULT([$cpu_features])
220    fi
221
222    if test -z "$saved_cflags" -a -z "$march"; then
223        AC_MSG_ERROR([compiler does not support -march=native, use --enable-pentium/etc. to choose the core, or set CFLAGS])
224    fi
225
226    case "$build_cpu" in
227        i?86)
228            ipp_arch=ia32;
229            ;;
230        x86_64|amd64)
231            ipp_arch=em64t;
232            ;;
233    esac
234
235    if test -z "$ipp_root"; then
236        AC_MSG_CHECKING([location of IPP libraries])
237        with_ipp_to_override=" (use --with-ipp=/path/to/ipp to override)"
238
239        ipp_dir="/opt/intel/ipp"
240        if test -d "$ipp_dir/"; then
241            ipp_root="$ipp_dir"
242        fi
243
244        if test -z "$ipp_root"; then
245            # IPP 7.0, 8.0
246            ipp_dir="/opt/intel/composerxe/ipp"
247            if test -d "$ipp_dir/"; then
248                ipp_root="$ipp_dir"
249            fi
250        fi
251
252        if test -z "$ipp_root"; then
253            # 5.3-6.1
254            case $ipp_core in
255                # Pentium-Pentium3 prefer IPP 5.3
256                px|a6)
257                    ipp_versions="5.3 6.1 6.0"
258                    ;;
259                *)
260                    ipp_versions="6.1 6.0 5.3"
261                    ;;
262            esac
263            for ipp_ver in $ipp_versions; do
264                ipp_dir="`echo /opt/intel/ipp/${ipp_ver}*/$ipp_arch`"
265                if test -d "$ipp_dir"; then
266                    ipp_root="$ipp_dir"
267                    break
268                fi
269            done
270        fi
271
272        AC_MSG_RESULT([$ipp_root])
273
274        if test -z "$ipp_root"; then
275            AC_MSG_ERROR([IPP not found - use --with-ipp=/path/to/ipp to specify])
276        fi
277    fi
278
279    ipp_version_h="$ipp_root"/include/ippversion.h
280    if test ! -f "$ipp_version_h"; then
281        AC_MSG_ERROR([IPP $ipp_version_h not found])
282    fi
283
284    AC_MSG_CHECKING([version of IPP libraries])
285    ipp_major=$(grep IPP_VERSION_MAJOR "$ipp_version_h" | awk '{print $3}')
286    ipp_minor=$(grep IPP_VERSION_MINOR "$ipp_version_h" | awk '{print $3}')
287    ipp_ver=$ipp_major.$ipp_minor
288    AC_MSG_RESULT([$ipp_ver])
289
290    if test $ipp_major -ge 7 -a "$ipp_arch" = "em64t"; then
291        ipp_arch=intel64
292    fi
293
294    case $ipp_core in
295        # Pentium3 a6 removed in IPP 6.0
296        a6)
297            if test "$ipp_ver" != "5.3"; then
298                if test "$ipp_ver" != "6.0" -a "$ipp_ver" != "6.1"; then
299                    AC_MSG_ERROR([Use IPP 5.3 (preferred) or 6.1 for Pentium3])
300                fi
301                ipp_core=px
302                use_ipp53=" (slower MMX core used, use IPP 5.3 for SSE instead)"
303            fi
304            ;;
305        s8)
306            if test "$ipp_ver" = "5.3"; then
307                ipp_core=v8; ipp_core64=u8
308                use_ipp60=" (Core2 scheduling used, IPP $ipp_ver does not support Atom, use IPP 6.0 or later instead)"
309            fi
310            ;;
311        # 32-bit SSE3 removed in 7.0
312        t7)
313            if test $ipp_major -ge 7; then
314                ipp_core=w7;
315                case "$build_cpu" in
316                    i?86)
317                        use_ipp60=" (SSE2 core, use IPP 6.1 for SSE3)"
318                        ;;
319                esac;
320            fi
321            ;;
322        # check missing staticlib/ include
323        g9)
324            if test $ipp_major -lt 7; then
325                AC_MSG_ERROR([Use IPP 7.0+ for Sandy Bridge AVX])
326            fi
327            case "$build_cpu" in
328                i?86)
329                    staticlib_inc="$ipp_root/tools/$ipp_arch/staticlib/ipp_$ipp_core.h"
330                    ;;
331                x86_64|amd64)
332                    staticlib_inc="$ipp_root/tools/$ipp_arch/staticlib/ipp_$ipp_core64.h"
333                    ;;
334            esac;
335            if ! test -f "$staticlib_inc"; then
336                AC_MSG_ERROR([Create "$staticlib_inc" manually as described in http://software.intel.com/en-us/articles/How-to-call-AVX-based-code-in-IPP-v-6-1/])
337            fi
338            ;;
339    esac
340
341    IPP_CFLAGS="-I\"$ipp_root/include\" $ipp_cdefs";
342    if test $ipp_major -ge 9; then
343        # need IPP Legacy to build speech codecs
344        AC_MSG_CHECKING([for legacy IPP 9.0 libraries])
345        ipp_legacy_h="$ipp_root"/legacy/include/ipps90legacy.h
346        if test ! -f "$ipp_legacy_h"; then
347            AC_MSG_ERROR([IPP $ipp_legacy_h not found])
348        fi
349        ipp_legacy_libsvml="$ipp_root"/legacy/lib/$ipp_arch/libsvml.a
350        if test ! -f "$ipp_legacy_libsvml"; then
351            AC_MSG_ERROR([IPP $ipp_legacy_libsvml not found])
352        fi
353        AC_MSG_RESULT([$ipp_legacy_h $ipp_legacy_libsvml])
354        IPP_CFLAGS="$IPP_CFLAGS -DG72X_IPP_LEGACY -I\"$ipp_root/legacy/include\" -Wno-deprecated-declarations";
355        IPP_LIBS="$ipp_root/legacy/lib/$ipp_arch/libippsc90lgc.a $ipp_root/legacy/lib/$ipp_arch/libipps90lgc.a $ipp_root/lib/$ipp_arch/libipps.a $ipp_root/lib/$ipp_arch/libippvm.a $ipp_root/lib/$ipp_arch/libippcore.a $ipp_root/legacy/lib/$ipp_arch/libirc.a $ipp_root/legacy/lib/$ipp_arch/libsvml.a"
356    elif test $ipp_major -eq 8; then
357        IPP_LIBS="$ipp_root/lib/$ipp_arch/libippsc.a $ipp_root/lib/$ipp_arch/libipps.a $ipp_root/lib/$ipp_arch/libippvm.a $ipp_root/lib/$ipp_arch/libippcore.a $ipp_root/../compiler/lib/$ipp_arch/libirc.a $ipp_root/../compiler/lib/$ipp_arch/libsvml.a"
358    elif test $ipp_major -eq 7; then
359        IPP_LIBS="-lippsc_l -lipps_l -lippcore_l"
360        IPP_LDFLAGS="-L\"$ipp_root/lib/$ipp_arch\"";
361    else
362        IPP_LDFLAGS="-L\"$ipp_root/lib\"";
363    fi
364
365    case "$build_cpu" in
366        i?86)
367            if test $ipp_major -ge 7; then
368                IPP_CFLAGS="$IPP_CFLAGS -include \"$ipp_root/tools/$ipp_arch/staticlib/ipp_$ipp_core.h\""
369            else
370                IPP_CFLAGS="$IPP_CFLAGS -include \"$ipp_root/tools/staticlib/ipp_$ipp_core.h\""
371                IPP_LIBS="-lippscmerged -lippsrmerged -lippsmerged -lippcore"
372            fi
373            ;;
374        x86_64|amd64)
375            # IPP 5.3 does not have tools/staticlib helpers
376            if test "$ipp_ver" = "5.3"; then
377                IPP_CFLAGS="$IPP_CFLAGS -DIPPCORE_STATIC_INIT"
378                IPP_LIBS="-lippscemergedem64t -lippsremergedem64t -lippsemergedem64t -lippscmergedem64t -lippsrmergedem64t -lippsmergedem64t -lippcoreem64t"
379            elif test $ipp_major -ge 7; then
380                IPP_CFLAGS="$IPP_CFLAGS -include \"$ipp_root/tools/$ipp_arch/staticlib/ipp_$ipp_core64.h\""
381            else # 6.x
382                IPP_CFLAGS="$IPP_CFLAGS -include \"$ipp_root/tools/staticlib/ipp_$ipp_core64.h\""
383                IPP_LIBS="-lippscmergedem64t -lippsrmergedem64t -lippsmergedem64t -lippcoreem64t"
384            fi
385            ipp_core=$ipp_core64 # for output
386            ;;
387    esac
388
389else # G72X_BCG729 is defined
390    AC_CHECK_LIB([bcg729], [initBcg729EncoderChannel], [], [AC_MSG_ERROR([unable to find Bcg729 library])])
391fi
392
393if test -z "$saved_cflags"; then
394    CFLAGS="-O3 -fomit-frame-pointer -march=$march $flto $cflags"
395    FLTO_LDFLAGS="$fwholeprg"
396fi
397
398AM_CONDITIONAL([BCG729], [test -n "$G72X_BCG729"])
399AM_CONDITIONAL([G729_NOFP], [test -n "$G72X_9_NOFP" -a -z "$G72X_BCG729"])
400
401AC_SUBST([ASTERISK_ASTERISK_H])
402AC_SUBST([ASTERISK_CFLAGS])
403AC_SUBST([ASTERISK_VERSION])
404AC_SUBST([IPP_CFLAGS])
405AC_SUBST([IPP_LDFLAGS])
406AC_SUBST([IPP_LIBS])
407AC_SUBST([FLTO_LDFLAGS])
408AC_SUBST([G72X_BCG729])
409AC_SUBST([G72X_9_NOFP])
410
411AC_OUTPUT([Makefile])
412
413echo
414echo "Architecture: $build_cpu"
415echo "  CPU -march: $march"
416echo "      CFLAGS: $CFLAGS $IPP_CFLAGS $ASTERISK_CFLAGS"
417echo "     LDFLAGS: $FLTO_LDFLAGS" $IPP_LDFLAGS $IPP_LIBS
418echo " Codecs impl:" $(test -z "$G72X_BCG729" && echo IPP || echo Bcg729) $(test -z "$G729_NOFP_TRUE" && echo "/ G.729 integer codec")
419if test -z "$G72X_BCG729"; then
420echo "    IPP path: $ipp_root$with_ipp_to_override"
421echo "    IPP ver.: $ipp_ver"
422echo "    IPP core: $ipp_core$use_ipp53$use_ipp60"
423fi
424