LFS
소프트웨어 구축 HOW-TO
- 소프트웨어 패키지 다운로드
- 소프트웨어 압축 풀기 :
tar zvf filename
( .gz.tag / .bz2 ) - 설치 지침 확인 후 소프트웨어 설치 :
make install
- 패치 파일이 있다면
patch < patch file
수행
- 패치 파일이 있다면
- Makefile : 바이너리를 컴파일 하거나 빌드하기 위한 스크립트
- make : 통상적인 모든 실행파일 빌드
- make install : 적절한 디렉터리에 설치
- make clean : 오래된 object 파일 제거
- make -n : 빌드하지 않고 트리거되는 모든 명령 인쇄
- IMakefile : Makefile 템플릿,
xmkmf -a
로 Makefile, include, depend 생성 - configure : 디렉터리의 올바른 스크립트 호출 유도
-
/usr/bin
,/usr/local/bin
에 설치됨. - 상용버전은
/opt
에 설치됨.
- 사전 패키지된 바이너리
-
rpm
/deb
은tarbals
에 비해 느리게 출시된다. -
tarball
은 더 완전하고, 많은 옵션을 가질 수 있다. -
rpm --recompile packagename.rpm / rpm --rebuild packagename.rpm
등으로tarball
과 같이 빌드하고, 설치할 수 있다. - 일부 사전 패키지는 제대로 설치되지 않고, 충돌이나 덤프가 발생할 수 있다.
- 설치하기 전에
rpm --checksig packagename.rpm
에서 대조 확인을 하고 실행해야 한다.
-
- Termcap 및 Terminfo 이슈
- Terminfo 는 Termcap, termlib 를 대체, 터미널을 설명하는 데이터 베이스
- 아주 드물게 레거시의 경우 Termcap 링크 바이러리를 사용하는경우
#define termcap
을 주석 처리해야 할 수도 있음.
-
a.out
바이너리와의 하위 호환성- 드물게 새로운 ELF 바이너리를 빌드하는 것이 불가능한 경우
a.out
을 사용할 수도 있다. -
/usr/i486-linuxaout/lib
에 있는a.out
라이브러리는 ELF 설치의 거의 모든 것을 가지고 있다. - 가끔
a.out
을 로드 가능하게 하게 커널을 다시 빌드해야 할 수도 있다. - 샘플
- 드물게 새로운 ELF 바이너리를 빌드하는 것이 불가능한 경우
# /usr/i486-linuxaout/lib 에 라이브러리가 있지만 런타임에서 찾지 못함.
xrolodex: can't load library '//lib/libX11.so.3'
No such library
# 그런 경우 /lib 에 심폴릭 링크를 제공
ln -s /usr/i486-linuxaout/lib/X11.so.3.1.0 libX11.so.3
- 그 밖의 이슈 처리
- 링크 오류 (
No such file or direcotry
) :LIB, INCLUDE, LIBS
를 확인 - 링크 오류 (
cos
등 수학 라이브러리 ) :LIB, LIBS
등에-lm
추가 -
xmkmf
실패 : 다른 방법으로 시도 (make -DUseInstalled -I/usr/X386/lib/X11/config
) -
X11R5
라이브러리가 필요한 경우 : 링크 연결 (ln -s libX11.so.3.1.0 libX11.so
) -
Perl, Shell
스크립트가No such file or directory
: perl 설치 위치 확인 (/usr/local/bin
(0) ,/usr/bin
(X) ) -
./configure
를 호출하지 않으면 이상하게 구성될 수 있음. - 배포판 라이브러리 버전을 업그레이드안 경우 미리 컴파일된 바이너리가 터질 수 있음.
-
.NET
컴파일시-ansi
옵션을 제거해야 하는 경우도 있음. - 일부 프로그램은 루트 권한으로 실행하려면 setuid root 가 필요함. (보안 이슈가 있을 수도 있음.)
- Makefile 옵션들(gcc)
-
-O2
: 최적화 -
-fomit-frame-pointer
더 작은 바이너리 생성
-
- 링크 오류 (
-
.bashrc
: 특정 환경 변수 설정 -
.Xdefaults
/.Xresources
: 사용자 정의 -
~~~.ad
사용자 정의 후/usr/lib/X11/app-defaults
에 설치 - 소스 아카이브 찾는 곳
소스에서 설치하기 좋은 초보자 가이드
-
wget / curl / ftp
등으로 소스파일 다운로드 -
md5sum -c
으로 파일 확인 - 아카이브 파일 압축 해제 (
tar zvf
등) - 패치 (
patch awk sed
등) configure
make
sudo make install
- 필요 시
cmake
- 문서 설치시
/usr/share/doc
에 제공 -
strip
을 사용하면 일반 최종 사용자에게 필요하지 않은 컴파일 및 링크의 출력을 제거할 수 있음.
LFS 및 표준
- POSIX.1-2008, Filesystem Hierarchy Standard (FHS) Version 3.0, Linux Standard Base (LSB) Version 5.0 (2015) 의 표준에 따름.
-
Core
,Desktop
,Runtime
,Imaging
의 네 가지 개별 사양이 있음. -
Gtk8
,Graphics
의 시험 사양도 있음. - 요구사항 1 : LFS 패키지
- Core : Bash, Bc, Binutils, Coreutils, Diffutils, 파일, Findutils, Gawk, Grep, Gzip, M4, Man-DB, Ncurses, Procps, Psmisc, Sed, Shadow, Tar, Util-linux, Zlib
- Desktop : None
- Runtime : Perl, Python
- Imaging : None
- Gtk3, Graphic : None
- 요구사항 2 : LFS 패키지에서 제공되지 않는 패키지
- Desktop : Qt4
패키지에 대한 이론적 근거
LFS 의 목표는 자체 복제에 필요한 모든 패키지를 포함하여 완전한 시스템을 사용자 정의할 수 있는 상대적으로 최소한의 기반을 제공, 중요한 패키지에 대한 설명
- Acl : 파일 및 디렉토리에 대한 세분화된 임의 액세스 권한 정의
- Attr : 파일 시스템 object 의 확장된 속성을 관리
- Autoconf : 개발자 템플릿에서 소스 코드를 자동으로 구성할 수 있는 셸 스크립트 생성하기 위한 프로그램 제공
- Automake : 템플릿에서 Make 파일을 생성하는 프로그램이 포함되어 있음
- Bash : 시스템에 Bourme Shell 인터페이스를 제공하기 위한 LSB 코어 요구사항을 충족
- Bc : 임의의 정밀 수치 처리 언어 제공
- Bitutils : 링커, 어셈블러, 오브젝트 파일 처리 제공
- …
타이포그래피
타이밍 기법
-
\
로 줄넘김을 할 수 있지만, 탭이나 공백을 넣을 수는 없다. -
<< "EOF" ... EOF
등으로 구성 파일을 생성할 때 사용할 수 있다. -
<TEXT>
복사 붙여넣기나 캡슐화 시에 사용한다. -
[TEXT]
캡슐화 시에 사용한다.
LFS 시스템 구축 방법
- 새로운 LFS 시스템 컴파일 , 설치될 Linux 기본 파티션 및 파일 시스템 생성
- LFS 시스템 구축하기 위한 패키지 및 패치 다운로드
- 파일 시스템에 저장하는 방법
- 작업 환경 설정
- 작업 시작전 알아야 할 사항
- 크로스 컴파일 기술을 사용하여 호스트 시스템에서 새 도구를 분리하는 초기 도구 체인 설치
- 크로스 툴체인을 사용하여 기본 유틸리티 크로스 컴파일
- 새로운 도구를 사용하여 LFS 시스템을 만드는데 필요한 나머지 도구 구축하는
chroot
- LFS 시스템 구축
- 기본 시스템 구성
- 커널과 부트로더 생성
호스트 시스템 요구사항
- 하드웨어 : 4 core CPU, 8 GB Ram
- 소프트웨어 : devel , dev 제공한다면 포함하여 설치
- Bash-3.2
- Binutils-2.13.1
- Bison-2.7
- Coreutils-8.1
- Diffutils-2.8.1
- Findutils-4.2.31
- Gawk-4.0.1
- GCC-5.2
- Grep-2.5.1a
- Gzip-1.3.12
- Linux Kernel-4.19
- M4-1.4.10
- Make-4.0
- Patch-2.5.4
- Perl-5.8.8
- Python-3.4
- Sed-4.1.5
- Tar-1.22
- Texinfo-5.0
- Xz-5.0.0
- LFS 환경 변수에
FOR THE ROOT USER
로 설정 - 다 있는지 확인하려면 다음을 실행
cat > version-check.sh << "EOF"
#!/bin/bash
# A script to list version numbers of critical development tools
# If you have tools installed in other directories, adjust PATH here AND
# in ~lfs/.bashrc (section 4.4) as well.
LC_ALL=C
PATH=/usr/bin:/bin
bail() { echo "FATAL: $1"; exit 1; }
grep --version > /dev/null 2> /dev/null || bail "grep does not work"
sed '' /dev/null || bail "sed does not work"
sort /dev/null || bail "sort does not work"
ver_check()
{
if ! type -p $2 &>/dev/null
then
echo "ERROR: Cannot find $2 ($1)"; return 1;
fi
v=$($2 --version 2>&1 | grep -E -o '[0-9]+\.[0-9\.]+[a-z]*' | head -n1)
if printf '%s\n' $3 $v | sort --version-sort --check &>/dev/null
then
printf "OK: %-9s %-6s >= $3\n" "$1" "$v"; return 0;
else
printf "ERROR: %-9s is TOO OLD ($3 or later required)\n" "$1";
return 1;
fi
}
ver_kernel()
{
kver=$(uname -r | grep -E -o '^[0-9\.]+')
if printf '%s\n' $1 $kver | sort --version-sort --check &>/dev/null
then
printf "OK: Linux Kernel $kver >= $1\n"; return 0;
else
printf "ERROR: Linux Kernel ($kver) is TOO OLD ($1 or later required)\n" "$kver";
return 1;
fi
}
# Coreutils first because --version-sort needs Coreutils >= 7.0
ver_check Coreutils sort 8.1 || bail "Coreutils too old, stop"
ver_check Bash bash 3.2
ver_check Binutils ld 2.13.1
ver_check Bison bison 2.7
ver_check Diffutils diff 2.8.1
ver_check Findutils find 4.2.31
ver_check Gawk gawk 4.0.1
ver_check GCC gcc 5.2
ver_check "GCC (C++)" g++ 5.2
ver_check Grep grep 2.5.1a
ver_check Gzip gzip 1.3.12
ver_check M4 m4 1.4.10
ver_check Make make 4.0
ver_check Patch patch 2.5.4
ver_check Perl perl 5.8.8
ver_check Python python3 3.4
ver_check Sed sed 4.1.5
ver_check Tar tar 1.22
ver_check Texinfo texi2any 5.0
ver_check Xz xz 5.0.0
ver_kernel 4.19
if mount | grep -q 'devpts on /dev/pts' && [ -e /dev/ptmx ]
then echo "OK: Linux Kernel supports UNIX 98 PTY";
else echo "ERROR: Linux Kernel does NOT support UNIX 98 PTY"; fi
alias_check() {
if $1 --version 2>&1 | grep -qi $2
then printf "OK: %-4s is $2\n" "$1";
else printf "ERROR: %-4s is NOT $2\n" "$1"; fi
}
echo "Aliases:"
alias_check awk GNU
alias_check yacc Bison
alias_check sh Bash
echo "Compiler check:"
if printf "int main(){}" | g++ -x c++ -
then echo "OK: g++ works";
else echo "ERROR: g++ does NOT work"; fi
rm -f a.out
if [ "$(nproc)" = "" ]; then
echo "ERROR: nproc is not available or it produces empty output"
else
echo "OK: nproc reports $(nproc) logical cores are available"
fi
EOF
bash version-check.shcat > version-check.sh << "EOF"
#!/bin/bash
# A script to list version numbers of critical development tools
# If you have tools installed in other directories, adjust PATH here AND
# in ~lfs/.bashrc (section 4.4) as well.
LC_ALL=C
PATH=/usr/bin:/bin
bail() { echo "FATAL: $1"; exit 1; }
grep --version > /dev/null 2> /dev/null || bail "grep does not work"
sed '' /dev/null || bail "sed does not work"
sort /dev/null || bail "sort does not work"
ver_check()
{
if ! type -p $2 &>/dev/null
then
echo "ERROR: Cannot find $2 ($1)"; return 1;
fi
v=$($2 --version 2>&1 | grep -E -o '[0-9]+\.[0-9\.]+[a-z]*' | head -n1)
if printf '%s\n' $3 $v | sort --version-sort --check &>/dev/null
then
printf "OK: %-9s %-6s >= $3\n" "$1" "$v"; return 0;
else
printf "ERROR: %-9s is TOO OLD ($3 or later required)\n" "$1";
return 1;
fi
}
ver_kernel()
{
kver=$(uname -r | grep -E -o '^[0-9\.]+')
if printf '%s\n' $1 $kver | sort --version-sort --check &>/dev/null
then
printf "OK: Linux Kernel $kver >= $1\n"; return 0;
else
printf "ERROR: Linux Kernel ($kver) is TOO OLD ($1 or later required)\n" "$kver";
return 1;
fi
}
# Coreutils first because --version-sort needs Coreutils >= 7.0
ver_check Coreutils sort 8.1 || bail "Coreutils too old, stop"
ver_check Bash bash 3.2
ver_check Binutils ld 2.13.1
ver_check Bison bison 2.7
ver_check Diffutils diff 2.8.1
ver_check Findutils find 4.2.31
ver_check Gawk gawk 4.0.1
ver_check GCC gcc 5.2
ver_check "GCC (C++)" g++ 5.2
ver_check Grep grep 2.5.1a
ver_check Gzip gzip 1.3.12
ver_check M4 m4 1.4.10
ver_check Make make 4.0
ver_check Patch patch 2.5.4
ver_check Perl perl 5.8.8
ver_check Python python3 3.4
ver_check Sed sed 4.1.5
ver_check Tar tar 1.22
ver_check Texinfo texi2any 5.0
ver_check Xz xz 5.0.0
ver_kernel 4.19
if mount | grep -q 'devpts on /dev/pts' && [ -e /dev/ptmx ]
then echo "OK: Linux Kernel supports UNIX 98 PTY";
else echo "ERROR: Linux Kernel does NOT support UNIX 98 PTY"; fi
alias_check() {
if $1 --version 2>&1 | grep -qi $2
then printf "OK: %-4s is $2\n" "$1";
else printf "ERROR: %-4s is NOT $2\n" "$1"; fi
}
echo "Aliases:"
alias_check awk GNU
alias_check yacc Bison
alias_check sh Bash
echo "Compiler check:"
if printf "int main(){}" | g++ -x c++ -
then echo "OK: g++ works";
else echo "ERROR: g++ does NOT work"; fi
rm -f a.out
if [ "$(nproc)" = "" ]; then
echo "ERROR: nproc is not available or it produces empty output"
else
echo "OK: nproc reports $(nproc) logical cores are available"
fi
EOF
bash version-check.sh
새 파티션 생성
전용 파티션에 설치된다. 빈 파티션이나, 파티션 되지 않은 공간이 충분할 경우 파티션을 생성
- 최소 10GB 의 파티션이 필요 : tarball 을 저장하고 패키지를 컴파일하기에 충분한 공간.
- 최소 30GB 의 파티션이 필요 : LFS 를 기본 Linux 시스템으로 사용하는 경우 추가 소프트웨어가 필요할 수 있음.
새 파티션이 생성될 하드 디스크의 이름을 지정하는 명령줄 옵션을 사용하여 cfdisk
또는 fdisk
과 같은 파티션 프로그램 실행하여 /dev/sda
파티션 생성 ( LFS 파티션이라고도 부름 )
-
root
(20GB 이상),swap
(RAM 크기의 두배 권장이나 최소 2GB 도 무난) 파티션도 생성 - 가능하면
swap
은 SSD 를 사용하지 않는 것이 놓음. -
Grub
파티션 : 부팅 시스크가 GPT (GUID 파티션 테이블) 로 파티션된 경우 작은 파티션이 아직 없으면 만들어야 하여 부트로더 설치 중에 GRUB 에서 사용할 수 있어야 함. 보통BIOS Boot
로 표시하고gdisk
를 사용하는 경우EF02
코드로 확인 - Convenience 파티션 : 필수는 아니지만 디스크 레이아웃을 설계할 때 고려할 파티션들
-
/boot
: 커널 및 기타 부팅 정보 저장 (200MB) -
/boot/efi
: UEFI 로 시스템 부팅시 필요한 파티션 -
/home
: 여러 배포판이나 LFS 빌드에서 홈 디렉토리와 사용자 정의를 공유 -
/usr
: LFS 에서/lib, /bin, /sbin
등에 대한 심볼릭 링크, 시스템의 모든 프로그램과 라이브러리를 수용할 수 있을 만큼 커야 함. (1GB) -
/opt
:/usr
계층 구조에 파일을 포함하지 않고KDE, Texlive
와 같은 대형 패키지를 설치 (5~10GB) -
/tmp
: 씬 클라이언트를 구성하는 경우 유용, ( 2 GB 이하 ) -
/usr/src
: LFS 빌드에서 공유할 위치를 제공하는 데 유용. (30 ~ 50GB)
-
시스템 시작시 자동으로 마운트하려는 별도의 파티션을 /etc/fstab
에 저장해야 함.
파티션에 파일 시스템 생성
- 파티션 : 파티션 테이블에 설정된 경계로 구분되는 디스크 드라이브의 섹터 범위
- 운영체제가 필요한 파티션 : 레이블, 디렉터리 블록, 데이터 블록 및 요청 시 특정 파일을 찾기 위한 인덱싱 체계로 구성된 파일 시스템을 포함하도록 파티션을 포맷
- 모든 파일 시스템을 사용할 수 있지만 가장 일반적인 유형은
ext3
및ext4
-
ext2
:/boot
와 같이 자주 업데이트되지 않는 작은 파티션에 적합합니다. -
ext3
: 범용 파일 시스템으로 사용,ext2
에서 비정상적으로 종료된 경우 파티션 상태를 복구하는 데 도움이 되는 저널이 포함되도록 업그레이드 -
ext4
: 나노초 타임스탬프, 초대형 파일(최대 16TB) 생성 및 사용, 속도 향상 등 여러 가지 새로운 기능을 제공
# 파일 시스템 생성
mkfs -v -t ext4 /dev/<xxx>
# swap 파티션 초기화
mkswap /dev/<yyy>
$LBS 변수 설정
LFS 시스템을 구축할 디렉터리 이름으로 설정
export LFS=/mnt/lfs
새 파티션 마운트
파일 시스템을 통해서 마운트
mkdir -pv $LFS
mount -v -t ext4 /dev/<xxx> $LFS
활성화 되어 있는지 확인
/sbin/swapon -v /dev/<zzz>
패키지 및 패치
- 기본 Linux 시스템을 구축하기 위해 다운로드 해야 하는 패키지 목록
- 통상적으로
$LFS/sources
에 저장
mkdir -v $LFS/sources
chmod -v a+wt $LFS/sources
- https://www.linuxfromscratch.org/mirrors.html#files 의 미러 사이트 중에서 다운로드 가능
wget --input-file=wget-list-sysv --continue --directory-prefix=$LFS/sources
pushd $LFS/sources
md5sum -c md5sums
popd
chown root:root $LFS/sources/*
- 패키지 : https://www.linuxfromscratch.org/lfs/view/stable/chapter03/packages.html
- 패치 : https://www.linuxfromscratch.org/lfs/view/stable/chapter03/patches.html
기타 시스템 구축 준비 과정
- LFS 파일 시스템에서 제한된 디렉토리 레이아웃 생성, 최종 버전이 빌드될 때 임시 프로그램을 덮어쓸 수 있음.
mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin}
for i in bin lib sbin; do
ln -sv usr/$i $LFS/$i
done
case $(uname -m) in
x86_64) mkdir -pv $LFS/lib64 ;;
esac
# 크로스 컴파일이 가능하도록 tools 생성
mkdir -pv $LFS/tools
LFS 사용자 추가
root
로 로그인하면 단 한번의 실수로 시스템이 손상될 수 있어 별도의 사용자를 추가하여 사용
groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
# -s /bin/bash : 기본 쉘 설정
# -g lfs : 그룹 지정
# -m : 홈 디렉터리 생성
# -k /dev/null : 기본 디렉터리에서 파일을 복사하는 것을 방지
# lfs : 새 사용자의 이름
# 패스워드 설정
passwd lfs
# 사용할 수 있도록 권한 부여
chown -v lfs $LFS/{usr{,/*},lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown -v lfs $LFS/lib64 ;;
esac
# 로그인
su - lfs
환경 설정
Bash 쉘을 위한 두 개의 새로운 시작 파일 생성
cat > ~/.bash_profile << "EOF"
`exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash`
EOF
lfs
로 로그인하게 되면 bash_profile
을 읽고 명령을 실행하게 됩니다. 위 명령은 실행 중인 셀의 변수를 제외하고 환경이 완전히 비어 있는 새 쉘로 바꿉니다.
bashrc
는 비로그인쉘로 /etc/profile
과 .bash_profile
을 실행하지 않고 로그인하는 경우 사용됩니다.
cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE
EOF
임시 도구를 구축하기 위한 환경이 완전히 준비되었는지 확인하기 위해서 다음과 같이 설정합니다.
source ~/.bash_profile
SBU 정보
컴파일하고 설치하는 데 걸리는 시간을 SBS(Standard Build Unit) 을 통하여 알 수 있습니다. 맨 처음 컴파일하는 패키지는 binutils
인데 이것을 기준으로 시간단위가 표현됩니다.
Test Suites
대부분의 패키지는 test suites
를 제공합니다. 일부 테스트는 다른 테스트보다 더 중요한데, GCC, binutils, glibc
가 그렇습니다.
binutils
및 GCC
의 test suite
를 실행할 때 pseudo terminals(PTY)
가 부족할 수 있는데, 그 경우는 devpts
파일 시스템이 올바르게 설정되지 않았기 때문입니다.
Toolchain 기술 노트
크로스 컴파일
- build : 프로그램을 작성하는 기계
- host : 빌드된 프로그램이 실행될 기계/시스템입니다.
- target : 컴파일러에만 사용됩니다. 컴파일러가 코드를 생성하는 기계입니다.
LFS 에서는 autoconf
기반 빌드 시스템을 사용하여 크로스 컴파일 합니다. LFS 에서 크로스 컴파일과 같이 구성하기 위해서 변수의 verdor
필드를 lfs
라고 표시한다.
--with-sysroot
를 사용하여 크로스 링커와 크로스 컴파일러를 구축할 때 필요한 호스트 파일을 찾을 수 있는 위치를 알려주기 위해 옵션을 사용합니다.
크로스 컴파일러는 의 최종 시스템의 일부가 아니기 때문에 $LFS/tools
디렉터리에 설치됩니다.
일반 컴파일 지침
각 패키지를 빌드하는 데 대해 알아야 할 몇 가지 사항입니다.
- 여러 패키지가 컴파일 전에 패치되지만 문제를 회피하기 위해 패치가 필요한 경우에만 패치됩니다.
- 대부분의 패키지를 컴파일 하는 동안 일부 경고가 화면에 스크롤됩니다. (일반적인 현상)
- LFS 환경변수를 확인합니다.
echo $LFS
첫번째 크로스 툴체인 컴파일
Binutils 문서에서는 전용 빌드 디렉터리에 Binutils를 빌드할 것을 권장합니다.
mkdir -v build
cd build
../configure --prefix=$LFS/tools \
--with-sysroot=$LFS \
--target=$LFS_TGT \
--disable-nls \
--enable-gprofng=no \
--disable-werror \
--enable-default-hash-style=gnu
-
--prefix
:$LFS/tools
디렉토리에 Binutils 프로그램 설치를 준비하도록 지시합니다. -
--with-sysroot
: 크로스 컴파일의 경우 빌드 시스템이 필요에 따라$LFS
에서 대상 시스템 라이브러리를 찾도록 지시합니다. -
--target
:$LFS_TGT
변수의 시스템 설명이 config.guess 스크립트에서 반환된 값과 약간 다르기 때문에configure
스크립트에서 크로스 링커 구축을 위해binutil
빌드 시스템을 조정하도록 지시합니다. -
--disable-nls
: 임시 도구에는i18n
이 필요하지 않아 국제화를 비활성화 합니다. -
--enable-gprofng=no
: 임시 도구에는 필요하지 않은gprofng
빌드가 비활성화됩니다. -
disable-werror
: 호스트 컴파일러에서 경고가 발생하는 경우 빌드가 중지되는 것을 방지할 수 있습니다. -
--enable-default-hash-style=gnu
: 해시 테이블은 동적 링커가 기호 조회를 수행하는 용도에 사용되는데 LFS 에서 동적 링커는 항상 쿼리 속도 가 더 빠른 GNU 스타일 해시 테이블을 사용할 수 있도록 합니다.
make
make install
이런식으로 각 패캐지에서 설명하는 크로스 툴체인을 컴파일합니다.
크로스 툴체인으로 기본 유틸리티 크로스 컴파일
기본 유틸리티 중 M4-1.4.19 크로스 컴파일
./configure --prefix=/usr \
--host=$LFS_TGT \
--build=$(build-aux/config.guess)
make
make DESTDIR=$LFS install
Chroot 입력 및 추가 임시도구 구축
다양한 패키지를 빌드하는 데 필요한 도구를 빌드하기 위해 chroot 설정 (순환 종속성 제거)
- 소유권 변경
chown -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown -R root:root $LFS/lib64 ;;
esac
- 가상의 파일 시스템 준비
mkdir -pv $LFS/{dev,proc,sys,run}
mount -v --bind /dev $LFS/dev
mount -vt devpts devpts -o gid=5,mode=0620 $LFS/dev/pts
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
mount -vt tmpfs tmpfs $LFS/run
- 심볼링 링크 디렉터리 생성
if [ -h $LFS/dev/shm ]; then
install -v -d -m 1777 $LFS$(realpath /dev/shm)
else
mount -vt tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm
fi
- chroot 환경 접속
chroot "$LFS" /usr/bin/env -i \ # 모든 환경 변수 삭제
HOME=/root \
TERM="$TERM" \
PS1='(lfs chroot) \u:\w\$ ' \
PATH=/usr/bin:/usr/sbin \
MAKEFLAGS="-j$(nproc)" \
TESTSUITEFLAGS="-j$(nproc)" \ # nproc (코어 수)
/bin/bash --login
- 디렉토리 생성
LFS 파일 시스템에 전체 디렉토리 구조를 생성
mkdir -pv /{boot,home,mnt,opt,srv}
mkdir -pv /etc/{opt,sysconfig} (데비안/우분투는 /etc/default)
mkdir -pv /lib/firmware
mkdir -pv /media/{floppy,cdrom}
mkdir -pv /usr/{,local/}{include,src}
mkdir -pv /usr/local/{bin,lib,sbin}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
mkdir -pv /var/{cache,local,log,mail,opt,spool}
mkdir -pv /var/lib/{color,misc,locate}
ln -sfv /run /var/run
ln -sfv /run/lock /var/lock
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
- 필수 파일 및 Symlink 생성
# find 를 기대하는 유틸리티를 만족시키려면 /etc/mtab 심볼릭 링크 생성
ln -sv /proc/self/mounts /etc/mtab
# 기본 /etc/hosts 생성
cat > /etc/hosts << EOF
`127.0.0.1 localhost $(hostname) ::1 localhost`
EOF
# 기본 /etc/passwd, /etc/group 생성
cat > /etc/passwd << "EOF"
`root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/dev/null:/usr/bin/false daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false`
EOF
cat > /etc/group << "EOF"
`root:x:0: bin:x:1:daemon sys:x:2: kmem:x:3: tape:x:4: tty:x:5: daemon:x:6: floppy:x:7: disk:x:8: lp:x:9: dialout:x:10: audio:x:11: video:x:12: utmp:x:13: cdrom:x:15: adm:x:16: messagebus:x:18: input:x:24: mail:x:34: kvm:x:61: uuidd:x:80: wheel:x:97: users:x:999: nogroup:x:65534:`
EOF
# 테스트시 필요한 사용자 지정, 테스트 후 삭제
echo "tester:x:101:101::/home/tester:/bin/bash" >> /etc/passwd
echo "tester:x:101:" >> /etc/group
install -o tester -d /home/tester
# 로그인 로그 기록 생성
touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664 /var/log/lastlog
chmod -v 600 /var/log/btmp
- 유틸리티 설치
# Gettext-0.22.4
./configure --disable-shared
make
cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin
등 Bison
, Perl
, Python
, Texinfo
, Util-linux
설치
- 임시 시스템 정리 및 저장
rm -rf /usr/share/{info,man,doc}/*
find /usr/{lib,libexec} -name \*.la -delete
rm -rf /tools
# chroot logout
exit
# unmount
mountpoint -q $LFS/dev/shm && umount $LFS/dev/shm
umount $LFS/dev/pts
umount $LFS/{sys,proc,run,dev}
# backup archive
cd $LFS
tar -cJpf $HOME/lfs-temp-tools-12.1.tar.xz .
# 실수가 있어 복원 시
cd $LFS
rm -rf ./*
tar -xpf $HOME/lfs-temp-tools-12.1.tar.xz
기본 시스템 소프트웨어 설치
- 패키지 관리 : 파일 설치를 추적하여 패키지를 더 쉽게 제거하고 업그레이드할 수 있도록 함.
- 패키지 관리자를 사용하면 최신 버전이 출시될 때 쉽게 업그레이드 할 수 있음.
- 패키지 관리 기술 : 별도의 디렉터리, symlink, 타임스탬프, 설치 스크립트 추적, 패키지 아카이브 생성, 사용자 기반 관리 등 여러 패키지 관리 기술이 있음.
- 여러 시스템에 LFS 배포 : root 파티션에 tar 를 풀어서 설치하고 몇가지 기본 파일(
/etc/hosts
등)만 수정하면 된다.
- Man-pages-6.06
rm -v man3/crypt*
make prefix=/usr install
- 2와 같이 여러 기본 시스템 소프트웨어 설치
- 기타 옵션 :
- stripping : 바이너리 및 라이브러리에서 디버깅 기호와 일부 불필요한 기호 테이블 항목을 제거, 다시 수행 시 처리 중인 바이너리 또는 라이브러리를 덮어 쓸 수 있으므로 복사 후 다시 설치할 수 있도록 하자
save_usrlib="$(cd /usr/lib; ls ld-linux*[^g])
libc.so.6
libthread_db.so.1
libquadmath.so.0.0.0
libstdc++.so.6.0.32
libitm.so.1.0.0
libatomic.so.1.2.0"
cd /usr/lib
# 임시 복사
for LIB in $save_usrlib; do
objcopy --only-keep-debug --compress-debug-sections=zlib $LIB $LIB.dbg
cp $LIB /tmp/$LIB
strip --strip-unneeded /tmp/$LIB
objcopy --add-gnu-debuglink=$LIB.dbg /tmp/$LIB
install -vm755 /tmp/$LIB /usr/lib
rm /tmp/$LIB
done
online_usrbin="bash find strip"
online_usrlib="libbfd-2.42.so
libsframe.so.1.0.0
libhistory.so.8.2
libncursesw.so.6.4-20230520
libm.so.6
libreadline.so.8.2
libz.so.1.3.1
libzstd.so.1.5.5
$(cd /usr/lib; find libnss*.so* -type f)"
# --strip-unneeded : 모든 디버깅 기호 제거
for BIN in $online_usrbin; do
cp /usr/bin/$BIN /tmp/$BIN
strip --strip-unneeded /tmp/$BIN
install -vm755 /tmp/$BIN /usr/bin
rm /tmp/$BIN
done
for LIB in $online_usrlib; do
cp /usr/lib/$LIB /tmp/$LIB
strip --strip-unneeded /tmp/$LIB
install -vm755 /tmp/$LIB /usr/lib
rm /tmp/$LIB
done
for i in $(find /usr/lib -type f -name \*.so* ! -name \*dbg) \
$(find /usr/lib -type f -name \*.a) \
$(find /usr/{bin,sbin,libexec} -type f); do
case "$online_usrbin $online_usrlib $save_usrlib" in
*$(basename $i)* )
;;
* ) strip --strip-unneeded $i
;;
esac
done
unset BIN LIB save_usrlib online_usrbin online_usrlib
- Clean up
rm -rf /tmp/*
find /usr/lib /usr/libexec -name \*.la -delete
find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf
userdel -r tester
게이트웨이 On-promise 제품 팀에서 시스템 모니터링 및 관리를 쉽게 다가갈 수 있도록 하기 위한 업무를 하고 있습니다.
Contact: lhjnano@gmail.com