简体中文 繁體中文 English Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français Japanese

站内搜索

搜索

活动公告

04-22 00:04
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

CentOS Stream源代码编译实战教程 手把手教你掌握编译技能

SunJu_FaceMall

3万

主题

1503

科技点

3万

积分

白金月票

碾压王

积分
32796

立华奏

发表于 2025-9-2 20:30:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. CentOS Stream简介

CentOS Stream是Red Hat Enterprise Linux (RHEL)的上游开发平台,它位于Fedora和RHEL之间。与传统的CentOS不同,CentOS Stream提供了一个滚动更新的版本,让用户可以提前体验到未来RHEL版本中的功能和更新。对于开发者和系统管理员来说,掌握CentOS Stream的源代码编译技能至关重要,这不仅可以帮助你定制系统,还能让你深入理解Linux系统的工作原理。

CentOS Stream采用开放的开发模式,所有的源代码都是公开的,这为用户提供了极大的灵活性和透明度。通过编译源代码,你可以:

• 优化软件以适应特定的硬件环境
• 获取最新功能,而不必等待官方发布
• 修复安全漏洞或错误
• 学习软件内部工作原理

2. 编译环境准备

在开始编译源代码之前,我们需要准备一个合适的编译环境。以下步骤将指导你完成环境的搭建。

2.1 系统更新

首先,确保你的CentOS Stream系统是最新的:
  1. sudo dnf update -y
复制代码

2.2 安装开发工具组

CentOS Stream提供了一个方便的”Development Tools”软件包组,它包含了编译软件所需的基本工具:
  1. sudo dnf groupinstall "Development Tools" -y
复制代码

这个命令会安装GCC编译器、make工具、autoconf、automake等基本开发工具。

2.3 安装必要的库和头文件

许多软件在编译过程中需要特定的库和头文件。以下是一些常用的开发库:
  1. sudo dnf install -y \
  2.     glibc-devel \
  3.     openssl-devel \
  4.     zlib-devel \
  5.     readline-devel \
  6.     libcurl-devel \
  7.     expat-devel \
  8.     gettext-devel
复制代码

2.4 设置编译环境变量

为了确保编译过程顺利进行,建议设置一些环境变量。编辑你的~/.bashrc或~/.bash_profile文件:
  1. cat >> ~/.bashrc << EOF
  2. # 编译环境变量
  3. export CC=gcc
  4. export CXX=g++
  5. export MAKEFLAGS="-j$(nproc)"
  6. EOF
  7. source ~/.bashrc
复制代码

这里,MAKEFLAGS="-j$(nproc)"会设置make使用所有可用的CPU核心进行并行编译,大大加快编译速度。

3. 源代码获取方法

在CentOS Stream中,有几种获取源代码的方法,我们将逐一介绍。

3.1 使用dnf下载源代码包

CentOS Stream的DNF包管理器可以直接下载源代码RPM包:
  1. # 启用源代码仓库
  2. sudo dnf install -y dnf-plugins-core
  3. sudo dnf config-manager --enable crb
  4. # 下载特定软件的源代码
  5. dnf download --source <package-name>
  6. # 例如,下载nginx的源代码
  7. dnf download --source nginx
复制代码

3.2 使用git克隆源代码仓库

对于许多开源项目,可以直接从其Git仓库获取最新源代码:
  1. # 安装git
  2. sudo dnf install -y git
  3. # 克隆仓库
  4. git clone <repository-url>
  5. # 例如,克隆Linux内核源代码
  6. git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
复制代码

3.3 从官方网站下载源代码

许多软件项目在其官方网站提供源代码压缩包:
  1. # 使用wget下载
  2. wget <source-code-url>
  3. # 例如,下载Python源代码
  4. wget https://www.python.org/ftp/python/3.10.6/Python-3.10.6.tgz
  5. # 解压
  6. tar -xvf Python-3.10.6.tgz
  7. cd Python-3.10.6
复制代码

4. 基本编译流程

大多数开源软件遵循类似的编译流程,通常包括配置、编译和安装三个主要步骤。

