summaryrefslogtreecommitdiff
path: root/scripts/build/libc/uClibc.sh
blob: b7fd737f4362422c60daa867608b33eecc0cd574 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# This file declares functions to install the uClibc C library
# Copyright 2007 Yann E. MORIN
# Licensed under the GPL v2. See COPYING in the root of this package

# Download uClibc
do_libc_get() {
    libc_src="http://www.uclibc.org/downloads
              http://www.uclibc.org/downloads/snapshots
              http://www.uclibc.org/downloads/old-releases"
    # For uClibc, we have almost every thing: releases, and snapshots
    # for the last month or so. We'll have to deal with svn revisions
    # later...
    CT_GetFile "uClibc-${CT_LIBC_VERSION}" ${libc_src}
    # uClibc locales
    if [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ]; then
        CT_GetFile "uClibc-locale-030818" ${libc_src}
    fi

    return 0
}

# Extract uClibc
do_libc_extract() {
    CT_Extract "uClibc-${CT_LIBC_VERSION}"
    CT_Patch "uClibc-${CT_LIBC_VERSION}"

    # uClibc locales
    if [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ]; then
        CT_Pushd "${CT_SRC_DIR}/uClibc-${CT_LIBC_VERSION}/extra/locale"
        CT_Extract "uClibc-locale-030818" nochdir
        CT_Patch "uClibc-locale-030818" nochdir
        CT_Popd
    fi

    return 0
}

# Check that uClibc has been previously configured
do_libc_check_config() {
    CT_DoStep INFO "Checking C library configuration"

    CT_TestOrAbort "You did not provide a uClibc config file!" -n "${CT_LIBC_UCLIBC_CONFIG_FILE}" -a -f "${CT_LIBC_UCLIBC_CONFIG_FILE}"

    if grep -E '^KERNEL_SOURCE=' "${CT_LIBC_UCLIBC_CONFIG_FILE}" >/dev/null 2>&1; then
        CT_DoLog WARN "Your uClibc version refers to the kernel _sources_, which is bad."
        CT_DoLog WARN "I can't guarantee that our little hack will work. Please try to upgrade."
    fi

    CT_DoLog EXTRA "Munging uClibc configuration"
    mungeuClibcConfig "${CT_LIBC_UCLIBC_CONFIG_FILE}" "${CT_CONFIG_DIR}/uClibc.config"

    CT_EndStep
}

# This functions installs uClibc's headers
do_libc_headers() {
    local install_rule

    CT_DoStep INFO "Installing C library headers"

    # Simply copy files until uClibc has the ability to build out-of-tree
    CT_DoLog EXTRA "Copying sources to build dir"
    CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/uClibc-${CT_LIBC_VERSION}"   \
                            "${CT_BUILD_DIR}/build-libc-headers"
    cd "${CT_BUILD_DIR}/build-libc-headers"

    # Retrieve the config file
    CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/uClibc.config" .config

    # uClibc uses the CROSS environment variable as a prefix to the
    # compiler tools to use.  Setting it to the empty string forces
    # use of the native build host tools, which we need at this
    # stage, as we don't have target tools yet.
    CT_DoLog EXTRA "Applying configuration"
    CT_DoYes "" |CT_DoExecLog ALL make CROSS= PREFIX="${CT_SYSROOT_DIR}/" oldconfig

    CT_DoLog EXTRA "Building headers"
    CT_DoExecLog ALL make ${CT_LIBC_UCLIBC_VERBOSITY} CROSS= PREFIX="${CT_SYSROOT_DIR}/" headers

    if [ "${CT_LIBC_UCLIBC_0_9_30_or_later}" = "y" ]; then
        install_rule=install_headers
    else
        install_rule=install_dev
    fi

    CT_DoLog EXTRA "Installing headers"
    CT_DoExecLog ALL make ${CT_LIBC_UCLIBC_VERBOSITY} CROSS= PREFIX="${CT_SYSROOT_DIR}/" "${install_rule}"

    CT_EndStep
}

# Build and install start files
do_libc_start_files() {
    :
}

