configure.ac 5.17 KB
Newer Older
1
2
3
4
5
6
### configure.ac                    -*- Autoconf -*-
# Template used by Autoconf to generate 'configure' script. For more see:
#   * https://unconj.ca/blog/an-autoconf-primer-for-r-package-authors.html
#   * https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Configure-and-cleanup

AC_PREREQ(2.69)
7
AC_INIT([lightgbm], [~~VERSION~~], [], [lightgbm], [])
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

###########################
# find compiler and flags #
###########################

AC_MSG_CHECKING([location of R])
AC_MSG_RESULT([${R_HOME}])

# set up CPP flags
# find the compiler and compiler flags used by R.
: ${R_HOME=`R HOME`}
if test -z "${R_HOME}"; then
    echo "could not determine R_HOME"
    exit 1
fi
23
24
25
CXX17=`"${R_HOME}/bin/R" CMD config CXX17`
CXX17STD=`"${R_HOME}/bin/R" CMD config CXX17STD`
CXX="${CXX17} ${CXX17STD}"
26
CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS`
27
CXXFLAGS=`"${R_HOME}/bin/R" CMD config CXX17FLAGS`
28
LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS`
29
AC_LANG(C++)
30
31
32
33

# LightGBM-specific flags
LGB_CPPFLAGS=""

34
35
36
37
#########
# Eigen #
#########

38
LGB_CPPFLAGS="${LGB_CPPFLAGS} -DEIGEN_MPL2_ONLY -DEIGEN_DONT_PARALLELIZE"
39

40
41
42
43
44
45
46
47
48
49
50
51
52
###############
# MM_PREFETCH #
###############

AC_MSG_CHECKING([whether MM_PREFETCH works])
ac_mmprefetch=no
AC_LANG_CONFTEST(
    [
        AC_LANG_PROGRAM(
            [[
                #include <xmmintrin.h>
            ]],
            [[
53
54
55
                int a = 0;
                _mm_prefetch(&a, _MM_HINT_NTA);
                return 0;
56
57
58
59
            ]]
        )
    ]
)
60
${CXX} ${CPPFLAGS} ${CXXFLAGS} -o conftest conftest.cpp 2>/dev/null && ./conftest && ac_mmprefetch=yes
61
62
AC_MSG_RESULT([${ac_mmprefetch}])
if test "${ac_mmprefetch}" = yes; then
63
    LGB_CPPFLAGS="${LGB_CPPFLAGS} -DMM_PREFETCH=1"
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
fi

############
# MM_ALLOC #
############

AC_MSG_CHECKING([whether MM_MALLOC works])
ac_mm_malloc=no
AC_LANG_CONFTEST(
    [
        AC_LANG_PROGRAM(
            [[
                #include <mm_malloc.h>
            ]],
            [[
79
80
81
                char *a = (char*)_mm_malloc(8, 16);
                _mm_free(a);
                return 0;
82
83
84
85
            ]]
        )
    ]
)
86
${CXX} ${CPPFLAGS} ${CXXFLAGS} -o conftest conftest.cpp 2>/dev/null && ./conftest && ac_mm_malloc=yes
87
88
AC_MSG_RESULT([${ac_mm_malloc}])
if test "${ac_mm_malloc}" = yes; then
89
    LGB_CPPFLAGS="${LGB_CPPFLAGS} -DMM_MALLOC=1"
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
fi

##########
# OpenMP #
##########

OPENMP_CXXFLAGS=""

if test `uname -s` = "Linux"
then
    OPENMP_CXXFLAGS="\$(SHLIB_OPENMP_CXXFLAGS)"
fi

if test `uname -s` = "Darwin"
then
    OPENMP_CXXFLAGS='-Xclang -fopenmp'
    OPENMP_LIB='-lomp'
107
108
109
110
111
112
113
114

    # libomp 15.0+ from brew is keg-only (i.e. not symlinked into the standard paths search by the linker),
    # so need to search in other locations.
    # See https://github.com/Homebrew/homebrew-core/issues/112107#issuecomment-1278042927.
    #
    # If Homebrew is found and libomp was installed with it, this code adds the necessary
    # flags for the compiler to find libomp headers and for the linker to find libomp.dylib.
    HOMEBREW_LIBOMP_PREFIX=""
115
    if command -v brew >/dev/null 2>&1; then
116
117
        ac_brew_openmp=no
        AC_MSG_CHECKING([whether OpenMP was installed via Homebrew])
118
        brew --prefix libomp >/dev/null 2>&1 && ac_brew_openmp=yes
119
120
121
122
123
124
125
        AC_MSG_RESULT([${ac_brew_openmp}])
        if test "${ac_brew_openmp}" = yes; then
            HOMEBREW_LIBOMP_PREFIX=`brew --prefix libomp`
            OPENMP_CXXFLAGS="${OPENMP_CXXFLAGS} -I${HOMEBREW_LIBOMP_PREFIX}/include"
            OPENMP_LIB="${OPENMP_LIB} -L${HOMEBREW_LIBOMP_PREFIX}/lib"
        fi
    fi
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    ac_pkg_openmp=no
    AC_MSG_CHECKING([whether OpenMP will work in a package])
    AC_LANG_CONFTEST(
        [
            AC_LANG_PROGRAM(
                [[
                    #include <omp.h>
                ]],
                [[
                    return (omp_get_max_threads() <= 1);
                ]]
            )
        ]
    )
140
141
142
143
144
145
146
147
148
149
150
151
    ${CXX} ${CPPFLAGS} ${CXXFLAGS} ${LDFLAGS} ${OPENMP_CXXFLAGS} ${OPENMP_LIB} -o conftest conftest.cpp 2>/dev/null && ./conftest && ac_pkg_openmp=yes

    # -Xclang is not portable (it is clang-specific)
    # if compilation above failed, try without that flag
    if test "${ac_pkg_openmp}" = no; then
        if test -f "./conftest"; then
            rm ./conftest
        fi
        OPENMP_CXXFLAGS="-fopenmp"
        ${CXX} ${CPPFLAGS} ${CXXFLAGS} ${LDFLAGS} ${OPENMP_CXXFLAGS} ${OPENMP_LIB} -o conftest conftest.cpp 2>/dev/null && ./conftest && ac_pkg_openmp=yes
    fi

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    AC_MSG_RESULT([${ac_pkg_openmp}])
    if test "${ac_pkg_openmp}" = no; then
        OPENMP_CXXFLAGS=''
        OPENMP_LIB=''
        echo '***********************************************************************************************'
        echo ' OpenMP is unavailable on this macOS system. LightGBM code will run single-threaded as a result.'
        echo ' To use all CPU cores for training jobs, you should install OpenMP by running'
        echo ''
        echo '     brew install libomp'
        echo '***********************************************************************************************'
    fi
fi

# substitute variables from this script into Makevars.in
AC_SUBST(OPENMP_CXXFLAGS)
AC_SUBST(OPENMP_LIB)
AC_SUBST(LGB_CPPFLAGS)
AC_CONFIG_FILES([src/Makevars])

# write out Autoconf output
AC_OUTPUT