4.1 autotools项目编译流程

使用autotools(autoconf、automake等)的项目通常遵循以下编译流程:
  1. # 1. 进入源代码目录
  2. cd <source-directory>
  3. # 2. 运行configure脚本(如果不存在,先运行autogen.sh或./bootstrap)
  4. ./configure --prefix=/usr/local --sysconfdir=/etc --with-<feature>
  5. # 3. 编译
  6. make
  7. # 4. 可选:运行测试套件
  8. make check
  9. # 5. 安装
  10. sudo make install
复制代码

configure脚本接受多种参数,可以使用./configure --help查看所有可用选项。常见的选项包括:

• --prefix:指定安装目录
• --sysconfdir:指定配置文件目录
• --enable-<feature>:启用特定功能
• --disable-<feature>:禁用特定功能
• --with-<package>:使用特定的外部包
• --without-<package>:不使用特定的外部包

4.2 CMake项目编译流程

使用CMake的项目编译流程略有不同:
  1. # 1. 进入源代码目录
  2. cd <source-directory>
  3. # 2. 创建构建目录
  4. mkdir build && cd build
  5. # 3. 运行cmake配置
  6. cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -D<feature>=ON
  7. # 4. 编译
  8. make
  9. # 5. 可选:运行测试
  10. make test
  11. # 6. 安装
  12. sudo make install
复制代码

4.3 Meson项目编译流程

使用Meson构建系统的项目编译流程如下:
  1. # 1. 进入源代码目录
  2. cd <source-directory>
  3. # 2. 创建构建目录
  4. mkdir build && cd build
  5. # 3. 运行meson配置
  6. meson .. --prefix=/usr/local -D<feature>=true
  7. # 4. 编译
  8. ninja
  9. # 5. 可选:运行测试
  10. ninja test
  11. # 6. 安装
  12. sudo ninja install
复制代码

5. 实战案例:编译Nginx

让我们通过一个实际的例子来演示如何在CentOS Stream上编译Nginx Web服务器。

5.1 安装依赖

首先,安装Nginx编译所需的依赖:
  1. sudo dnf install -y \
  2.     pcre-devel \
  3.     zlib-devel \
  4.     openssl-devel \
  5.     libxslt-devel \
  6.     gd-devel \
  7.     perl-ExtUtils-Embed \
  8.     geoip-devel
复制代码

5.2 下载源代码

从Nginx官方网站下载最新的源代码:
  1. cd ~
  2. wget https://nginx.org/download/nginx-1.23.3.tar.gz
  3. tar -xvf nginx-1.23.3.tar.gz
  4. cd nginx-1.23.3
复制代码

5.3 配置编译选项

Nginx提供了许多模块,我们可以根据需要选择启用或禁用:
  1. ./configure \
  2.     --prefix=/etc/nginx \
  3.     --sbin-path=/usr/sbin/nginx \
  4.     --modules-path=/usr/lib64/nginx/modules \
  5.     --conf-path=/etc/nginx/nginx.conf \
  6.     --error-log-path=/var/log/nginx/error.log \
  7.     --http-log-path=/var/log/nginx/access.log \
  8.     --pid-path=/var/run/nginx.pid \
  9.     --lock-path=/var/run/nginx.lock \
  10.     --http-client-body-temp-path=/var/cache/nginx/client_temp \
  11.     --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
  12.     --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
  13.     --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
  14.     --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
  15.     --user=nginx \
  16.     --group=nginx \
  17.     --with-compat \
  18.     --with-file-aio \
  19.     --with-threads \
  20.     --with-http_addition_module \
  21.     --with-http_auth_request_module \
  22.     --with-http_dav_module \
  23.     --with-http_flv_module \
  24.     --with-http_gunzip_module \
  25.     --with-http_gzip_static_module \
  26.     --with-http_mp4_module \
  27.     --with-http_random_index_module \
  28.     --with-http_realip_module \
  29.     --with-http_secure_link_module \
  30.     --with-http_slice_module \
  31.     --with-http_ssl_module \
  32.     --with-http_stub_status_module \
  33.     --with-http_sub_module \
  34.     --with-http_v2_module \
  35.     --with-mail \
  36.     --with-mail_ssl_module \
  37.     --with-stream \
  38.     --with-stream_realip_module \
  39.     --with-stream_ssl_module \
  40.     --with-stream_ssl_preread_module \
  41.     --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'