# This function build and install the full uClibc
do_libc() {
    CT_DoStep INFO "Installing C library"

    # Simply copy files until uClibc has the ability to build out-of-tree
    CT_DoLog EXTRA "Copying sources to build dir"
    CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/uClibc-${CT_LIBC_VERSION}"   \
                            "${CT_BUILD_DIR}/build-libc"
    cd "${CT_BUILD_DIR}/build-libc"

    # Retrieve the config file
    CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/uClibc.config" .config

    # uClibc uses the CROSS environment variable as a prefix to the compiler
    # tools to use.  The newly built tools should be in our path, so we need
    # only give the correct name for them.
    # Note about CFLAGS: In uClibc, CFLAGS are generated by Rules.mak,
    # depending  on the configuration of the library. That is, they are tailored
    # to best fit the target. So it is useless and seems to be a bad thing to
    # use LIBC_EXTRA_CFLAGS here.
    CT_DoLog EXTRA "Applying configuration"
    CT_DoYes "" |CT_DoExecLog ALL               \
                 make CROSS=${CT_TARGET}-       \
                 PREFIX="${CT_SYSROOT_DIR}/"    \
                 oldconfig

    # We do _not_ want to strip anything for now, in case we specifically
    # asked for a debug toolchain, thus the STRIPTOOL= assignment
    # /Old/ versions can not build in //
    CT_DoLog EXTRA "Building C library"
    CT_DoExecLog ALL                                    \
    make ${CT_LIBC_UCLIBC_PARALLEL:+${PARALLELMFLAGS}}  \
         CROSS=${CT_TARGET}-                            \
         PREFIX="${CT_SYSROOT_DIR}/"                    \
         STRIPTOOL=true                                 \
         ${CT_LIBC_UCLIBC_VERBOSITY}                    \
         all

    # YEM-FIXME:
    # - we want to install 'runtime' files, eg. lib*.{a,so*}, crti.o and
    #   such files, except the headers as they already are installed
    # - "make install_dev" installs the headers, the crti.o... and the
    #   static libs, but not the dynamic libs
    # - "make install_runtime" installs the dynamic libs only
    # - "make install" calls install_runtime and install_dev
    # - so we're left with re-installing the headers... Sigh...
    #
    # We do _not_ want to strip anything for now, in case we specifically
    # asked for a debug toolchain, hence the STRIPTOOL= assignment
    #
    # Note: PARALLELMFLAGS is not usefull for installation.
    #
    CT_DoLog EXTRA "Installing C library"
    CT_DoExecLog ALL                    \
    make CROSS=${CT_TARGET}-            \
         PREFIX="${CT_SYSROOT_DIR}/"    \
         STRIPTOOL=true                 \
         ${CT_LIBC_UCLIBC_VERBOSITY}    \
         install

    if [ "${CT_LIBC_UCLIBC_BUILD_CROSS_LDD}" = "y" ]; then
        CT_DoLog EXTRA "Building C library cross-ldd"
        CT_DoExecLog ALL                    \
        make PREFIX="${CT_SYSROOT_DIR}/"    \
             ${CT_LIBC_UCLIBC_VERBOSITY}    \
             -C utils hostutils

        CT_DoLog EXTRA "Installing C library cross-ldd"
        CT_DoExecLog ALL install -m 0755 utils/ldd.host "${CT_PREFIX_DIR}/bin/${CT_TARGET}-ldd"
    fi

    CT_EndStep
}

# This function is used to install those components needing the final C compiler
do_libc_finish() {
    :
}

