I have a recipe to compile a printer driver and have a few simple lines to run in do_install.
do_install() {
install -d ${D}${libdir}/cups/filter
install -m 755 ${B}/src/rastertoprinter ${D}${libdir}/cups/filter/
install -d ${D}${sysconfdir}/cups/ppd
install -m 755 ${B}/../rastertoprinter/printer_name.ppd ${D}${sysconfdir}/cups/ppd/
}
To compile the source I have a DEPENDS on cups and also an RDEPENDS on cups as the OS needs cups installed to print of course.
The printer driver is not publicly available so as such I've renamed it to rastertoprinter and changed my path names.
Essentially I need to simply create or ensure the directory /usr/lib/cups/filter exists, and copy the rastertoprinter program there. I also need to create or ensure the directory /etc/cups/ppd exists and copy the .ppd file into that directory.
The first two lines run fine but the 3rd throws the following errors:
file /etc/cups conflicts between attempted installs of printername-r0.corei7_64 and cups-2.2.2-r0.corei7_64
file /etc/cups/ppd conflicts between attempted installs of printername-r0.corei7_64 and cups-2.2.2-r0.corei7_64
I don't understand why both recipes can't create this directory and put stuff in it? Strangely I'm able to do the first /usr/lib/cups/filter directory though fine.
Turns out the issue is that each file to be packaged in Yocto will also generate a %dir for each parent of each file. We don't want to own a directory that is owned by another package, so if you add this to your recipe:
DIRFILES = "1"
It will cause your package to not own parent directories of the files you package.
This will generate an rpm spec file without the %dir entries.
Related
I am trying to build a dev package out of some .so files - i.e libraries.
dh_make -f ../ mylibs.tar.gz
then I choose
-l
since I want a library package.
A debian folder is created which consists of among others the controlfile and the install file.
When I finally create the package with
dpkg-buildpackage
I get the following error message:
dh_install: mylibs-dev missing files (usr/include/*), aborting
I dont understand what is missing since the headers are copied to
usr/include
I have checked the directory and the headers are copied there. So why do I get this error message?
the install-file look like this:
usr/lib/lib*.so.*
So - may the path to usr/include be missing here? I've tried with
usr/include/h.*
but it does not work
The debian install files are most often used for source packages that produce several binary packages. In that case, dh_auto_install installs to the directory debian/tmp/ and dh_install moves the files from there to each package. However, when there is a single package, dh_auto_install takes a shortcut and installs directly to debian/package-name/. In that case, you only need to list in the install file the files that make install missed (usually none). If you list the regular, installed files, dh_install will get confused because it is still looking for them in debian/tmp/.
It is possible to override either the directory where dh_auto_install installs, or the directory where dh_install is looking, but you probably don't need either.
I created a binary package with this command:
dpkg-deb --build -z9 -Zlzma $(DEB_SRC_DIR) $(DEB_DEST_DIR)
and install it on my Ubuntu 12.04 with this command:
sudo dpkg -i /path/to/package
The contents of the package I think are irrelevant.
Despite the sudo command the files in the installation directory belong to the current user and not to root as I expected.
How can I fix that?
Try to run the dpkg-deb command with fakeroot:
`fakeroot dpkg-deb ...`
(This will only help if the files in the source directory already have the correct ownership, which they probably dont. The problem you're actually trying to solve here, is to create an archive with files in it that belong to user root, which is where fakeroot theoretically helps.)
Let me say though, that what you are doing is not the best way for creating a binary package (far from it).
Instead, create a debian/ directory with dh_make (from the dh-make package), and edit the control file and changelog accordingly. You also need a file debian/install that lists what files you are installing and where they should go. There are various guides on the net (and on Stack Overflow) that explain this process. For example, look at the Debian New Maintainers' Guide.
You can then use dpkg-buildpackage to create a real, standard-conforming Debian package with your files in a reproducible way.
dpkg-deb is a low-level tool for manipulating existing deb files; it's not meant to be used for package creation.
I have a debian package that I built that contains a tar ball of the files, a control file, and a postinst file. Its built using dpkg-deb and it installs properly using dpkg.
The modification I would like to make is to have the installation directory of the files be determined at runtime based on an environment variable that will be set when dpkg -i is run on the deb file. I echo out the environment variable in the postinst script and I can see that its set properly.
My questions:
1) Is it possible to dynamically determine the installation directory at runtime?
2) If its possible how would I go about this? I have read about the rules file and the mypackage.install files but I don't know if either of these would allow me to accomplish this.
I could hack it by copying the files to the target location in the posinst script but I would prefer to do it the right way if possible.
Thanks in advance!
So this is what I found out about this problem over the past couple of weeks.
With prepackaged binaries you can't build a debian package with a destination directory dynamicall determined at runtime. I believe that this might be possible if installing a package that is built from source where you can set the install directory using configure. But in this case since these are embedded Ubuntu machines they don't have make so I didn't pursue such an option. I did work out a non traditional method (hack) for installing that did work. Since debian packages simply contain a tar ball relative to / simply build your package relative to a directory under /tmp. In the postinst script you can then determine where to copy the files from the archive into a permanent location.
I expected that after rebooting and the automatic deletion of the subdirectory under /tmp that dpkg might not know that the file package existed. This wasn't a problem. When I ran 'dpkg -l myapp' it showed as still installed. Updating the package using dpkg/apt-get also worked without a hitch.
What I did find is that if you attempted to remove the package using 'dpkg -r myapp' that dpkg would try and remove /tmp which wasn't good. However /tmp isn't easily removed so it never succeeded. Plus in our situation we never remove packages but instead simply upgrade them.
I eventually had to abandon the universal package due to code differences in the sources resulting in having to recompile per platform but I would have left it this way and it did work.
I tried using --instdir to change the install directory of the package and it does relocate the files but dpkg fails since the dpkg file can't be found relative to the new instdir. Using --instdir is sort of like a chroot. I also tried --admindir and --root in various combinations to see if I could use the dpkg system relative to / but install relocate the files but they didn't work. I guess rpm has a relocate option that works but not Ubuntu.
You can also write a script that runs dpkg-deb with a different environment for 6 times, generating 6 different packages. When you make a modification, you simply have to run your script, and all 6 packages gets generated and you can install them on your machines avoiding postinst hacking!
Why not install to a standard location, and simply use a postinst script to create symbolic links to the desired location? This is much cleaner, and shouldn't break anything in dpk -I.
In the process of building an RPM package, I have to specify the BuildRoot and later will be used in %install which invovles $RPM_BUILD_ROOT. I always think that $RPM_BUILD_ROOT is the fake installation for RPM to perform packaging. Then, at install time using the RPM package, it will install into actual location. For example:
$RPM_BUILD_ROOT/usr/bin
I thought that $RPM_BUILD_ROOT is for the packaging process only, and in some ways RPM can distinguish the $RPM_BUILD_ROOT and the actual install location when the user performs "rpm -ivh package.rpm" will be /usr/bin.
But recently upon reading some documents, it is suggested that $RPM_BUILD_ROOT is the actual location which will be installed, and the $RPM_BUILD_ROOT is specified by user with the setting of environment variable $RPM_BUILD_ROOT in order to let the users install the package in their desire locations. Otherwise, $RPM_BUILD_ROOT will be null and it will install into the default location. In the above case, it is /usr/bin . Thus, $RPM_BUILD_ROOT is not just for packaging or "fake installation" process, but is a way for user to define install location, similar to select folder location in Windows.
I don't know my thinking is correct or not. Can someone please verify? Thanks in advance.
$RPM_BUILD_ROOT (or the equivalent %{buildroot} SPEC file macro) always holds the directory under which RPM will look for any files to package. The RPM scripts (e.g. the script that compresses the manual pages) will also use that value to know where to look for the files that were just installed. Normally, this value will be non-empty and contain a location away from the system directories - usually somewhere under /tmp or /var/tmp.
The author of the SPEC file is expected to make sure that make install (or whatever installer the software in question is using) will place any files under $RPM_BUILD_ROOT, with the same hierarchy that should be used when the software is finally installed. E.g. to have RPM install ls in /bin/ls, the %install SPEC file section should make sure that ls is placed in $RPM_BUILD_ROOT/bin/ls.
The author of the SPEC file is also expected to use the BuildRoot: tag to specify a proper location. Alternatively, the build system could have an rpmrc RPM configuration file with a proper entry. In any case the build root should be set, so that:
Normal users will be able to build the source package.
Should the superuser ever build the source package, the build process will not clobber any system files, unless the superuser installs the resulting binary package. And yes, there may be a good reason to build some packages as root - for example, running the full glibc testsuite requires root privileges for some tests.
That said, RPM can and will build a package with an empty build root variable. In that case both the build install and the final destination locations will coincide. A potential call to e.g. make install will use the default locations, thus clobbering the system files under e.g. /usr/lib if run with sufficient privileges. Additionally, having /usr/bin/* in your %files section will happily pull the whole contents of the build host /usr/bin/ directory into your binary package.
Bottom line:
Never use an empty build root.
Do not build packages as root unless there is absolutely no other way.
the file ~/.rpmmacros defines the paths per user:
%_topdir %(echo $HOME)/rpmbuild
%_tmppath %{_topdir}/tmp
and one can also define them with rpmbuild command line parameters:
rpmbuild --define '_topdir /home/username/rpmbuild'
I am using Fedora 10, I have created an rpm file for my software. It removes all the files from the installed directory. If i use yum remove command or rpm -e command. but after installation my application automatically creates some extra folders in home directory. If I uninstall my application then file from home directories do not get removed. So what I have to do. Is there anything that I have to write in my spec file?
You need to create a post-uninstall script inside your rpm.
The %postun Script
The %postun script executes after the package has been removed. It is the last chance for a package to clean up after itself. Quite often, %postun scripts are used to run ldconfig to remove newly erased shared libraries from ld.so.cache.
See: Maximum RPM: Taking the Red Hat Package Manager to the Limit