You may know me from former titles such as “Batocera Linux Buildroot Modifications” and “How to work on Batocera (and not recompile everything)”.
RPi3, the “per platform” example used here, was formerly known internally as rpi3 in Batocera v35 and lower. This is now bcm2837 in v36 and higher.
If you'd instead like to only test certain config files (like es_features.cfg), you can edit them directly in the live system and save them via overlays.
Compiling the entirety of Batocera is optional, but recommended as it automatically sets up your enviroment for compiling individual packages. batocera.linux is based on Buildroot, manual available here.
For each package (ie. kodi, emulationstation), Buildroot does the following:
More exactly:
package/package-name/package-name.mk or package/batocera/package-name/package-name.mkoutput/build/package-name-version*.patch files (files next to the .mk file or board/batocera/patches/ or board/batocera/bcm2837/patches/).mk file.mk fileoutput/bcm2837/host/ staging directory, in case of librariesoutput/bcm2837/target/ directory
For each step, Buildroot creates an empty flag file. For example: .stamp_downloaded in output/bcm2837/build/package-name-version.
In case a step failed, just run make or make package-name again to restart/continue the build where you left.
To completely rebuild a package (for example an RPi 3 package):
rm -rf output/bcm2837/build/package-name-version make package-name
For example, to build EmulationStation again from the latest master git version:
rm -rf output/bcm2837/build/batocera-emulationstation-master make batocera-emulationstation
Individual packages can also be compiled using the container using:
make x86_64-pkg PKG=batocera-splash
replacing the components as necessary.
Although this will build package itself, it does not do so in the same way that the regular make x86_64-build does. Using a package build cannot be used for testing a package's successful build, always use -build or -cleanbuild to confirm before making a pull request.
When you clone the batocera.linux git repository, you mainly get the following directories:
.config: the list of all packages, stating if you are going to build it or not.dl: the directory where all files are downloaded, for example, batocera-emulationstation-master.tar.gzoutput: the directory where everything is built.In other words, in order to reinitialize your build, you can type:
rm -rf .config dl output
I personally use the following command to confirm I have no other remaining files:
git status --ignored
My dl directory is a link on ../DL in order to use the same download directory for all my builds, to avoid to download the source archives each time again and again. Note that you may have to remove some packages like batocera-emulationstation-master.tar.gz or batocera-configgen-master.tar.gz while the contains is the master branch of their respective git repositories. In other words, whenever the content is dynamic (master) and not a precise GitHub version. If you commit something on configgen, while the file is in the dl directory, buildroot will not download it again as it is seen as the same filename.
EmulationStation is a separate git repository from Batocera system. To work on EmulationStation, the simplest way is to directly get it on your computer and compile it without buildroot.
This is for generic packages that aren't necessarily emulators.
The following is a (very) brief summarization of chapter 19 of the Buildroot manual. It is recommended to read that in full in case of any questions.
Todo:
package/batocera/utils/package-name/.
It's worth checking if the package you want is already included in buildroot, just check in the buildroot/package/Config.in file. If so, skip steps 2 and 3.
Config.in file. This should contain the package's “metadata” for compilation purposes. Add into this file its:config BR2_PACKAGE_<package>bool "<package shortname>"depends on BR2_PACKAGE_<other package>
For more information on Buildroot's Config.in syntax, refer to chapter 16.1 in Buildroot's manual.
.mk extension: <package-shortname>.mk<package>_VERSION = <commit hash> <package>_SITE = $(call github,<author>,<repository>,$(<package>_VERSION))
<package>_CONF += <options>. For example: GZDOOM_CONF_OPTS += -DCMAKE_BUILD_TYPE=Release -DDYN_GTK=OFF -DDYN_OPENAL=OFF
<package>_CONF_ENV += <environment variables>. For example: GZDOOM_CONF_ENV += ZMUSIC_LIBRARIES="/x86_64/target/usr/lib/" ZMUSIC_INCLUDE_DIR="/x86_64/target/usr/lib/cmake/ZMusic/"
define <package>_BUILD_CMDS. Inside of that function, be sure to use the appropriate flag to set the correct working directory: $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) The “make” compiler uses its own instance, which may not be sharing the same current working directory. A generic compilation script would be as follows: define <package>_BUILD_CMDS $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) endef
define <package>_INSTALL_TARGET_CMDS mkdir -p $(TARGET_DIR)/usr/bin cp $(@D)/output_executable $(TARGET_DIR)/usr/bin endef
$(eval $(generic-package)).For more information on Buildroot's makefile syntax, refer to chapter 16.2 in Buildroot's manual.
package/batocera/core/batocera-system/Config.in. This is where you would refer to its Buildroot package header, not its shortname.Config.in. That's right, the file in the root directory of the repo.An example of a recent pull request that adds a simple package: https://github.com/batocera-linux/batocera.linux/pull/5812/files
/usr/share/batocera/data/..keys file to <shortname>.<emulator>.keys.config BR2_PACKAGE_BATOCERA_ALL_SYSTEMS under the #### systems #### section./usr/lib/python#.#/site-packages/configgen/Generator Importer.py)if emulator == '<emulator name>' from generators.<emulator name>.<emulator name>Generator import <CamelCased emulator name>Generator'')
In Batocera v34 and earlier, this process is instead:
from generators.<shortname>.<shortname>Generator import <CamelCased shortname>Generator, shortname is the system name) with its system shortname here: https://github.com/batocera-linux/batocera.linux/blob/master/package/batocera/core/batocera-configgen/configgen/configgen/emulatorlauncher.py (you can test this locally with /usr/lib/python#.#/site-packages/configgen/emulatorlauncher.py). The commandArray is ultimately the line that is used to run the emulator from bash.configgen.generators.<shortname>) here: https://github.com/batocera-linux/batocera.linux/blob/master/package/batocera/core/batocera-configgen/configgen/setup.py.generators/<shortname>/ folder.If you'd like an example of a recent pull request that adds a whole new emulator: https://github.com/batocera-linux/batocera.linux/pull/4742/files
Buildroot features the ability to patch the source code of a package before compiling it, read section 19.2 in the buildroot user manual for more info. Here we will do a quick rundown.
Let's say you want to work on the package “retroarch” to make it evolve via a patch.
First, compile a complete version of Batocera for the architecture you will test. In this example, we will do so for RPi3.
cd batocera.linux make bcm2837-build
Once this is done, you don't need to build the entirety of it again for your tests. You can just rename/remove the output's target folder for that architecture, like so:
mv output/bcm2837/target output/bcm2837/target_
Now for our patch. First change the working directory to that of the build folder for the respective package:
cd output/bcm2837/build/retroarch-version
Establish the package state using git:
git init
Then add the file(s) you want to modify to the current commit:
git add <the file(s) you modified>
Add all files with git add -A.
Make the modifications to the files you want now.
Then compare the differences and save them to a “patch” file:
git diff > ../../package/batocera/retroarch/001-mymodification.patch
Now clear out the package's respective build folder to make way for testing a new build with it:
cd ../../.. rm -rf ouput/bcm2837/build/batocera/retroarch-version
Then build the package (replacing make if using a different make tool):
make retroarch-patch # to confirm the patch is applied make retroarch # to finish other steps
It's possible to compile just the package you've modified and then transfer it over to your live Batocera installation using rsync. First, compile the individual package as explained above with make bcm2837-pkg PKG=<package name> and then run:
rsync -av output/bcm2837/target/ root@batocera.local:/
This will sync up the contents of the target directory on your build machine with the Batocera machine. Feel free to immediately test your changes. If the changes are bad and you need to restore, simply reboot and the changes will not persist. To have them persist instead, run batocera-save-overlay from the machine itself.