Fatal: The 'prepare' command must be used on the source tree

DESCRIPTION:

To build my project in QtCreator, I used to add sfdk prepare %{buildDir} as custom build step, but this doesn’t work anymore with SDK 3.10.4. Worked fine till 3.9.6.

STEPS TO REPRODUCE:

  1. Try to build a project that uses %prep with QtCreator. I can provide my spec file if needed.

EXPECTED RESULT:

Project should just build.

ACTUAL RESULT:

Fatal: The 'prepare' command must be used on the source tree.

1 Like

Following the error message hint, I’ve also tested sfdk prepare %{sourceDir}, but that returns Fatal: The command needs to be used from the top of a build tree. See the 'build-init' command..

Following last error message hint, I’ve also tested sfdk build-init %{sourceDir}; sfdk prepare %{sourceDir}, but this returns Fatal: Refusing to prepare dirty work tree - commit or reset your changes first..

I’m lost now.

Got it working by setting the no-vcs-apply option this way:
sfdk config --push no-vcs-apply

2 Likes

I’m not sure to understand. Is this a workaround?

I don’t know either. I really didn’t know how to solve it when I reported it, but now I would like to get a confirm by some SDK dev.

Before I go into details, I’ll start with: sfdk prepare isn’t designed to be used as a build step in QtCreator. It’s designed to be executed from command line. Trying to use a tool in a way it’s not designed for is almost never a good idea.

Now the details:
sfdk prepare does not take build dir or source dir as a parameter. Trying to add %{buildDir} or %{sourceDir} there does nothing.
When you first tried running it, you had shadow build enabled in your project settings. sfdk prepare detected it, and tried to give you a hint that you should change your current directory to the source directory before executing the command.

As I wrote earlier, sfdk prepare does not take source directory as a parameter, so the change in the error message is not because of that. I suspect you disabled shadow build in your project settings, or you added cd %{sourceDir} before the prepare command. The error message means that sfdk prepare should be used from top of a build tree. The previous message said that it should be used on the source tree. A quick 1+1 calculation shows that sfdk prepare is not really well suited for shadow builds, as it must be used simultaneously on a build tree and a source tree. However, the sfdk build-init command can be used for turning the source tree into a build tree as well, which is what you did next.

You most likely actually executed these commands on the source tree. sfdk build-init accepts source directory as a parameter, but in this case the directory is already the current directory so the sourceDir parameter does nothing. But your source tree is now also a build tree, so sfdk prepare could progress a bit further. Note that the %{sourceDir} parameter is still ignored. Next, sfdk prepare detects that your sources are stored in git, and your source tree contains changes which are not committed, and refuses to continue. This is mostly a safety measure - we want to be sure that the sources are in a know state when we start the actual build. So ideally, you have the sources from git, and then sfdk prepare does whatever preparation needs to be done (typically applies patches). But now you have something else there as well and we don’t know the actual state of your source tree.

This pretty much just turned off the above mentioned safety mechanism. Instead of doing this, you would be much better of either committing your changes before running sfdk prepare, or duplicating the changes as part of the %prep section.

So, to recap:

  1. Don’t try to use sfdk prepare as a build step in QtCreator
  2. If you really have to use sfdk prepare as a build step in QtCreator, don’t use shadow builds
  3. If you really must use shadow builds, change to source tree first, then run sfdk build-init before sfdk prepare
  4. Don’t make uncommitted changes to the source tree before running sfdk prepare
1 Like

Thank you a lot for the great and detailed answer @vige!

Let me clarify some point:

I’ll start with: sfdk prepare isn’t designed to be used as a build step in QtCreator.

I need to because %prep doesn’t work in QtCreator and that’s the only workaround I’ve found.

sfdk prepare does not take build dir or source dir as a parameter. Trying to add %{buildDir} or %{sourceDir} there does nothing.

I’m sorry I didn’t specify it before, but since I was talking specifically about QtCreator what I meant there is that I put sfdk in the command field, prepare in the argument field and %{buildDir} in the working dir field.

I suspect you disabled shadow build in your project settings

I don’t know what a shadow build is, nor if I should use it or not for my project. However, it’s enabled (I guess it’s by default?).

