LFS 의 개념 공부

2024/12/13 LFS 총 16264 자,약 47 문장

LFS

소프트웨어 구축 HOW-TO
  1. 소프트웨어 패키지 다운로드
  2. 소프트웨어 압축 풀기 : tar zvf filename ( .gz.tag / .bz2 )
  3. 설치 지침 확인 후 소프트웨어 설치 : make install
    1. 패치 파일이 있다면 patch < patch file 수행
  4. Makefile : 바이너리를 컴파일 하거나 빌드하기 위한 스크립트
    1. make : 통상적인 모든 실행파일 빌드
    2. make install : 적절한 디렉터리에 설치
    3. make clean : 오래된 object 파일 제거
    4. make -n : 빌드하지 않고 트리거되는 모든 명령 인쇄
    5. IMakefile : Makefile 템플릿, xmkmf -a 로 Makefile, include, depend 생성
    6. configure : 디렉터리의 올바른 스크립트 호출 유도
    7. /usr/bin, /usr/local/bin 에 설치됨.
    8. 상용버전은 /opt 에 설치됨.
  5. 사전 패키지된 바이너리
    1. rpm / debtarbals 에 비해 느리게 출시된다.
    2. tarball 은 더 완전하고, 많은 옵션을 가질 수 있다.
    3. rpm --recompile packagename.rpm / rpm --rebuild packagename.rpm 등으로 tarball 과 같이 빌드하고, 설치할 수 있다.
    4. 일부 사전 패키지는 제대로 설치되지 않고, 충돌이나 덤프가 발생할 수 있다.
    5. 설치하기 전에 rpm --checksig packagename.rpm 에서 대조 확인을 하고 실행해야 한다.
  6. Termcap 및 Terminfo 이슈
    1. Terminfo 는 Termcap, termlib 를 대체, 터미널을 설명하는 데이터 베이스
    2. 아주 드물게 레거시의 경우 Termcap 링크 바이러리를 사용하는경우 #define termcap 을 주석 처리해야 할 수도 있음.
  7. a.out 바이너리와의 하위 호환성
    1. 드물게 새로운 ELF 바이너리를 빌드하는 것이 불가능한 경우 a.out 을 사용할 수도 있다.
    2. /usr/i486-linuxaout/lib 에 있는 a.out 라이브러리는 ELF 설치의 거의 모든 것을 가지고 있다.
    3. 가끔 a.out 을 로드 가능하게 하게 커널을 다시 빌드해야 할 수도 있다.
    4. 샘플
# /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
  1. 그 밖의 이슈 처리
    1. 링크 오류 ( No such file or direcotry ) : LIB, INCLUDE, LIBS 를 확인
    2. 링크 오류 ( cos 등 수학 라이브러리 ) : LIB, LIBS 등에 -lm 추가
    3. xmkmf 실패 : 다른 방법으로 시도 ( make -DUseInstalled -I/usr/X386/lib/X11/config )
    4. X11R5 라이브러리가 필요한 경우 : 링크 연결 (ln -s libX11.so.3.1.0 libX11.so)
    5. Perl, Shell 스크립트가 No such file or directory : perl 설치 위치 확인 (/usr/local/bin (0) , /usr/bin (X) )
    6. ./configure 를 호출하지 않으면 이상하게 구성될 수 있음.
    7. 배포판 라이브러리 버전을 업그레이드안 경우 미리 컴파일된 바이너리가 터질 수 있음.
    8. .NET 컴파일시 -ansi 옵션을 제거해야 하는 경우도 있음.
    9. 일부 프로그램은 루트 권한으로 실행하려면 setuid root 가 필요함. (보안 이슈가 있을 수도 있음.)
    10. Makefile 옵션들(gcc)
      1. -O2 : 최적화
      2. -fomit-frame-pointer 더 작은 바이너리 생성
  2. .bashrc : 특정 환경 변수 설정
  3. .Xdefaults / .Xresources : 사용자 정의
  4. ~~~.ad 사용자 정의 후 /usr/lib/X11/app-defaults 에 설치
  5. 소스 아카이브 찾는 곳
    1. Redhat support
    2. InfoMagic
    3. comp 소스 UNIX 아카이브
소스에서 설치하기 좋은 초보자 가이드
  • 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 시스템 구축 방법
  1. 새로운 LFS 시스템 컴파일 , 설치될 Linux 기본 파티션 및 파일 시스템 생성
  2. LFS 시스템 구축하기 위한 패키지 및 패치 다운로드
  3. 파일 시스템에 저장하는 방법
  4. 작업 환경 설정
  5. 작업 시작전 알아야 할 사항
  6. 크로스 컴파일 기술을 사용하여 호스트 시스템에서 새 도구를 분리하는 초기 도구 체인 설치
  7. 크로스 툴체인을 사용하여 기본 유틸리티 크로스 컴파일
  8. 새로운 도구를 사용하여 LFS 시스템을 만드는데 필요한 나머지 도구 구축하는 chroot
  9. LFS 시스템 구축
  10. 기본 시스템 구성
  11. 커널과 부트로더 생성
호스트 시스템 요구사항
  1. 하드웨어 : 4 core CPU, 8 GB Ram
  2. 소프트웨어 : 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
  1. LFS 환경 변수에 FOR THE ROOT USER 로 설정
  2. 다 있는지 확인하려면 다음을 실행
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 에 저장해야 함.

파티션에 파일 시스템 생성
  • 파티션 : 파티션 테이블에 설정된 경계로 구분되는 디스크 드라이브의 섹터 범위
  • 운영체제가 필요한 파티션 : 레이블, 디렉터리 블록, 데이터 블록 및 요청 시 특정 파일을 찾기 위한 인덱싱 체계로 구성된 파일 시스템을 포함하도록 파티션을 포맷
  • 모든 파일 시스템을 사용할 수 있지만 가장 일반적인 유형은 ext3ext4
  • 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 가 그렇습니다.

binutilsGCCtest 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 설정 (순환 종속성 제거)

  1. 소유권 변경
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
  1. 가상의 파일 시스템 준비
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
  1. 심볼링 링크 디렉터리 생성
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
  1. 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
  1. 디렉토리 생성

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
  1. 필수 파일 및 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
  1. 유틸리티 설치
# Gettext-0.22.4

./configure --disable-shared
make
cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin

Bison, Perl, Python, Texinfo, Util-linux 설치

  1. 임시 시스템 정리 및 저장
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
기본 시스템 소프트웨어 설치
  1. 패키지 관리 : 파일 설치를 추적하여 패키지를 더 쉽게 제거하고 업그레이드할 수 있도록 함.
  • 패키지 관리자를 사용하면 최신 버전이 출시될 때 쉽게 업그레이드 할 수 있음.
  • 패키지 관리 기술 : 별도의 디렉터리, symlink, 타임스탬프, 설치 스크립트 추적, 패키지 아카이브 생성, 사용자 기반 관리 등 여러 패키지 관리 기술이 있음.
  • 여러 시스템에 LFS 배포 : root 파티션에 tar 를 풀어서 설치하고 몇가지 기본 파일(/etc/hosts 등)만 수정하면 된다.
  1. Man-pages-6.06
rm -v man3/crypt*
make prefix=/usr install
  1. 2와 같이 여러 기본 시스템 소프트웨어 설치
  2. 기타 옵션 :
    1. 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
  1. 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
HeonJe Lee | 선임연구원
게이트웨이 On-promise 제품 팀에서 시스템 모니터링 및 관리를 쉽게 다가갈 수 있도록 하기 위한 업무를 하고 있습니다.

Contact: lhjnano@gmail.com

Search

    Table of Contents