Bu, bu projede bulduğumuz en uzun süren (14 ay, ~1780 commit)
gerçek BusyBox hatası. "bbconfig" applet'i kullanıcının o anki .config'unu
çalışan binary içine gömüp busybox --show-config gibi bir komutla
gösterebilmek için scripts/config/mkconfigs.c adlı bir C programı yazıldı.
Bu program derleme sırasında .config'i okuyup her satırı doğrudan bir
C string literal'i içine fprintf ile basıyordu — satır sonu
karakterlerini \n olarak kaçışlamadan, ham (raw) newline olarak.
Sonuç: include/bbconfigopts.h içinde 900+ satır boyunca tek bir
"..." string literal'i, ortasında yüzlerce kaçışsız satır sonu ile.
Bu hiçbir C standardında geçerli değil — gerçek bir derleyiciye
verilseydi "missing terminating " character" hatası alırdın (tıpkı bu projede
bulduğumuz başka bir 1999 hatasında olduğu gibi). BusyBox'ın kendi basit bağımlılık
tarayıcısı scripts/bb_mkdep.c bunu farklı şekilde ama yine başarısız
olarak işliyor, "hmm, unterminated" diyerek build'i durduruyordu — ve bu dosya
make .depend adımında HER build'de koşulsuz üretildiği için, bu dönemdeki
hemen hemen hiçbir commit build edilemiyordu.
5 Ekim 2006'da Denis Vlasenko (bugünkü BusyBox maintainer'ı, o zamanki
kullanıcı adıyla "vda-linux") koca bir "build system overhaul" commit'i attı. Bunun
parçası olarak mkconfigs.c tamamen kaldırılıp yerine scripts/mkconfigs
adlı bir shell script'i kondu. Yeni script her .config satırını kendi
ayrı string literal'i olarak üretiyor (sed -e 's/$/\\n"/') —
yani "CONFIG_X=y\n" şeklinde, string'in İÇİNDE değil SONUNDA kaçışlı
\n ile. Ardışık string literal'leri C'de otomatik birleştiği için (string
concatenation) sonuç tamamen geçerli, tek-satırlık string'lerin art arda dizilmesi oluyor.
Basit ama köklü bir çözüm: veriyi tek dev bir string yerine, C'nin zaten desteklediği "yan yana string'ler otomatik birleşir" özelliğinden faydalanarak üretmek.
Aşağıda düzeltme commit'inin gerçek diff'i var — dosya dosya gezinebilirsin.
| @@ -0,0 +1,51 @@ | |
| + | #!/bin/sh |
| + | # |
| + | # Copyright (C) 2002 Khalid Aziz <khalid_aziz at hp.com> |
| + | # Copyright (C) 2002 Randy Dunlap <rddunlap at osdl.org> |
| + | # Copyright (C) 2002 Al Stone <ahs3 at fc.hp.com> |
| + | # Copyright (C) 2002 Hewlett-Packard Company |
| + | # |
| + | # This program is free software; you can redistribute it and/or modify |
| + | # it under the terms of the GNU General Public License as published by |
| + | # the Free Software Foundation; either version 2 of the License, or |
| + | # (at your option) any later version. |
| + | # |
| + | # This program is distributed in the hope that it will be useful, |
| + | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | # GNU General Public License for more details. |
| + | # |
| + | # You should have received a copy of the GNU General Public License |
| + | # along with this program; if not, write to the Free Software |
| + | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| + | # |
| + | # Busybox version by Matteo Croce <3297627799 at wind.it> |
| + | # |
| + | # Rules to generate bbconfig.h from .config: |
| + | # - Retain lines that begin with "CONFIG_" |
| + | # - Retain lines that begin with "# CONFIG_" |
| + | # - lines that use double-quotes must \\-escape-quote them |
| + | |
| + | if [ $# -lt 1 ] |
| + | then |
| + | config=.config |
| + | else config=$1 |
| + | fi |
| + | |
| + | echo "#ifndef _BBCONFIGOPTS_H" |
| + | echo "#define _BBCONFIGOPTS_H" |
| + | echo \ |
| + | "/* |
| + | * busybox configuration settings. |
| + | * |
| + | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| + | * |
| + | * This file is generated automatically by scripts/config/mkconfigs. |
| + | * Do not edit. |
| + | * |
| + | */" |
| + | |
| + | echo "static const char * const bbconfig_config =" |
| + | echo "`sed 's/\"/\\\\\"/g' $config | grep "^#\? \?CONFIG_" | awk '{print "\\"" $0 "\\\\n\\"";}'`" |
| + | echo ";" |
| + | echo "#endif /* _BBCONFIGOPTS_H */" |