# How to create a Linux RPM package?

**URL:** <https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566>\
**Category:** Rocky Linux Help & Support\
**Created:** [October 16, 2022, 6:14pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566 "2022-10-16T18:14:11Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![bhamvas](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/bhamvas/32/2355_2.png) [@bhamvas](https://forums.rockylinux.org/u/bhamvas)\
**Post date:** [October 16, 2022, 6:14pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/1 "2022-10-16T18:14:11Z")

</div>

Hi, I follow this article : [https://www.redhat.com/sysadmin/create-rpm-package](https://www.redhat.com/sysadmin/create-rpm-package)

I have the source file and necessary files. I have the developer environment , necessary tools are available.  
Is there anything that I miss ? Why can’t I compile a simple `.c` file if I have every details ?  
How do you do guys ? Thank you for your help in advance.

The reason why I cannot attach details about unsuccessful compile because the computer doesn’t have network card , I’ve just inserted an USB NIC but `rt2x00` module doesn’t work.

That’s why I would like to compile the driver.

---

<div class="post-metadata">

**Author:** ![bhamvas](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/bhamvas/32/2355_2.png) [@bhamvas](https://forums.rockylinux.org/u/bhamvas)\
**Post date:** [October 16, 2022, 6:28pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/2 "2022-10-16T18:28:09Z")

</div>

This is the source : [linux/drivers/net/wireless/ralink/rt2x00 at master · torvalds/linux · GitHub](https://github.com/torvalds/linux/tree/master/drivers/net/wireless/ralink/rt2x00)

I would like to build an `.rpm` package from `rt73usb.c`  
Kernel Headers and external header files are available.

I don’t know why it doesn’t work.

---

<div class="post-metadata">

**Author:** ![label](https://avatars.discourse-cdn.com/v4/letter/l/c5a1d2/32.png) [@label](https://forums.rockylinux.org/u/label)\
**Post date:** [October 16, 2022, 6:49pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/3 "2022-10-16T18:49:26Z")

</div>

I would encourage viewing the following pages:

[https://rpm-packaging-guide.github.io/](https://rpm-packaging-guide.github.io/)  
[https://docs.fedoraproject.org/en-US/packaging-guidelines/](https://docs.fedoraproject.org/en-US/packaging-guidelines/)

> **[Mock](https://rpm-software-management.github.io/mock/)**
>
> A ‘simple’ chroot build environment manager for building RPMs.

Copying a source code file is not enough. You will need to compile it in the spec file with the correct build requirements and correct commands/macros. As we do not see your spec file, it’s hard for us to guess what you have attempted.

If you continue to have issues, you can potentially request a driver built at [My View - ELRepo Bugs](https://elrepo.org/bugs)

---

<div class="post-metadata">

**Author:** ![bhamvas](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/bhamvas/32/2355_2.png) [@bhamvas](https://forums.rockylinux.org/u/bhamvas)\
**Post date:** [October 16, 2022, 7:13pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/4 "2022-10-16T19:13:26Z")

</div>

I try to attach the `.spec` file and outcome of the build from stdout .

build.log

```auto
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.VxlTqR
+ umask 022
+ cd /home/user/rpmbuild/BUILD
+ cd /home/user/rpmbuild/BUILD
+ rm -rf rt73usb-0.0.1
+ /usr/bin/tar -xof /home/user/rpmbuild/SOURCES/rt73usb-0.0.1.tar.gz
+ cd rt73usb-0.0.1
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ echo 'override rt73usb * weak-updates/rt73usb'
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.ef38CT
+ umask 022
+ cd /home/user/rpmbuild/BUILD
+ cd rt73usb-0.0.1
+ /usr/bin/make -C /usr/src/kernels/4.18.0-372.9.1.el8.x86_64 modules M=/home/user/rpmbuild/BUILD/rt73usb-0.0.1
make: Entering directory '/usr/src/kernels/4.18.0-372.9.1.el8.x86_64'
  CC [M] /home/user/rpmbuild/BUILD/rt73usb-0.0.1/rt73usb.o
/home/user/rpmbuild/BUILD/rt73usb-0.0.1/rt73usb.c:2306:22: error: initialization of 'void (*)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u32)' {aka 'void (*)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, unsigned int)'} from incompatible pointer type 'void (*)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u64)' {aka 'void (*)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, long long unsigned int)'} [-Werror=incompatible-pointer-types]
  .bss_info_changed = rt2x00mac_bss_info_changed,
                      ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/rpmbuild/BUILD/rt73usb-0.0.1/rt73usb.c:2306:22: note: (near initialization for 'rt73usb_mac80211_ops.bss_info_changed')
/home/user/rpmbuild/BUILD/rt73usb-0.0.1/rt73usb.c:2307:14: error: initialization of 'int (*)(struct ieee80211_hw *, struct ieee80211_vif *, u16, const struct ieee80211_tx_queue_params *)' {aka 'int (*)(struct ieee80211_hw *, struct ieee80211_vif *, short unsigned int, const struct ieee80211_tx_queue_params *)'} from incompatible pointer type 'int (*)(struct ieee80211_hw *, struct ieee80211_vif *, unsigned int, u16, const struct ieee80211_tx_queue_params *)' {aka 'int (*)(struct ieee80211_hw *, struct ieee80211_vif *, unsigned int, short unsigned int, const struct ieee80211_tx_queue_params *)'} [-Werror=incompatible-pointer-types]
  .conf_tx = rt73usb_conf_tx,
              ^ ~~~~~~~~~~~~~~
/home/user/rpmbuild/BUILD/rt73usb-0.0.1/rt73usb.c:2307:14: note: (near initialization for 'rt73usb_mac80211_ops.conf_tx')
cc1: some warnings being treated as errors
make[1]: *** [scripts/Makefile.build:322: /home/user/rpmbuild/BUILD/rt73usb-0.0.1/rt73usb.o] Error 1
make: *** [Makefile:1577: _module_/home/user/rpmbuild/BUILD/rt73usb-0.0.1] Error 2
make: Leaving directory '/usr/src/kernels/4.18.0-372.9.1.el8.x86_64'
error: Bad exit status from /var/tmp/rpm-tmp.ef38CT (%build)

RPM build errors:
    Bad exit status from /var/tmp/rpm-tmp.ef38CT (%build)

```

rt73usb.spec

```auto
# Define the kmod package name here.
%define kmod_name rt73usb

# If kmod_kernel_version isn't defined on the rpmbuild line, define it here.
%{!?kmod_kernel_version: %define kmod_kernel_version 4.18.0-372.9.1.el8}

%{!?dist: %define dist .el8}

Name: kmod-%{kmod_name}
Version:	0.0.1
Release:	1%{?dist}
Summary:	%{kmod_name} kernel module(s)
Group: System Environment/Kernel
License:	GPLv2
URL: http://www.kernel.org/
BuildArch:	x86_64
# Sources
Source0:	%{kmod_name}-%{version}.tar.gz
Source5:	GPL-v2.0.txt

# Fix for the SB-signing issue caused by a bug in /usr/lib/rpm/brp-strip
# https://bugzilla.redhat.com/show_bug.cgi?id=1967291

%define __spec_install_post	/usr/lib/rpm/check-buildroot \
				/usr/lib/rpm/redhat/brp-ldconfig \
				/usr/lib/rpm/brp-compress \
				/usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump \
				/usr/lib/rpm/brp-strip-static-archive /usr/bin/strip \
				/usr/lib/rpm/brp-python-bytecompile "" 1 \
				/usr/lib/rpm/brp-python-hardlink \
				PYTHON3="/usr/libexec/platform-python" /usr/lib/rpm/redhat/brp-mangle-shebangs

# Source code patches

%define findpat %( echo "%""P" )
%define __find_requires /usr/lib/rpm/redhat/find-requires.ksyms
%define __find_provides /usr/lib/rpm/redhat/find-provides.ksyms %{kmod_name} %{?epoch:%{epoch}:}%{version}-%{release}
%define dup_state_dir %{_localstatedir}/lib/rpm-state/kmod-dups
%define kver_state_dir %{dup_state_dir}/kver
%define kver_state_file %{kver_state_dir}/%{kmod_kernel_version}.%{_arch}
%define dup_module_list %{dup_state_dir}/rpm-kmod-%{kmod_name}-modules
%define debug_package %{nil}

%global _use_internal_dependency_generator 0
%global kernel_source() %{_usrsrc}/kernels/%{kmod_kernel_version}.%{_arch}

BuildRoot:	%(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)

ExclusiveArch:	x86_64

BuildRequires:	elfutils-libelf-devel
BuildRequires:	kernel-devel = %{kmod_kernel_version}
BuildRequires:	kernel-abi-whitelists
BuildRequires:	kernel-rpm-macros
BuildRequires:	redhat-rpm-config

Provides:	kernel-modules >= %{kmod_kernel_version}.%{_arch}
Provides:	kmod-%{kmod_name} = %{?epoch:%{epoch}:}%{version}-%{release}

Requires(post):	%{_sbindir}/weak-modules
Requires(postun):	%{_sbindir}/weak-modules
Requires:	kernel >= %{kmod_kernel_version}

%description
This package provides the %{kmod_name} kernel module(s).
It is built to depend upon the specific ABI provided by a range of releases
of the same variant of the Linux kernel and not on any one specific build.

%prep
%setup -q -n %{kmod_name}-%{version}
echo "override %{kmod_name} * weak-updates/%{kmod_name}" > kmod-%{kmod_name}.conf

# Apply patch(es)
# % patch0 -p1

%build
%{__make} -C %{kernel_source} %{?_smp_mflags} modules M=$PWD

whitelist="/lib/modules/kabi-current/kabi_whitelist_%{_target_cpu}"
for modules in $( find . -name "*.ko" -type f -printf "%{findpat}\n" | sed 's|\.ko$||' | sort -u ) ; do
	# update greylist
	nm -u ./$modules.ko | sed 's/.*U //' | sed 's/^\.//' | sort -u | while read -r symbol; do
		grep -q "^\s*$symbol\$" $whitelist || echo "$symbol" >> ./greylist
	done
done
sort -u greylist | uniq > greylist.txt

%install
%{__install} -d %{buildroot}/lib/modules/%{kmod_kernel_version}.%{_arch}/extra/%{kmod_name}/
%{__install} %{kmod_name}.ko %{buildroot}/lib/modules/%{kmod_kernel_version}.%{_arch}/extra/%{kmod_name}/
%{__install} -d %{buildroot}%{_sysconfdir}/depmod.d/
%{__install} -m 0644 kmod-%{kmod_name}.conf %{buildroot}%{_sysconfdir}/depmod.d/
%{__install} -d %{buildroot}%{_defaultdocdir}/kmod-%{kmod_name}-%{version}/
%{__install} -m 0644 %{SOURCE5} %{buildroot}%{_defaultdocdir}/kmod-%{kmod_name}-%{version}/
%{__install} -m 0644 greylist.txt %{buildroot}%{_defaultdocdir}/kmod-%{kmod_name}-%{version}/

# strip the modules(s)
find %{buildroot} -name \*.ko -type f | xargs --no-run-if-empty %{__strip} --strip-debug

# Sign the modules(s)
%if %{?_with_modsign:1}%{!?_with_modsign:0}
# If the module signing keys are not defined, define them here.
%{!?privkey: %define privkey %{_sysconfdir}/pki/SECURE-BOOT-KEY.priv}
%{!?pubkey: %define pubkey %{_sysconfdir}/pki/SECURE-BOOT-KEY.der}
for module in $(find %{buildroot} -type f -name \*.ko);
do %{_usrsrc}/kernels/%{kmod_kernel_version}.%{_arch}/scripts/sign-file \
sha256 %{privkey} %{pubkey} $module;
done
%endif

%clean
%{__rm} -rf %{buildroot}

%post
modules=( $(find /lib/modules/%{kmod_kernel_version}.x86_64/extra/%{kmod_name} | grep '\.ko$') )
printf '%s\n' "${modules[@]}" | %{_sbindir}/weak-modules --add-modules --no-initramfs

mkdir -p "%{kver_state_dir}"
touch "%{kver_state_file}"

exit 0

%posttrans
# We have to re-implement part of weak-modules here because it doesn't allow
# calling initramfs regeneration separately
if [-f "%{kver_state_file}"]; then
	kver_base="%{kmod_kernel_version}"
	kvers=$(ls -d "/lib/modules/${kver_base%%.*}"*)

	for k_dir in $kvers; do
		k="${k_dir#/lib/modules/}"

		tmp_initramfs="/boot/initramfs-$k.tmp"
		dst_initramfs="/boot/initramfs-$k.img"

		# The same check as in weak-modules: we assume that the kernel present
		# if the symvers file exists.
		if [-e "$k_dir/symvers.gz"]; then
			/usr/bin/dracut -f "$tmp_initramfs" "$k" || exit 1
			cmp -s "$tmp_initramfs" "$dst_initramfs"
			if ["$?" = 1]; then
				mv "$tmp_initramfs" "$dst_initramfs"
			else
				rm -f "$tmp_initramfs"
			fi
		fi
	done

	rm -f "%{kver_state_file}"
	rmdir "%{kver_state_dir}" 2> /dev/null
fi

rmdir "%{dup_state_dir}" 2> /dev/null

exit 0

%preun
if rpm -q --filetriggers kmod 2> /dev/null| grep -q "Trigger for weak-modules call on kmod removal"; then
	mkdir -p "%{kver_state_dir}"
	touch "%{kver_state_file}"
fi

mkdir -p "%{dup_state_dir}"
rpm -ql kmod-%{kmod_name}-%{version}-%{release}.%{_arch} | grep '\.ko$' > "%{dup_module_list}"

%postun
if rpm -q --filetriggers kmod 2> /dev/null| grep -q "Trigger for weak-modules call on kmod removal"; then
	initramfs_opt="--no-initramfs"
else
	initramfs_opt=""
fi

modules=( $(cat "%{dup_module_list}") )
rm -f "%{dup_module_list}"
printf '%s\n' "${modules[@]}" | %{_sbindir}/weak-modules --remove-modules $initramfs_opt

rmdir "%{dup_state_dir}" 2> /dev/null

exit 0

%files
%defattr(644,root,root,755)
/lib/modules/%{kmod_kernel_version}.%{_arch}/
%config /etc/depmod.d/kmod-%{kmod_name}.conf
%doc /usr/share/doc/kmod-%{kmod_name}-%{version}/

%changelog
* Wed Oct 12 2022 0.0-1
- Initial el8 build of the kmod package.
- Source code from RHEL 8.6 kernel

```

---

<div class="post-metadata">

**Author:** ![bhamvas](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/bhamvas/32/2355_2.png) [@bhamvas](https://forums.rockylinux.org/u/bhamvas)\
**Post date:** [October 16, 2022, 7:20pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/5 "2022-10-16T19:20:18Z")

</div>

Photo about the current state:

 ![rpm-build](https://us1.discourse-cdn.com/flex020/uploads/rockylinux/original/2X/b/b34b7cca107714337c45f5ffa57a1fb844cd8f9d.jpeg)

---

<div class="post-metadata">

**Author:** ![toracat](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/toracat/32/68_2.png) [@toracat](https://forums.rockylinux.org/u/toracat)\
**Post date:** [October 17, 2022, 1:30am UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/6 "2022-10-17T01:30:55Z")

</div>

Instead of Linus’ source tree, get the source from RHEL/Rocky’s kernel and try building from there. I think it will succeed.

---

<div class="post-metadata">

**Author:** ![bhamvas](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/bhamvas/32/2355_2.png) [@bhamvas](https://forums.rockylinux.org/u/bhamvas)\
**Post date:** [October 17, 2022, 5:30am UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/7 "2022-10-17T05:30:45Z")

</div>

Thank you again for your help. Before I start to browse the net explain me one thing please .  
If I enter the `make menuconfig` I can find the necessary modul in my current kernel (4.18.0-…)

![ralink-kernel](https://us1.discourse-cdn.com/flex020/uploads/rockylinux/original/2X/f/ffa778c873193de2ed93251f7789805fca29627d.jpeg)

Why I cannot find it the source of the modul ? How it is possible than the kernel is able to compile it ?  
I don’t get it. Thank you for your answer.

---

<div class="post-metadata">

**Author:** ![bhamvas](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/bhamvas/32/2355_2.png) [@bhamvas](https://forums.rockylinux.org/u/bhamvas)\
**Post date:** [October 17, 2022, 6:30am UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/8 "2022-10-17T06:30:06Z")

</div>

Ok. Great. I understand.  
I simple downloaded this `.src` and got the source of the my kernel : [http://mirror.szerverem.hu/rocky/8.6/BaseOS/source/tree/Packages/k/kernel-4.18.0-372.9.1.el8.src.rpm](http://mirror.szerverem.hu/rocky/8.6/BaseOS/source/tree/Packages/k/kernel-4.18.0-372.9.1.el8.src.rpm)

After `rpm2cpio` I was able to browse the files. I have found the source of the NIC and you were right (again) build was successful by using the certain sources.

Thank y’all for your kind help. 👏🏼

---

<div class="post-metadata">

**Author:** ![atomicturtle](https://avatars.discourse-cdn.com/v4/letter/a/34f0e0/32.png) [@atomicturtle](https://forums.rockylinux.org/u/atomicturtle)\
**Post date:** [October 18, 2022, 2:07pm UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/9 "2022-10-18T14:07:03Z")

</div>

A shortcut here, instead of rpm2cpio, install the src.rpm: rpm -Uvh kernel-4.18.0-372.9.1.el8.src.rpm and this will extract the contents of the RPM to ~/rpmbuild/SOURCES and ~/rpmbuild/SPECS/

---

<div class="post-metadata">

**Author:** ![label](https://avatars.discourse-cdn.com/v4/letter/l/c5a1d2/32.png) [@label](https://forums.rockylinux.org/u/label)\
**Post date:** [August 24, 2023, 4:53am UTC](https://forums.rockylinux.org/t/how-to-create-a-linux-rpm-package/7566/10 "2023-08-24T04:53:32Z")

</div>