复制代码

5.4 编译和安装
  1. # 编译
  2. make -j$(nproc)
  3. # 安装
  4. sudo make install
复制代码

5.5 创建systemd服务文件

为了方便管理Nginx,创建一个systemd服务文件:
  1. sudo tee /usr/lib/systemd/system/nginx.service > /dev/null <<EOF
  2. [Unit]
  3. Description=nginx - high performance web server
  4. Documentation=http://nginx.org/en/docs/
  5. After=network-online.target remote-fs.target nss-lookup.target
  6. Wants=network-online.target
  7. [Service]
  8. Type=forking
  9. PIDFile=/var/run/nginx.pid
  10. ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
  11. ExecReload=/bin/kill -s HUP \$MAINPID
  12. ExecStop=/bin/kill -s TERM \$MAINPID
  13. [Install]
  14. WantedBy=multi-user.target
  15. EOF
复制代码

5.6 启动和测试Nginx
  1. # 创建nginx用户
  2. sudo useradd -r -d /var/cache/nginx -s /sbin/nologin nginx
  3. # 创建必要的目录
  4. sudo mkdir -p /var/cache/nginx/client_temp
  5. # 重新加载systemd
  6. sudo systemctl daemon-reload
  7. # 启动nginx
  8. sudo systemctl start nginx
  9. # 检查状态
  10. sudo systemctl status nginx
  11. # 设置开机自启
  12. sudo systemctl enable nginx
复制代码

现在,你可以通过浏览器访问服务器的IP地址,应该能看到Nginx的欢迎页面。

6. 实战案例:编译Linux内核

编译Linux内核是系统管理员和开发者的常见任务,下面我们将演示如何在CentOS Stream上编译自定义Linux内核。

6.1 安装必要的依赖
  1. sudo dnf install -y \
  2.     ncurses-devel \
  3.     bc \
  4.     bison \
  5.     flex \
  6.     openssl-devel \
  7.     elfutils-libelf-devel \
  8.     dwarves \
  9.     rpm-build \
  10.     openssl-devel \
  11.     python3-devel
复制代码

6.2 获取内核源代码
  1. cd ~
  2. # 从kernel.org下载最新的稳定内核
  3. wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.19.12.tar.xz
  4. tar -xvf linux-5.19.12.tar.xz
  5. cd linux-5.19.12
复制代码

6.3 配置内核

有几种方法可以配置内核选项:
  1. # 复制当前系统的配置
  2. cp /boot/config-$(uname -r) .config
  3. # 更新配置
  4. make olddefconfig
复制代码
  1. # 启动文本菜单配置
  2. make menuconfig
复制代码

在菜单中,你可以导航到不同的选项并启用或禁用功能。完成后,保存并退出。
  1. # 启动ncurses图形配置
  2. make nconfig
复制代码

6.4 编译内核
  1. # 清理之前的构建(如果有)
  2. make clean
  3. # 编译内核和模块
  4. make -j$(nproc) bzImage modules
  5. # 或者,如果你想编译所有内容(包括文档等)
  6. make -j$(nproc) all
复制代码

6.5 安装内核
  1. # 安装模块
  2. sudo make modules_install
  3. # 安装内核
  4. sudo make install
复制代码

6.6 更新引导加载程序

CentOS Stream使用GRUB2作为引导加载程序,我们需要更新它以包含新内核:
  1. # 更新GRUB配置
  2. sudo grub2-mkconfig -o /boot/grub2/grub.cfg
  3. # 如果使用UEFI,还需要更新EFI引导
  4. sudo grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
复制代码