What exactly are you doing in your %prep section? I’m just starting to think that perhaps you have something in there which should really be part of the %build section.

The %prep section should only be used for preparing the build environment before the first build, and not during any following builds. And since it’s supposed to be run only once, I wouldn’t spend any time trying to find workarounds for executing it within QtCreator. Instead I would just run it from the command line before doing any builds in QtCreator.

Shadow build means building in a separate directory, as opposed to building on the source tree. Yes, it’s enabled by default in Qt Creator.

This is my spec file.

I extract a tarball during the %prep section. %setup -a 1 works on OBS, but I use tar xf explicitly to get it working with mb2.

Since I switch between all the architectures (or the upstream application version) from QtCreator, it helps me to extract this archive “on the fly”.

Maybe in the end this thread is only about mb2 ignoring %setup -a 1?

Thanks for the link to the spec file. Yes, extracting source tarballs is something that one would normally do in the %prep section. However, your case is a bit special as you have different tarballs for each architecture.

The only way to do this “cleanly” would be to have the sources for different architectures in separate subdirectiories, so you could have them existing on the source tree simultaneously. But then again, I’m starting to think that the workaround you mentioned, i.e. using no-vcs-apply might just be the best solution for you. But just for the sake of possible future readers of this thread: This is not generally recommended!

No. That’s another thing. Maybe even a bug, I’m not sure.

Just chiming in to say that this is really really annoying when i’m trying to contribute to system packages involving rpm spec and patch changes. Turnaround times for testing changes are at least doubled.

It didn’t use to work like this, right? Please reconsider.

The way it works is especially designed for making it as easy as possible to contribute to system packages, involving rpm spec and patch changes. git commit takes literally seconds. Somehow I get the feeling you are not using the tool the way it was designed to be used - which is really our fault as we haven’t really advertised the correct approach much, as we have thought it’s mostly used internally at Jolla. But here’s how it’s supposed to be done:

  1. before you start hacking around, you run sfdk prepare - which will apply the patches and possibly other preparations for the build tree.
  2. sfdk build - it’s important you do this once before starting hacking, so that you know that the sources are in a buildable state. Any issues you encounter later are because of the changes you have made.
  3. make changes to the sources. If you want to edit earlier patches, use e.g. git rebase -i. Otherwise, the changes will become a new patch.
  4. repeat steps 2 and 3 until you are satisfied with how the package works.
  5. git commit your changes
  6. run sfdk scrape to extract patches
  7. edit the RPM SPEC file to include your new patch, if there is one.
  8. git commit your changes to the SPEC and patches
  9. make a PR.

I wasn’t aware of scrape, but otherwise that’s just about the process i have been following. Not wanting to prepare a dirty upstream is fine.
The problem/annoyance i’m facing is around point 7-8 in the list - whatever i do i have to commit on top level to run the prepare step. Perhaps i have been a bit prepare-happy… but i have long-cultivated trust issues with not building all the way from the beginning.

That sounds only healthy - there are countless cases where a developer has created a PR, only to discover later on that the changes don’t build on a clean build tree. I should have included a step between 8 and 9, let’s call 8.5 now: git clean -f -x -d followed by sfdk build --prepare to make sure everything really compiles from a clean tree.

But that was besides the point you were making, sorry about that.

Yes, you do. That is by design. git commit literally takes seconds, and it gives you the benefit of knowing exactly what you have done, just by looking at the latest commit. And when you are iterating things, you can use git commit -a which takes even less than that. I’m quite sure it’s really insignificant compared to the time it has already taken you to make changes, and the time it’s going to take to build the package.

This is fair, but so does the other steps… making this noticeable.
Sometimes i don’t really know what i’ll end up doing and writing a commit message, and again this is a habit, but if you start writing derp or lol as a commit message, sooner or later that gets pushed. So i try to avoid that. Kind of reminds me working with IBM ClearCase as a VCS - we’d have to give a check-out comment to get to edit the file. :slight_smile:

I’d argue that this is what git diff is for normally. The build will not really change the top level repo that i have noticed.

For rpm spec changes in particular, no, not really.

Anyway; now you know my complaints… but i guess we’ll just have to agree to disagree.