# Initialises the .config file to sensible values
# $1: original file
# $2: munged file
mungeuClibcConfig() {
    src_config_file="$1"
    dst_config_file="$2"
    munge_file="${CT_BUILD_DIR}/munge-uClibc-config.sed"

    # Start with a fresh file
    rm -f "${munge_file}"
    touch "${munge_file}"

    # Do it all in a sub-shell, it's easier to redirect output
    (

    # Hack our target in the config file.
    # Also remove stripping: its the responsibility of the
    # firmware builder to strip or not.
    cat <<-ENDSED
		s/^(TARGET_.*)=y$/# \\1 is not set/
		s/^# TARGET_${CT_ARCH} is not set/TARGET_${CT_ARCH}=y/
		s/^TARGET_ARCH=".*"/TARGET_ARCH="${CT_ARCH}"/
		s/.*(DOSTRIP).*/# \\1 is not set/
		ENDSED

    # Ah. We may one day need architecture-specific handler here...
    if [ "${CT_ARCH}" = "arm" ]; then
        # Hack the ARM {E,O}ABI into the config file
        if [ "${CT_ARCH_ARM_EABI}" = "y" ]; then
            cat <<-ENDSED
				s/.*(CONFIG_ARM_OABI).*/# \\1 is not set/
				s/.*(CONFIG_ARM_EABI).*/\\1=y/
				ENDSED
        else
            cat <<-ENDSED
				s/.*(CONFIG_ARM_OABI).*/\\1=y/
				s/.*(CONFIG_ARM_EABI).*/# \\1 is not set/
				ENDSED
        fi
    fi

    # Accomodate for old and new uClibc versions, where the
    # way to select between big/little endian has changed
    case "${CT_ARCH_BE},${CT_ARCH_LE}" in
        y,) cat <<-ENDSED
				s/.*(ARCH_LITTLE_ENDIAN).*/# \\1 is not set/
				s/.*(ARCH_BIG_ENDIAN).*/\\1=y/
				s/.*(ARCH_WANTS_LITTLE_ENDIAN).*/# \\1 is not set/
				s/.*(ARCH_WANTS_BIG_ENDIAN).*/\\1=y/
				ENDSED
        ;;
        ,y) cat <<-ENDSED
				s/.*(ARCH_LITTLE_ENDIAN).*/\\1=y/
				s/.*(ARCH_BIG_ENDIAN).*/# \\1 is not set/
				s/.*(ARCH_WANTS_LITTLE_ENDIAN).*/\\1=y/
				s/.*(ARCH_WANTS_BIG_ENDIAN).*/# \\1 is not set/
				ENDSED
        ;;
    esac

    # Accomodate for old and new uClibc version, where the
    # way to select between hard/soft float has changed
    case "${CT_ARCH_FLOAT_HW},${CT_ARCH_FLOAT_SW}" in
        y,) cat <<-ENDSED
				s/^[^_]*(HAS_FPU).*/\\1=y/
				s/.*(UCLIBC_HAS_FPU).*/\\1=y/
				ENDSED
            ;;
        ,y) cat <<-ENDSED
				s/^[^_]*(HAS_FPU).*/\\# \\1 is not set/
				s/.*(UCLIBC_HAS_FPU).*/# \\1 is not set/
				ENDSED
            ;;
    esac

    # Change paths to work with crosstool-NG
    # From http://www.uclibc.org/cgi-bin/viewcvs.cgi?rev=16846&view=rev
    #  " we just want the kernel headers, not the whole kernel source ...
    #  " so people may need to update their paths slightly
    quoted_kernel_source=$(echo "${CT_HEADERS_DIR}" | sed -r -e 's,/include/?$,,; s,/,\\/,g;')
    quoted_headers_dir=$(echo "${CT_HEADERS_DIR}" | sed -r -e 's,/,\\/,g;')
    # CROSS_COMPILER_PREFIX is left as is, as the CROSS parameter is forced on the command line
    # DEVEL_PREFIX is left as '/usr/' because it is post-pended to $PREFIX, wich is the correct value of ${PREFIX}/${TARGET}
    # Some (old) versions of uClibc use KERNEL_SOURCE (which is _wrong_), and
    # newer versions use KERNEL_HEADERS (which is right).
    cat <<-ENDSED
		s/^DEVEL_PREFIX=".*"/DEVEL_PREFIX="\\/usr\\/"/
		s/^RUNTIME_PREFIX=".*"/RUNTIME_PREFIX="\\/"/
		s/^SHARED_LIB_LOADER_PREFIX=.*/SHARED_LIB_LOADER_PREFIX="\\/lib\\/"/
		s/^KERNEL_SOURCE=".*"/KERNEL_SOURCE="${quoted_kernel_source}"/
		s/^KERNEL_HEADERS=".*"/KERNEL_HEADERS="${quoted_headers_dir}"/
		s/^UCLIBC_DOWNLOAD_PREGENERATED_LOCALE=y/\\# UCLIBC_DOWNLOAD_PREGENERATED_LOCALE is not set/
		ENDSED

    if [ "${CT_USE_PIPES}" = "y" ]; then
        if grep UCLIBC_EXTRA_CFLAGS extra/Configs/Config.in >/dev/null 2>&1; then
            # Good, there is special provision for such things as -pipe!
            cat <<-ENDSED
				s/^(UCLIBC_EXTRA_CFLAGS=".*)"$/\\1 -pipe"/
				ENDSED
        else
            # Hack our -pipe into WARNINGS, which will be internally incorporated to
            # CFLAGS. This a dirty hack, but yet needed
            cat <<-ENDSED
				s/^(WARNINGS=".*)"$/\\1 -pipe"/
				ENDSED
        fi
    fi

    # Locales support
    # Note that the two PREGEN_LOCALE and the XLOCALE lines may be missing
    # entirely if LOCALE is not set.  If LOCALE was already set, we'll
    # assume the user has already made all the appropriate generation
    # arrangements.  Note that having the uClibc Makefile download the
    # pregenerated locales is not compatible with crosstool; besides,
    # crosstool downloads them as part of getandpatch.sh.
    if [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] ; then
        cat <<-ENDSED
			s/^# UCLIBC_HAS_LOCALE is not set/UCLIBC_HAS_LOCALE=y\\
			UCLIBC_PREGENERATED_LOCALE_DATA=y\\
			# UCLIBC_DOWNLOAD_PREGENERATED_LOCALE_DATA is not set\\
			# UCLIBC_HAS_XLOCALE is not set/
			ENDSED
    fi

    # WCHAR support
    if [ "${CT_LIBC_UCLIBC_WCHAR}" = "y" ] ; then
        cat <<-ENDSED
			s/^.*UCLIBC_HAS_WCHAR.*/UCLIBC_HAS_WCHAR=y/
			ENDSED
    else
        cat <<-ENDSED
			s/^.*UCLIBC_HAS_WCHAR.*/UCLIBC_HAS_WCHAR=n/
			ENDSED
    fi

    # Force on options needed for C++ if we'll be making a C++ compiler.
    # I'm not sure locales are a requirement for doing C++... Are they?
    if [ "${CT_CC_LANG_CXX}" = "y" ]; then
        cat <<-ENDSED
			s/^# DO_C99_MATH is not set/DO_C99_MATH=y/
			s/^# UCLIBC_CTOR_DTOR is not set/UCLIBC_CTOR_DTOR=y/
			s/^# UCLIBC_HAS_GNU_GETOPT is not set/UCLIBC_HAS_GNU_GETOPT=y/
			ENDSED
    fi

    # Always build the libpthread_db
    cat <<-ENDSED
		s/^# PTHREADS_DEBUG_SUPPORT is not set.*/PTHREADS_DEBUG_SUPPORT=y/
		ENDSED

    # Force on debug options if asked for
    case "${CT_LIBC_UCLIBC_DEBUG_LEVEL}" in
      0)
        cat <<-ENDSED
			s/^DODEBUG=y/# DODEBUG is not set/
			s/^DODEBUG_PT=y/# DODEBUG_PT is not set/
			s/^DOASSERTS=y/# DOASSERTS is not set/
			s/^SUPPORT_LD_DEBUG=y/# SUPPORT_LD_DEBUG is not set/
			s/^SUPPORT_LD_DEBUG_EARLY=y/# SUPPORT_LD_DEBUG_EARLY is not set/
			s/^UCLIBC_MALLOC_DEBUGGING=y/# UCLIBC_MALLOC_DEBUGGING is not set/
			ENDSED
        ;;
      1)
        cat <<-ENDSED
			s/^# DODEBUG is not set.*/DODEBUG=y/
			s/^DODEBUG_PT=y/# DODEBUG_PT is not set/
			s/^DOASSERTS=y/# DOASSERTS is not set/
			s/^SUPPORT_LD_DEBUG=y/# SUPPORT_LD_DEBUG is not set/
			s/^SUPPORT_LD_DEBUG_EARLY=y/# SUPPORT_LD_DEBUG_EARLY is not set/
			s/^UCLIBC_MALLOC_DEBUGGING=y/# UCLIBC_MALLOC_DEBUGGING is not set/
			ENDSED
        ;;
      2)
        cat <<-ENDSED
			s/^# DODEBUG is not set.*/DODEBUG=y/
			s/^# DODEBUG_PT is not set.*/DODEBUG_PT=y/
			s/^# DOASSERTS is not set.*/DOASSERTS=y/
			s/^# SUPPORT_LD_DEBUG is not set.*/SUPPORT_LD_DEBUG=y/
			s/^# SUPPORT_LD_DEBUG_EARLY is not set.*/SUPPORT_LD_DEBUG_EARLY=y/
			s/^# UCLIBC_MALLOC_DEBUGGING is not set/UCLIBC_MALLOC_DEBUGGING=y/
			ENDSED
        ;;
    esac

    # And now, this is the end
    ) >>"${munge_file}"

    sed -r -f "${munge_file}" "${src_config_file}" >"${dst_config_file}"
}