6.7 重启并验证
  1. # 重启系统
  2. sudo reboot
  3. # 重启后,验证新内核
  4. uname -r
复制代码

7. 实战案例:编译Python

Python是一种广泛使用的编程语言,有时我们需要编译自定义版本的Python以满足特定需求。

7.1 安装依赖
  1. sudo dnf install -y \
  2.     gcc \
  3.     openssl-devel \
  4.     bzip2-devel \
  5.     libffi-devel \
  6.     zlib-devel \
  7.     readline-devel \
  8.     sqlite-devel \
  9.     gdbm-devel \
  10.     libdb-devel \
  11.     expat-devel \
  12.     xz-devel \
  13.     tk-devel
复制代码

7.2 下载源代码
  1. cd ~
  2. wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tgz
  3. tar -xvf Python-3.11.0.tgz
  4. cd Python-3.11.0
复制代码

7.3 配置编译选项
  1. # 创建一个目录来安装Python
  2. mkdir -p ~/python-installations/Python-3.11.0
  3. # 配置
  4. ./configure --prefix=$HOME/python-installations/Python-3.11.0 \
  5.             --enable-optimizations \
  6.             --with-ensurepip=install \
  7.             --enable-shared
复制代码

这里,我们使用了几个重要的选项:

• --prefix:指定安装目录
• --enable-optimizations:启用优化,会使Python运行更快,但编译时间更长
• --with-ensurepip=install:确保pip被安装
• --enable-shared:构建共享库,便于其他程序嵌入Python

7.4 编译和安装
  1. # 编译
  2. make -j$(nproc)
  3. # 安装
  4. make install
复制代码

7.5 设置环境变量

为了方便使用新编译的Python,我们可以设置环境变量:
  1. # 添加到PATH
  2. echo 'export PATH="$HOME/python-installations/Python-3.11.0/bin:$PATH"' >> ~/.bashrc
  3. # 添加库路径
  4. echo 'export LD_LIBRARY_PATH="$HOME/python-installations/Python-3.11.0/lib:$LD_LIBRARY_PATH"' >> ~/.bashrc
  5. # 重新加载配置
  6. source ~/.bashrc
复制代码

7.6 验证安装
  1. # 检查Python版本
  2. python3 --version
  3. # 检查pip版本
  4. pip3 --version
  5. # 检查安装路径
  6. which python3
复制代码

8. 高级编译技巧

在掌握了基本的编译技能后,我们可以探索一些更高级的技巧,以优化编译过程和结果。

8.1 使用ccache加速编译

ccache是一个编译器缓存,可以显著加快重复编译的速度:
  1. # 安装ccache
  2. sudo dnf install -y ccache
  3. # 设置环境变量
  4. echo 'export CC="ccache gcc"' >> ~/.bashrc
  5. echo 'export CXX="ccache g++"' >> ~/.bashrc
  6. source ~/.bashrc
  7. # 查看ccache统计
  8. ccache -s
复制代码

8.2 使用distcc进行分布式编译

如果你有多台机器,可以使用distcc进行分布式编译,进一步加快编译速度:
  1. # 在所有机器上安装distcc
  2. sudo dnf install -y distcc
  3. # 在主节点上设置环境变量
  4. echo 'export CC="distcc gcc"' >> ~/.bashrc
  5. echo 'export CXX="distcc g++"' >> ~/.bashrc
  6. echo 'export DISTCC_HOSTS="localhost host1 host2 host3"' >> ~/.bashrc
  7. source ~/.bashrc
  8. # 启动distcc服务
  9. sudo systemctl start distccd
  10. sudo systemctl enable distccd
复制代码

8.3 使用链接时优化(LTO)

链接时优化(Link Time Optimization, LTO)可以在链接阶段进行额外的优化,提高程序性能:
  1. # 对于autotools项目
  2. ./configure --enable-lto
  3. # 对于CMake项目
  4. cmake .. -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON
  5. # 对于手动编译
  6. gcc -flto -c source.c
  7. gcc -flto -o program source.o
复制代码

