Entware Package-related tips
Entware Package-related tips
see https://github.com/Entware/Entware/wiki
For the case where Entware doesn't have the package on board that you wish to use, and your freely asked request for a new package gets declined, you have the option to create an Entware package yourself.
First setup an environment that meets OpenWrt buildroot dependencies as can be read in OpenWrt build system installation. This is because Entware is a modified OpenWrt environment.
Then setup Entware by cloning its repository:
$ git clone https://github.com/Entware/Entware.git
$ cd Entware
By copying a ready-made file name .config from folder configs. In this example the target is an Asus RT-N56U. The RT-N56U contains as processor a Ralink RT3883/RT3662 SoC (# cat /proc/cpuinfo | grep system\ type). SoC means System on Chip. That Ralink is a cpu of model MIPS 74Kc (# cat /proc/cpuinfo | grep cpu\ model). Such a MIPS 74Kc processor requires the bytes to be in little endian (el) order, and doesn't contain a floating point unit (FPU), that is why floating point operations need to be done in software (sf). This all means you can use a ready made configuration file that is located in the configs folder with the name mipselsf:
$ cp configs/mipsel-3.4.config .config
The full execution op OpenWRT Buildroot environment a.k.a. rebuild repo a.k.a. make in folder ./Entware is not necessary. You only need:
$ make tools/install
$ make toolchain/install
$ make target/compile
Note: I'm not sure whether this target/compile step is necessary, its in the OpenWrt build one package from scratch instructions.
Now you should be ready to compile an individual package. For starters you can test make package/.../compile using a tiny package that hasn't got dependencies, for example usbreset:
$ make package/usbreset/compile
When everything succeeds your package ends up in a subfolder of the Entware "bin" folder. For this mipselsf based example, you should find the .ipk file at bin/mipselsf-uClibc/packages:
$ ls bin/mipselsf-uClibc/packages | grep usbreset
usbreset_4_mipselsf.ipk
When you see the ..._mipselsf.ipk output, your first package is successfully build. Now it's time to ...
For starters read OpenWrt creating a package and as a reference there is OpenWrt creating packages. Hint: use one of the Makefiles that is already in the Entware or OpenWrt repository, and modify that file to your needs.
Next step, is that you also instruct your configuration (.config file) to Make the desired package.
Without adapting your configuration file, the command make package/xxxxx/compile after a few seconds will enter your package folder:
make[1] package/my_package_name/compile
make[2] -C package/libs/toolchain compile
make[2] -C package/SECTION/subfolder/my_package_name compile
And immediately (not build the package at all) return to your command prompt.
Or in the more verbose make package/xxxxx/compile V=s output this "mistake" will look like:
make[1]: Entering directory `/Volumes/Case-sensitive/Entware'
make[2]: Entering directory `/Volumes/Case-sensitive/Entware/package/libs/toolchain'
make[2]: Leaving directory `/Volumes/Case-sensitive/Entware/package/libs/toolchain'
make[2]: Entering directory `/Volumes/Case-sensitive/Entware/package/SECTION/subfolder/my_package_name'
make[2]: Leaving directory `/Volumes/Case-sensitive/Entware/package/SECTION/subfolder/my_package_name'
make[1]: Leaving directory `/Volumes/Case-sensitive/Entware'
A command line interactive tool that lists the new options is $ make oldconfig. This will list all .config options and ask a question for each newly added package. Choose [m] for each package you might wish to build. In case there are no new options to configure, the output will be # configuration written to .config.
There also is a graphical (ncurses based) tool to enable your package: $ make menuconfig. Make sure your package is present in packages list and selected [*] or [M].
In case you prefer a non interactive command line, there is a third option. You can use this stream editor command to search for the "not set" text string and replace it with the string that will enable the make of your package:
$ sed -ir 's/# CONFIG_PACKAGE_my_package_name is not set/CONFIG_PACKAGE_my_package_name=m/' .config
A step-by-step example for the package ucspi-tcp. This shows the configuration file before, the command to run the search-and-replace enable package operation, and the .config file after the change so you can verify that this change is actually made:
$ cat .config | grep ucspi-tcp
# CONFIG_PACKAGE_ucspi-tcp is not set
$ sed -ir 's/# CONFIG_PACKAGE_ucspi-tcp is not set/CONFIG_PACKAGE_ucspi-tcp=m/' .config
$ cat .config | grep ucspi-tcp
CONFIG_PACKAGE_ucspi-tcp=m
You might want to start your package automatically when the router starts. For this purpose the router does execute scripts located in the folder '/opt/etc/init.d/'.
Here is a point where Entware and its predecessor Entware are different from OpenWrt. OpenWrt as well as Entware both use an 'init.d' folder (where init is short for initialization) containing scripts. Though the OpenWrt init scripts are not compatible with Entware. OpenWrt uses "rc.common" where on the contrary Entware uses "rc.func" as a wrapper to provide its main and default functionality. "Rc.func" does not check the script prior to execution as is done by OpenWrt's rc.common. Entware also uses "rc.unslung" as the helper script to start and stop all /opt/etc/init.d/ scripts. To be more precise, rc.unslung will process all executable files that start with a capital S and will do that in sorted order. Except for stopping, restarting and killing, then the executable S* init script files will be processed in reverse sorted order.
Learn yourself bash scripting and have a look inside rc.func to understand its functionality. By this rc.func template, the available commands for any init script are as follows:
start Start the service
stop Stop the service
restart Restart the service
check Check the service (dead or alive)
kill Kill the service
reconfigure Reload configuration files (sends SIGHUP signal)
All these arguments can be passed to the script when run. For example, to restart the service call it with restart:
# /opt/etc/init.d/my_init_script restart
An example Entware init script, S15upsd init from the nut package, looks like this:
#!/bin/sh
ENABLED=yes
PROCS=upsd
ARGS="-u admin"
PREARGS=""
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
. /opt/etc/init.d/rc.func
Entware hasn't got functionality like OpenWrt to enable/disable init scripts. You need to name your init script starting with the capital letter S. Next name the file with a number. If you haven't got a clue which number to choose, look for the section START= in the OpenWrt init file. Neither is there a Unified Configuration Interface: OpenWrt UCI. Look for strings like /lib/functions/, those needs rework because they don't exist in Entware' world.
Important
Make sure that the filesystem containing your working directory for compilation has at least 7 GiB of free disk space. You will need ~150 GiB of free space to compile the whole repository.
Entware builds packages using the OpenWrt SDK Build system, please install its dependencies first. If you choose to build the packages from Docker, the dependencies are automatically provided so you can move to the next step. Also, there are some package-specific dependencies:
| Package | Dependencies |
|---|---|
| luajit | g++-multilib |
| 7-zip | p7zip-full |
git clone https://github.com/Entware/Entware.git && cd Entware
There are some additional steps required if you are building packages for any of the deprecated architectures.
For armv7sf-k2.6 or x86-k2.6:
git fetch && git switch k2.6
For armv5sf-k3.2:
git fetch && git switch armv5-3.2
make package/symlinks
The OpenWRT SDK manages its configuration in a file named , located in its root directory. Pre-made configurations for most of the major target architectures are stored in the directory that is also located in the SDK's root directory. To make use of them, you need only to copy the desired configuration file into the root directory and rename it to . The example below demonstrates doing this for the MIPSEL platform:.configconfigs.config
cp -iv configs/mipsel-3.4.config .config
make -j$(nproc)
Please refer to the OpenWrt Build system documentation for more details, and ask any questions you may have about its use on their forum.
Tip
You can build one package (, for example) with all its dependencies using only a single command. Example:squid
make package/squid/compile
Tip
If something goes wrong during compilation, turn on verbose mode by appending to your make invocation for more detailed progress and error messages.V=s
make package/tmux/compile V=s
Tip
You can speed up compilation on multi-processor systems by running several build threads simultaneously. Just add to the invocation, like this:-j$(nproc)make
make -j$(nproc) package/compile
make -j$(nproc) tools/install
make -j$(nproc) toolchain/install
make -j$(nproc) target/compile
make -j$(nproc) package/compile
This can also be used in case you don't need to build all of the packages. Replace the final command in the sequence above () with the command required to build the package you need, though it may require a little modification. For instance, if you're getting an error during the compilation of a package…make -j$(nproc) package/compile
…
root@host~$ make -C feeds/rtndev/telegram-cli host-compile
…
make[3] -C feeds/rtndev/telegram-cli host-compile
make[3] -C feeds/rtndev/totd compile
make -r world: build failed. Please re-run make with -j1 V=s or V=sc for a higher verbosity level to see what's going on
…follow the advice given and run 'make -j1 V=s' to better see what happened. Be aware, though, that you'll have a longer wait until the build system gets through all of the already-built packages. It's much more convenient to proceed directly to the package that failed, like this:
make -j1 package/feeds/rtndev/totd/compile V=s
Sometimes you have to omit the package section, for instance with the error message you would target it for compilation by invoking this way:make[3] -C feeds/packages/utils/ttyd compilemake
make -j1 package/feeds/packages/ttyd/compile V=s
You can also run and then search the file for the exact target name of the package you're interested in.make printdb >log.txtlog.txt
In the event of an error during the or sections of the compilation that results in changes to your configuration in the file, remember that you'll need to use rather than the usual command. If you only want to clean one specific part of the tree, you can run instead.tools/installtoolchain/install.configmake dircleanmake cleanmake toolchain/uClibc/headers/clean
Mirrors
Alternative package sources
You may use one of the community-supported mirrors:
- https://mirrors.bfsu.edu.cn/entware/
- https://mirrors.cqupt.edu.cn/entware/
- https://mirrors.nju.edu.cn/entware/
- https://entware.diversion.ch/
Please, follow this guide to make sure the package manager can use HTTPS transport. Then, edit URL in /opt/etc/opkg.conf and run opkg update.
- General Information
- Installing GCC on Entware
- Installing a build configuration system
- Installing development headers
- Environment variables
- Example compilation process
- External links
The gcc package is a beta release in the OpenWrt package repository, and it is treated likewise in Entware, primarily intended for advanced users who understand how to work around its limitations. Specifically, the GCC package in the Entware repositories only supports dynamic linking; static linking is not supported, there are no static libraries.
It is faster and much more reliable to cross-compile binaries on a GNU/Linux computer or virtual machine of a different architecture (x86_64, for instance), and a basic primer for doing so is provided here in our Wiki.
There are some notable restrictions in what can be successfully compiled and how when using GCC on Entware, and a majority are described in the following sections.
💡 Note: As always, before attempting to install packages in Entware using opkg, first use the
opkg updatecommand to ensure that they will be the latest versions available.
A barebones install of the GCC compiler can be performed using these commands. It will install the gcc package as well as well as any of its dependencies (binutils, libc, libpthread, librt, libssp, and libstdcpp) that aren't already present on the system.
opkg install gcc
In addition to installing the gcc packages plus its dependencies (as shown above), users are strongly encouraged to also install the binutils, busybox, gawk, ldd, make, sed and tar packages before a successful compilation can be reasonably expected for even the simplest software.
opkg install binutils busybox gawk ldd make sed tar
While the above commands will prepare your Entware environment to perform basic compilation of software written in C/C++ from source code, it is still lacking some crucial utilities that most modern software projects rely on to configure the build process appropriately for the environment it will take place on. Some basic utilities that are often integral to the build process include the coreutils-install, diffutils, ldconfig, patch and pkg-config packages, which can be installed with the command below.
opkg install coreutils-install diffutils ldconfig patch pkg-config --force-overwrite
There are also several build configuration systems with widespread adoption, of which it is highly likely that you will require at least one. Once you identify the one in use by the project you're seeking to compile, the following command snippets can help you install the required packages for each.
opkg install automake libintl-full libtool-bin
opkg install cmake icu libopenssl
opkg install bash git python3-pip python3-setuptools
python3 -m pip install -U wheel
cd /opt/tmp && git clone https://github.com/ninja-build/ninja.git && cd ./ninja
git checkout release
CONFIG_SHELL=/opt/bin/bash python3 ./configure.py --bootstrap
install -Dm0755 -t /opt/bin ./ninja
cd /opt/tmp && rm -Rf /opt/tmp/ninja
python3 -m pip install -U meson
🎗️ Reminder: While nearly all packages in the Entware repositories are distributed without header files, certain packages that use architecture-dependent headers are installed by the package they were built with. Currently, those packages are:
gcc,libncurses-dev,libxml2-dev,python3-dev,ruby-devandzlib-dev. If you had to delete your/opt/includefolder for any reason after installing these packages and then encounter errors trying to compile something, use the following shell one-liner to reinstall all the packages in the list above that are present on your system:for pkg in gcc libncurses-dev libxml2-dev python3-dev ruby-dev zlib-dev; do if opkg list-installed "${pkg}"; then opkg install "${pkg}" --force-overwrite --force-reinstall; fi; done
There are no *-dev or *-devel packages in Entware (as it comes from OpenWrt), unlike the majority of Linux distributions in use today. Those packages typically install the headers, static libraries and other development files that are produced along with the target ELF files when software is compiled and that are needed again to build software with dependencies on those packages. However, those files are not provided in the ipk packages used by Entware. Instead, there is a tar.gz archive of all the headers and development files from the entirety of packages produced for Entware.
💡 Note: If you use these include files, configure scripts generated by Autotools that you run to prepare to compile something may report to you that you have software projects installed that you in fact do not. The reason for this is that the include archive has the development header files for almost all of the packages in Entware, and no way to selectively install only those files for the packages currently on your system. Thus, a project relying on libxml2 may tell you that it found libxml2 and complete its build configuration successfully, only to fail during compilation with a "File not found:..." error. What happened is that the configuration script found the libxml2 headers in the include directory and simply assumed you also had the library they belong to, which you didn't. The customary solution to that is to determine which Entware package(s) the missing files are associated with, and install them, then run the configure script again.
💭 Also: If the reverse is true and you find that the build system is unable to locate a library or other package that you are certain is present on your system along with its headers, the issue may be the lack of a .pc file for it in
/opt/lib/pkgconfig. You can often overcome this by visiting the source code repository for that library/package and finding out what the expected name and contents are of the .pc files it installs, then downloading them with the correct name into/opt/lib/pkgconfigor using a text editor to create them in that directory by hand.
There is a different tar.gz archive for each of the architectures in the Entware repository. You can expand the section below to find the link to the archive for your device's architecture in order to download it directly to your computer and examine the contents. This would be a prudent step for someone who, for instance, didn't expect to need the files for more than just a single compilation and was familiar enough with the process to know which files/directories they needed, preferring not to clutter their Entware filesystem with the full contents of the archive.
Links to header archives for all Entware-supported architecturesFor those interested in adding all of the development files available for their architecture to their Entware partition, the following one-liner shell command can determine the correct architecture link from the table above, download the archive and expand its contents in the proper location, using just the busybox tools present in every Entware setup.
⚠️ Attention: This currently requires over 400 MiB of available storage on your Entware filesystem and is prone to increasing in size over time, as new packages are added to Entware and the existing ones become more complex.
/opt/bin/busybox wget -qO- "$(/opt/bin/busybox sed -Ene \
's|^src/gz[[:space:]]entware[[:space:]]https?([[:graph:]]+)|http\1/include/include.tar.gz|p' \
/opt/etc/opkg.conf)" | /opt/bin/busybox tar x -vzC /opt/include
Binaries compiled in Entware must use rpath=/opt/lib and a non-standard dynamic linker. The gcc package installs the /opt/bin/gcc_env.sh script that will set sane default values for the CFLAGS and LDFLAGS environment variables which are crucial for building binaries, but don't be surprised if they require further customization to achieve a successful build. If the source code you're attempting to build is written in C++ and not C, you may also have to define the CPPFLAGS and/or CXXFLAGS variables. For armv7sf, this might look like:
export LDFLAGS="-Wl,-rpath=/opt/lib -Wl,--dynamic-linker=/opt/lib/ld-linux.so.3 -L/opt/lib"
export CFLAGS="-O2 -pipe -march=armv7-a -mtune=cortex-a9 -fno-caller-saves -mfloat-abi=soft"
export CPPFLAGS="${CFLAGS} -I/opt/include"
export CXXFLAGS="${CFLAGS} ${LDFLAGS}"
To setup environment variables for GCC execute
source /opt/bin/gcc_env.sh
Alternatively, use the flags from /opt/bin/gcc_env.sh manually when building binaries, such as the following invocation for the GNU C Compiler:
source /opt/bin/gcc_env.sh && gcc "${CFLAGS}" "${LDFLAGS}" helloworld.c -o helloworld
Or this one for the GNU C++ Compiler:
source /opt/bin/gcc_env.sh && g++ "${CFLAGS}" -I/opt/include "${LDFLAGS}" \
helloworld.c -o helloworld
💡 Note: Environment variables are applied automatically in the latest gcc package. Always attempt to build with the environment you have upon starting the shell first before making changes.
If you find yourself forced to attempt to "finesse" the compilation flags to achieve a working build of something, a good place to start is always the compiler's default target for your particular architecture. You can print them to the console in their entirety with this single command:
gcc -march=native -v -Q --help=target
On rare occasions, there can be some utility in comparing the compiler/precompiler defines with the project's header files. You can print the defines to the terminal using
echo | gcc -dM -E - -march=native.
Let's use GCC to build the GNU Screen binary. The project documentation informs us that screen depends on libncursesw and that it uses GNU Autotools to configure new builds, so install those first, then download and extract the source code archive. Inside you're likely to find specific tips on building the project written by the developer(s), often in one or more files named README, INSTALL or broken down by platform under a doc/ directory. These can be read comfortably in the terminal using the command: ${PAGER:-/opt/bin/less} [filename] (if that produces an error, install a pager program like less, more or most using opkg).
The following sequence of commands demonstrates a pain-free progression from first downloading the source code tarball, verifying its integrity and extracting its contents, setting the build configuration, then finally compiling the code. It's almost never this easy.
| ⚠️❗ Attention: ❗⚠️ |
|---|
You should always pass the prefix flag to an Autotools configure script, as in sh ./configure --prefix=/opt, and it is not at all uncommon to need to do likewise to any other options the project exposes that involve file paths (e.g. --sysconfdir, --sharedstatedir, --runstatedir, etc. You can see a list containing them all using the command sh ./configure --help.) and pointing them to a location analogous to their default but inside the /opt directory, where you have full permissions to read, write and execute files. |
Not all steps will apply to all projects; common sense must always prevail. This is an attempt to illustrate the use of "best practices" for the task in general, not a set of hard and fast rules that need to take place for a successful result.
- Confirm that you have all the packages you need installed, for the build system and any dependencies the project needs
opkg install gcc libc libgcc autoconf automake m4 make libtool-bin pkg-config libncursesw libncurses-dev terminfo gnupg2 ldconfig ldd - Create a new empty directory to contain everything and make it the working directory
mkdir /opt/tmp/source && cd /opt/tmp/source - Download the source code archive file (tarball) you're interested in
wget http://ftp.gnu.org/gnu/screen/screen-4.8.0.tar.gz- If it's signed for authenticity, download the signature too
wget http://ftp.gnu.org/gnu/screen/screen-4.8.0.tar.gz.sig - Download the public key of the signer, either by downloading a keyring file like below or with the key ID published on the download page
wget https://ftp.gnu.org/gnu/gnu-keyring.gpgorgpg --keyserver hkps://keys.openpgp.org/ --recv-keys [KEY_ID] - Use GnuPG to verify the signature against the public key/keyring file
gpg --verify --keyring ./gnu-keyring.gpg ./screen-4.8.0.tar.gz.sigorgpg --verify ./screen-4.8.0.tar.gz.sig
- If it's signed for authenticity, download the signature too
- Uncompress the archive file
/opt/bin/busybox tar xvzf ./screen-4.8.0.tar.gz - Make the newly-expanded source code folder the working directory
cd ./screen-4.8.0 - Verify that all the Autotools files are present and up-to-date
autoreconf -vfi - Run the
configurescript, making sure you at least set the --prefix flag (a list of all available options can be printed withsh ./configure --help)sh ./configure --prefix=/opt --sharedstatedir=/opt/var/lib --with-socket-dir=/opt/tmp/screens --with-sys-screenrc=/opt/etc/screenrc
It is critically important to use --prefix=/opt if the package creates executables or shared libraries, or for any project you intend to install using the make install command, instead of moving/copying the files yourself in the shell. It's also a good practice to carefully review the list of available configuration options to discover if any are used to define the default paths for the program's working files. These will almost always need to be supplied along with the prefix to the configuration script rather than using the defaults, as was done in the example above (note that the final two option flags above are specific to building GNU Screen and not applicable to most Autotools builds, though the first two are). Since Entware itself lives in a non-standard path and is most often running on embedded devices whose root filesystems are read-only, causing software that's built expecting to write information there to crash or otherwise behave unpredictably.
Now invoke GNU make to execute the configured build, using as many cores as your device's CPU has, and (optionally) turn on verbose output by adding V=1 to help troubleshoot any errors that arise:
make -j$(nproc) V=1
If the process completes without error, you will find the screen binary in the working directory. To examine the shared objects it was linked to, do:
$ ldd ./screen
libncursesw.so.6 => /opt/lib/libncursesw.so.6 (0x4011a000)
libcrypt.so.1 => /opt/lib/libcrypt.so.1 (0x4017f000)
libgcc_s.so.1 => /opt/lib/libgcc_s.so.1 (0x4009f000)
libc.so.6 => /opt/lib/libc.so.6 (0x401be000)
libdl.so.2 => /opt/lib/libdl.so.2 (0x402f9000)
/opt/lib/ld-linux.so.3 (0x400e7000)
This binary appears to be exactly as we'd hoped. Specifically, what you want to see is:
- It only uses shared objects from
/opt/libor (rarely) elsewhere under/opt, and - The correct dynamic linker,
/opt/lib/ld-linux.so.3was used (you can confirm this against the table of dynamic linkers above).
You can run the newly-compiled binary in the build tree to ensure it functions as expected prior to installing it:
LD_LIBRARY_PATH="$(pwd)${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH:-/opt/lib}}" ./screen
If you're satisfied with what you saw, you can complete the process by installing it alongside the files from your Entware packages, but first do a dry run using make --dry-run install and check to see that all of the target paths look well-formed. If so, you can install the fruits of your labors and retreat out of the build directory and delete it (assuming you have no further use for the contents).
# Actually execute the install commands printed in the dry run
make install
# Some projects that build shared libraries require that the list of shared
# objects be refreshed manually after installation, and will print a message
# roughly to that effect among the install command output. If you see one, then:
ldconfig -v
# Return to the parent directory and list its contents to be sure you're not
# deleting anything important
cd .. && ls -lFAhkp --group-directories-first
# Delete your downloads from earlier
rm -iv screen-4.8.0.tar.gz* gnu-keyring.gpg
# Likewise, delete the extracted contents of the source code archive
rm -Rfv ./screen-4.8.0/
========= End


浙公网安备 33010602011771号