Recommended methods for custom software

Hello. I’m working on deploying a custom image to my board which uses the Orin NX and Jetpack and L4T will be used.
I want to ask, what is the best method for deploying the custom software, these were the methods I could think of:

  • Flash jetpack to Orin
  • Inside the board, get binaries from a local server/git/whatever and setup things manually (scripts, …)
  • Create debian packages for all the software needed
  • Flash jetpack to Orin
  • Move debian packages inside and install them with apt (would it be possible to do this when flashing/building?)

Are there other “recommended” methods?

I can tell you my preference, which in turn depends on the software. Roughly what is the software? Is it used in boot, or just run by the end user? Is it a shell script, python script, or a binary with linking to libraries?

Note that the content in “Linux_for_Tegra/rootfs/” is flashed nearly verbatim. There is some content copied in for the kernel, device tree, and boot settings based on the target. Most of what goes into that directory will be flashed and left in place exactly as you put it there.

There might also be legal implications. Having your software installed by the end user, and only copying it to a convenient location, could be different than preinstalling it. As an example, NVIDIA ships the flash software and the Ubuntu image as separate packages. Then the end user (either directly on command line or via ok in JetPack) installs the NVIDIA content on top of the otherwise purely Ubuntu set of files. This means NVIDIA does not have the same obligations that it would have if NVIDIA had preinstalled its files into the Ubuntu image; the end user doing this instead of NVIDIA has implications. Also, in California, you would have trouble if you ship a default login account with a default login password…this is why NVIDIA switched to the first boot setup. If your program is just your program and not something special, and if you don’t need the end user to agree to anything, then you might consider just preinstalling rather than simply adding a copy for the end user to run the install on.

I was thinking about .deb so later OTA updates to the software would be easier…

Yes, packages are mandatory for OTA, at least if it is going to be reliable. One advantage you can make is to create a dependency between your software and some other software if you want that other software to not upgrade to an incompatible release.

I do have another question. In the flashing process, I’ll need custom software probably written in C/C++. Another issue I’m thinking is, should that software be compiled outside ? Couldn’t that lead to libc/… issues?

I might follow the “custom rootfs” approach, but there are some edge cases I’m worried about (should I compile inside to avoid issues? pre cross-compile the software I need for the specified arch?) …

Is your software entirely user space? Or is there driver or kernel code? Is there code related to boot?

If your software is purely user space software, i.e., an ordinary program run by a user, then it might link to other libraries. If you link against the major release version of the o/s as compiled on the Jetson, or with a sysroot from such a Jetson while cross-compiling, then it should work. You can mark the glibc major release as a dependency if you wish.

If you are looking at a common user space binary executable, then you can get an idea of its library linkage from ldd. For example, if you have binary executable “/usr/bin/ls”, then you can see what it dynamically links against like this:
ldd /usr/bin/ls

Software can be compiled with static linkage as well if you have the source code, but that’s usually for portability reasons and not necessarily all that useful for a typical user space program. This also tends to consume a lot of disk space.

Note that any library usually has a major version, a minor version, and a patch release. Quite often major release compatibility is all that is needed. If you want to see what libraries are in your system’s default linker path, and to see the link between some major and minor release equivalents, try this:
ldconfig -p

Note that you will get an “alias” for a lib of some major release, and that this will point at a more specific file or location that is more detailed; this file in turn can also point to some more detailed release version. Most programs link to the least specific version, not the more specific version.

Unless you have a scripted program, e.g., Python or shell scripts as an example, your binary executable will have to be against the Jetson’s architecture. You cannot compile on a host PC as an x86/x86_64/amd64 architecture and get it to work on a Jetson. You have to compile it against 64-bit ARM (armv8-a/aarch64/arm64). This latter is automatic if you compile natively on the Jetson. If you’ve specified this in a cross compile and are linking on the host PC against the Jetson’s sysroot, then this also works. It’s quite difficult to answer this without more information about many details.

It’s user programs usually.
Thank you for the support and opinions.

What about docker containers? Is it a reliable/used method as well?

I’m not really a “Docker guy”, but Docker has shown itself to be useful and reliable on Jetsons. Beware though that you might be reproducing some of the content and using more space. If you want to develop particular scenarios with Docker, then you might want to start a new thread on the forums with Docker in the title. I think several people here could help with that if you give more details. I don’t know enough about Docker though to be of much use.