8.4 使用Profile-Guided Optimization(PGO)

PGO是一种基于运行时行为信息进行优化的技术:
  1. # 第一步:编译一个带有性能分析支持的版本
  2. ./configure --enable-profile-generate
  3. make -j$(nproc)
  4. # 第二步:运行代表性工作负载
  5. make check  # 或运行其他代表性测试
  6. # 第三步:使用收集到的数据重新编译
  7. make clean
  8. ./configure --enable-profile-use
  9. make -j$(nproc)
复制代码

8.5 使用静态链接

创建完全静态链接的二进制文件可以减少依赖,便于分发:
  1. # 对于autotools项目
  2. ./configure --enable-static --disable-shared LDFLAGS="-static"
  3. # 对于手动编译
  4. gcc -static -o program source.c
复制代码

9. 常见问题及解决方案

在源代码编译过程中,可能会遇到各种问题。本节将介绍一些常见问题及其解决方案。

9.1 缺少依赖文件

问题:编译过程中出现”error: ‘someheader.h’ file not found”或类似的错误。

解决方案:
  1. # 使用dnf查找包含所需文件或库的包
  2. sudo dnf provides */someheader.h
  3. # 安装相应的开发包
  4. sudo dnf install -y somepackage-devel
复制代码

9.2 版本不兼容

问题:编译过程中出现版本不兼容的错误,如”too few arguments to function ‘somefunction’“。

解决方案:

1. 检查软件的README或INSTALL文件,了解所需的依赖版本。
2. 如果系统中的版本太新,可能需要安装旧版本或使用兼容性选项。
3. 如果系统中的版本太旧,考虑升级或从源代码编译所需的依赖。

9.3 内存不足

问题:编译大型项目(如浏览器或LLVM)时出现内存不足的错误。

解决方案:
  1. # 增加交换空间
  2. sudo fallocate -l 4G /swapfile
  3. sudo chmod 600 /swapfile
  4. sudo mkswap /swapfile
  5. sudo swapon /swapfile
  6. echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
  7. # 或者,限制并行编译作业数
  8. make -j2  # 使用2个并行作业而不是所有CPU核心
复制代码

9.4 编译器错误

问题:编译器报告内部错误或崩溃。

解决方案:

1. 尝试更新编译器:sudo dnf update -y gcc gcc-c++
2. 尝试使用不同的编译器选项,如降低优化级别:make CFLAGS="-O0"  # 禁用优化
3. 如果可能,尝试使用不同版本的编译器。
  1. sudo dnf update -y gcc gcc-c++
复制代码
  1. make CFLAGS="-O0"  # 禁用优化
复制代码

9.5 链接错误

问题:链接阶段出现”undefined reference to ‘somefunction’“错误。

解决方案:

1. 确保所有必需的库都被链接:gcc -o program source.c -lsomelibrary
2. 检查库的顺序(有些链接器对库的顺序敏感)。
3. 确保使用正确的库路径:gcc -o program source.c -L/path/to/libs -lsomelibrary
  1. gcc -o program source.c -lsomelibrary
复制代码
  1. gcc -o program source.c -L/path/to/libs -lsomelibrary
复制代码

10. 构建RPM包

在CentOS Stream上,构建RPM包是分发软件的标准方式。下面我们将介绍如何从源代码构建RPM包。

10.1 安装构建工具
  1. sudo dnf install -y rpm-build rpmdevtools rpmlint
复制代码

10.2 设置构建环境
  1. # 创建构建目录结构
  2. rpmdev-setuptree
  3. # 这会创建以下目录:
  4. # ~/rpmbuild/
  5. # ├── BUILD
  6. # ├── RPMS
  7. # ├── SOURCES
  8. # ├── SPECS
  9. # └── SRPMS
复制代码

10.3 准备源代码和补丁
  1. cd ~/rpmbuild/SOURCES
  2. # 下载源代码
  3. wget https://example.com/software-1.0.0.tar.gz
  4. # 如果需要,创建补丁
  5. # wget https://example.com/software-fix.patch
