phlash / obs-backscrub

Integration for backscrub project into OBS Studio
Apache License 2.0
11 stars 3 forks source link

CMakeLists.txt assumes backscrub build directory layout #3

Open ali1234 opened 3 years ago

ali1234 commented 3 years ago

The CMakeLists.txt allows to override the BACKSCRUB variable to specify the path to the backscrub repository:

https://github.com/phlash/obs-backscrub/blob/de6c75f4a57a0ca69b9e4ee7cb8d047eef78679b/CMakeLists.txt#L10-L12

Then it does two things with this variable. It sets LIBBACKSRUB_INCLUDE_DIR, which needs to point to the source repository:

https://github.com/phlash/obs-backscrub/blob/de6c75f4a57a0ca69b9e4ee7cb8d047eef78679b/CMakeLists.txt#L16

and also it includes a file from the build directory:

https://github.com/phlash/obs-backscrub/blob/de6c75f4a57a0ca69b9e4ee7cb8d047eef78679b/CMakeLists.txt#L15

Here the build directory is assumed to be within the source repository with no way to override. This is not necessarily the case. The cmake build directory can be anywhere, and in the case of building a snap package, it will be along side the source, not inside it.

phlash commented 3 years ago

Good point. I'm not sure I want to insist on installing backscrub before it can be used in another project (and installing backscrub currently doesn't install the dependencies list file BackscrubTargets.cmake, this may be a bug!). I think I would rather be able to pull in backscrub as a sub-project via cmake's add_subdirectory().

Right now I do neither and have this fragile dependency between my projects because I'm lazy and wanted to avoid re-compiling Tensorflow Lite everywhere. I'll try using backscrub as a proper sub-project, if I can avoid the TFLite compile that would be a bonus..

ali1234 commented 3 years ago

It should be possible to make backscrub work as either a sub-project or installed, but unfortunately it is currently beyond my understanding of cmake. I'm looking in to it though. What I found so far is that the BackscrubTargets.cmake cannot be installed because it refers to the build directory. You have to make a BacksrubConfig.cmake and that is a bit more complicated. No reason you can't have both though.

ali1234 commented 3 years ago

Here is obs-backscrub reworked to have backscrub as a submodule:

https://github.com/ali1234/obs-backscrub/tree/bs-submodule

Note that it points to my fork of backscrub as I have made changes to both CMakeLists.txt to facilitate this.

Also note that I have patched the default model path in obs-backscrub so that it points to the location needed for a snap. That definitely won't work for you.

What has been done in backscrub:

The above changes are not strictly necessary for this but they make the layout easier to understand, as a large amount of code can be removed from the top level CMakeLists.txt. Then:

Again, these aren't strictly necessary and only affect installation which we don't use when backscrub is a submodule. Then finally:

The effect of this is that when you add backscrub as a subdirectory and add libbackscrub as a dependency on obs-backscrub, cmake automatically knows to add the dependency's include directories. So now you don't need those path variables. Or BackscrubTargets.cmake, because you already have the actual target from the real CMakeLists.txt.

So after all this, you can now make one build directory and call cmake on the top of the obs-backscrub project, and it will build everything and optionally install it. The following will be installed in CMAKE_INSTALL_PREFIX:

lib/libbackscrub.a
include/libbackscrub.h
share/backscrub/models
share/backscrub/models/body-pix-float-050-8.tflite
share/backscrub/models/deeplabv3_257_mv_gpu.tflite
share/backscrub/models/segm_lite_v681.tflite
share/backscrub/models/retrain.md
share/backscrub/models/selfiesegmentation_mlkit-256x256-2021_01_19-v1215.f16.tflite
share/backscrub/models/body-pix
share/backscrub/models/segm_full_v679.tflite
bin/backscrub
lib/obs-plugins/obs-backscrub.so

All of this builds, the backscrub executable works, and the OBS plugin works too as long as it can find the model.

The next step would be to create an installable BackscrubConfig.cmake so that the install libraries and headers are usable without needing backscrub as a submodule, and also fix up both projects so that they check /usr/share/backscrub/models for the model files.

phlash commented 3 years ago

Good work! I've just been doing similar in my tree, but didn't want to munge the existing backscrub system about (that's a separate challenge that needs agreement from Ben & Florian), so I've created a cmake find-module (FindBackscrub.cmake) for backscrub, pushed to my experimental fork.

This finds and pulls in the BackscrubTargets.cmake export file (which defines all the targets and dependent libs) it then sets two variables as per normal find modules: BACKSCRUB_INCLUDES and BACKSCRUB_LIBS that are used to build super-projects.

Here I have just pushed a modified CMakeLists.txt that uses this find module to remove internal knowledge of backscrub.

ali1234 commented 3 years ago

As long as you know where the backscrub source is you can just add it directly like this:

https://github.com/ali1234/obs-backscrub/commit/2f7ef5cd4c0160b93c3c90b7ff632a723b01d0aa

This will work against backscrub main. You don't need to build it, just set BACKSCRUB to wherever the source is. The standalone app won't be built and install will do nothing, due to the EXCLUDE_FROM_ALL directive.

You do not need to find and use BackscrubTargets.cmake at all.

phlash commented 3 years ago

Yep, I'm aware that using backscrub as a sub-project will build everything and get all the dependencies correct, it also means a whole Tensorflow download/build which is several minutes (on my laptop anyhow!) and 100s of MB. Using backscrub as an external (pre-built) package avoids this in my situation where I work on backscrub as a separate project from this one, and simply want to re-link this occasionally. Supporting both mechanisms could be an option via a cmake config variable?

Using a git sub-project reference to pull in backscrub is also how we reference Tensorflow in the backscrub build, and would work similarly here, hopefully with the right cmake voodoo we can also avoid a checkout if referring to an external backscrub build instead.. I'll have a play!

phlash commented 3 years ago

OK! The top-level CMakeLists.txt now builds with backscrub as a sub-module by default, or as an out-of-tree external library if you provide a location (-DBACKSCRUB=<path>).

Some tidy-up to export the include path(s) in the backscrub project would be helpful but I think this is a good start?