复制代码

10.4 创建SPEC文件

SPEC文件是RPM包的核心,它包含了构建包所需的所有指令:
  1. cd ~/rpmbuild/SPECS
  2. cat > software.spec << EOF
  3. Name:           software
  4. Version:        1.0.0
  5. Release:        1%{?dist}
  6. Summary:        A sample software package
  7. License:        GPLv2+
  8. URL:            https://example.com/
  9. Source0:        https://example.com/software-%{version}.tar.gz
  10. # Patch0:        software-fix.patch
  11. BuildRequires:  gcc
  12. BuildRequires:  make
  13. Requires:       glibc
  14. %description
  15. This is a sample software package for demonstration purposes.
  16. %prep
  17. %setup -q
  18. # %patch0 -p1
  19. %build
  20. %configure
  21. make %{?_smp_mflags}
  22. %install
  23. rm -rf \$RPM_BUILD_ROOT
  24. %make_install
  25. %files
  26. %doc
  27. %license
  28. %{_bindir}/software
  29. %{_mandir}/man1/software.1*
  30. %changelog
  31. * $(date +"%a %b %d %Y") Your Name <you@example.com> - 1.0.0-1
  32. - Initial package
  33. EOF
复制代码

10.5 构建RPM包
  1. # 构建源RPM和二进制RPM
  2. rpmbuild -ba software.spec
  3. # 或者只构建二进制RPM
  4. rpmbuild -bb software.spec
  5. # 或者只构建源RPM
  6. rpmbuild -bs software.spec
复制代码

构建完成后,RPM包将位于~/rpmbuild/RPMS/$(uname -m)/目录中,源RPM位于~/rpmbuild/SRPMS/目录中。

10.6 测试RPM包
  1. # 安装RPM包
  2. sudo dnf localinstall ~/rpmbuild/RPMS/$(uname -m)/software-1.0.0-1.el8.x86_64.rpm
  3. # 验证安装
  4. rpm -ql software  # 列出包中的文件
  5. software --version  # 运行软件
  6. # 卸载RPM包
  7. sudo dnf remove software
复制代码

11. 总结与最佳实践

通过本教程,我们已经学习了在CentOS Stream上编译源代码的基本和高级技能。以下是一些总结和最佳实践:

11.1 总结

1. 环境准备:确保系统更新,安装必要的开发工具和库。
2. 源代码获取:可以通过DNF、Git或官方网站获取源代码。
3. 基本编译流程:大多数项目遵循配置、编译、安装的基本流程。
4. 高级技巧:使用ccache、distcc、LTO和PGO等技术可以优化编译过程和结果。
5. 问题解决:学会识别和解决常见的编译问题。
6. RPM构建:掌握RPM包的构建方法,便于软件分发。

11.2 最佳实践

1. 保持环境整洁:使用单独的构建目录,避免污染源代码目录。
2. 并行编译:使用make -j$(nproc)进行并行编译,加快编译速度。
3. 版本控制:对自定义配置和补丁使用版本控制,便于追踪变更。
4. 文档记录:记录编译过程中的特殊配置和解决方法,便于将来参考。
5. 测试验证:编译完成后,进行充分的测试验证,确保软件功能正常。
6. 安全考虑:从可信来源获取源代码,验证文件完整性,注意安全漏洞。

11.3 持续学习

编译技能是一个持续学习的过程。以下是一些建议:

1. 阅读文档:仔细阅读软件的README、INSTALL和文档,了解特定的编译要求。
2. 参与社区:加入相关软件的社区,学习他人的经验。
3. 实践练习:尝试编译不同类型的软件,挑战更复杂的项目。
4. 关注更新:关注编译工具和技术的更新,学习新的方法和技巧。

通过不断学习和实践,你将能够熟练掌握CentOS Stream上的源代码编译技能,为你的工作和项目带来更大的灵活性和控制力。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

手机版|联系我们|小黑屋|TG频道|RSS |网站地图

Powered by Pixtech

© 2025-2026 Pixtech Team.

>