Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake: Adjustments to build config with OpenCV/Protobuf/Boost #604

Merged
merged 23 commits into from Jan 13, 2021

Conversation

ferdnyc
Copy link
Contributor

@ferdnyc ferdnyc commented Dec 24, 2020

This PR against the opencv project branch adjusts the CMake build configuration for the newly-introduced OpenCV components, dropping the use of output variables in favor of CMake targets so that dependency relationships are automatically propagated by CMake.

A new CMake option, ENABLE_OPENCV, is created, and defaults to ON. It can be explicitly set OFF with -DENABLE_OPENCV=0 on the initial cmake command line, or it should automatically disable itself if it fails to detect a usable OpenCV install on the system.

Users who have OpenCV installed somewhere not accessible to CMake by default may need to provide the path to its CMake configuration on the command line, using either:

  1. -DCMAKE_MODULE_PREFIX=/path/to/OpenCV/installation
  2. -DOpenCV_ROOT=/path/to/prefix/used/when/installing/OpenCV

cc: @BrennoCaldato

@ferdnyc ferdnyc added the build Issues related to compiling or installing libopenshot and its dependencies label Dec 24, 2020
@codecov
Copy link

codecov bot commented Dec 24, 2020

Codecov Report

Merging #604 (90e7ac4) into opencv (b6975ae) will decrease coverage by 2.96%.
The diff coverage is 71.42%.

Impacted file tree graph

@@            Coverage Diff             @@
##           opencv     #604      +/-   ##
==========================================
- Coverage   55.19%   52.23%   -2.97%     
==========================================
  Files         129      129              
  Lines       12366    10776    -1590     
==========================================
- Hits         6826     5629    -1197     
+ Misses       5540     5147     -393     
Impacted Files Coverage Δ
src/AudioReaderSource.cpp 0.00% <ø> (ø)
src/Clip.cpp 43.74% <ø> (-0.04%) ⬇️
src/Exceptions.h 31.25% <ø> (-3.08%) ⬇️
src/FrameMapper.cpp 91.39% <ø> (-0.37%) ⬇️
src/Qt/AudioPlaybackThread.h 0.00% <ø> (ø)
src/Qt/PlayerPrivate.cpp 0.00% <ø> (ø)
src/Timeline.cpp 43.66% <ø> (-0.51%) ⬇️
tests/Cache_Tests.cpp 100.00% <ø> (ø)
tests/Clip_Tests.cpp 100.00% <ø> (ø)
tests/Color_Tests.cpp 100.00% <ø> (ø)
... and 37 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b6975ae...d71631a. Read the comment docs.

Comment on lines -57 to -66
################ OPENCV ##################
find_package( OpenCV 4 )
if (OpenCV_FOUND)
message("\nCOMPILING WITH OPENCV\n")
set(CMAKE_SWIG_FLAGS "-DUSE_OPENCV=1")
add_definitions( -DUSE_OPENCV=1 )
else()
message("\nOPENCV NOT FOUND, SOME FUNCTIONALITIES WILL BE DISABLED\n")
endif()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all made unnecessary by the use of target_link_libraries(openshot PUBLIC <opencv_related_targets>) in the src/CMakeLists.txt file, which makes the target configs propagate to all library dependents automatically.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ferdnyc I was checking your pull request and on my machine I had to include opencv on this cmake, otherwise the opencv effects are not displayed in openshot-qt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll have to look at that. If that's the case, even with protocol buffers using targets, then most likely what's missing is either the compiler flag that #defines USE_OPENCV in the SWIG context, or the include directories didn't get propagated to SWIG like they should've. Either way, it's definitely solvable, and will need to be solved in the target context. If any subdirectory config hacks like this are necessary, then the target config isn't right across the build which will bite us when we start generating EXPORTED targets from the build. (Which I'm very close to, I've already got it working in libopenshot-audio.)

I'll take a look at it in the morning. What version of CMake are you building with? (I might've asked that in the past, but I forget the answer sorry.) Some of these things do require certain versions, possibly 3.12 or 3.13 at a minimum for it to all work like it's supposed to. (But I can put in checks that use the older hacks to fake it, when they have to.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm currently using CMake 3.10.2 on my system, but I can update it if necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's OK, at least for the moment. The issue wasn't the version. (Though, you should update, 3.10 is ancient! Still, we theoretically support it.)

The real issue is that the CMAKE_SWIG_FLAGS propagation from the src/ directory has been broken for some time, turns out. I just submitted PR #615 to sort that out. Once that's merged, the SWIG_FLAGS for the bindings will be set directly from the COMPILE_DEFINITIONS set on the openshot library target, so there won't be any need to play around with CMAKE_SWIG_FLAGS at all anymore.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great @ferdnyc, thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With CMake 3.10, you will have the issue that CMake won't automatically propagate your INCLUDE_DIRECTORIES from the openshot target. But that's OK, because you don't actually need to be setting any additional target_include_directories for the generated protocol buffer sources. What you should do is just always include the subdirectory when you reference them, e.g.:

#include "protobuf_messages/stabilizedata.pb.h"

That way, they'll be covered under the existing INCLUDE_DIRECTORIES. (That also means they'll work for external library consumers using the installed headers, because they'll be located at /usr/local/include/libopenshot/protobuf_messages/. The library's include path gets exported as /usr/local/include/libopenshot on install. (Or wherever it's installed.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the PR branch I've fixed all the includes to use #include "protobuf_messages/..." and #include "sort_filter/...", as well as making sure that all of the includes get installed, and that all of the libraries go the right place. (DLLs on Windows install to the RUNTIME DESTINATION (which is bin/, not lib/), so that needs to be set in the install(TARGETS...) for any shared libraries.)

Comment on lines +397 to +399
if(NOT OpenCV_FOUND)
set(ENABLE_OPENCV FALSE CACHE BOOL
"Build with OpenCV algorithms (requires Boost, Protobuf 3)" FORCE)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, OpenCV isn't discovered with REQUIRED because it's not, and if ENABLE_OPENCV is ON (by default or explicitly) but it's not found, the option will just forcibly reset itself to OFF. Any subsequent consumption of any of the OpenCV pieces is then made conditional on ENABLE_OPENCV being a truthy value.

Comment on lines +418 to +422
opencv_core
opencv_video
opencv_highgui
opencv_dnn
opencv_tracking
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list is a total guess, I just basically flung stuff at it until the compile stopped failing with missing symbols. It may need to be corrected, augmented, or pared down.

opencv_highgui
opencv_dnn
opencv_tracking
protobuf::libprotobuf
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boost isn't represented here at all, BTW, because it doesn't seem to be needed. If it's required for OpenCV and/or Protobuf, then presumably their target(s) take care of loading it automatically, and we should let them. But it's not required for any of our code AFAICT, is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I forgot to qualify, though, that if it should turn out that it's possible to end up with a system where OpenCV/Protobuf are installed, but the correct Boost components aren't, then this whole question may have to be revisited and we may need to do at least some detection/configuration for ourselves. But IMHO that's one of those "don't dick around solving it before you know if it's even possible to have it" type of schrödingproblems.)

endif()
add_feature_info("OpenCV algorithms" ENABLE_OPENCV "Use OpenCV algorithms")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will report the OpenCV status in the FeatureSummary table at the end of the configuration run, which is a lot more pleasant than message()-ing out status lines that will end up getting repeated multiple times. But the text can be adjusted, augmented, or etc. however we please.

Comment on lines +456 to +458
install(FILES ${ProtobufHeaders}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libopenshot
)
Copy link
Contributor Author

@ferdnyc ferdnyc Dec 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, because these are #included in the effect headers, I have the build installing them... but, it would be really nice if we didn't have to install them, and they could be treated as private headers.

Do the contents of those files define types or classes that are actually used in the headers? Or could their #includes be moved to the .cpp files and treated as private headers, instead?

Copy link
Contributor Author

@ferdnyc ferdnyc Dec 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other reason it would be nice to make some of these headers PRIVATE if possible is, it's less stuff for the Python bindings to have to wrap. Anything in the installable public headers is fair game for having to be wrapped in the Python API as well, which is why I've begun working on an effort (PR #602) to migrate references to internal headers out of the other, public headers and into the corresponding .cpp files instead.

Any header file that isn't referenced by any of the other header files can be considered private and left out of both the install and the generated bindings, which will make our installed APIs tighter and leaner, plus it'll help shave a bit of time off of the builds for both our own internal code and any external API consumers.

Comment on lines -98 to -106
if(OpenCV_FOUND)
set(OPENSHOT_CV_TEST_FILES
if(ENABLE_OPENCV)
list(APPEND OPENSHOT_TEST_FILES
CVTracker_Tests.cpp
CVStabilizer_Tests.cpp
# CVObjectDetection_Tests.cpp
)
set(OPENSHOT_CV_LIBRARIES
${OpenCV_LIBS}
${PROTOBUF_LIBRARY}
Copy link
Contributor Author

@ferdnyc ferdnyc Dec 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This incorporates the OpenCV unit tests into the single openshot-test executable, the testrunner for all of our unit tests. No need for a separate one, or a separate list of sources.

Comment on lines -124 to -125
${OPENSHOT_CV_LIBRARIES}
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, the use of CMake targets instead of variables means that it takes care of propagating these dependencies automatically.

@ferdnyc
Copy link
Contributor Author

ferdnyc commented Dec 24, 2020

I'll need to adjust the Github Actions CI configs to get OpenCV, Protobuf, and Boost installed into the build image, so that we can get CI runs with those components enabled. At the moment it'll be building with them auto-disabled (and the fact that the builds succeed tells me that worked, yay), which means the CI runs aren't actually testing anything here so far, it's just business as usual for them.

@ferdnyc
Copy link
Contributor Author

ferdnyc commented Dec 24, 2020

Having all of the OpenCV stuff #include<>ed publicly in the headers really slows down the compilation of EVERY one of the test objects, BTW, not to mention it blows out their size like crazy. Here's a comparison in meld of the build output directory for the unit tests, opencv_build_config branch on the left, develop branch on the right:

image

A sampling:

Source file Previous size New size
Cache_Tests.cpp.o 225.7 kB 309.5 kB
Clip_Tests.cpp.o 145.7 kB 229.5 kB
Coordinate_Tests.o 31.1 kB 115.1 kB (!!!)
ReaderBase_Tests.cpp 65.6 kB 149.1 kB

Unless we can get some of the new #includes out of the headers and make them private to indivdual .cpp translation units, I think the days of a one-size-fits-all #include "OpenShot.h" may be at an end, it's just becoming too costly in terms of compilation size/time.

cc: @jonoomph

@ferdnyc
Copy link
Contributor Author

ferdnyc commented Dec 24, 2020

Ping @jonoomph as well, regarding my previous comment.

- To prevent slow compiles of unit tests, replace all of the
  '#include "OpenShot.h"' invocations with includes of the
  individual headers actually needed by each test file.

Revert "Unit tests: Don't use OpenShot.h header"

This reverts commit e5cc4f8bf91fc60697996023a86dc618637f6161.

Unit tests: Don't use OpenShot.h header

- To prevent slow compiles of unit tests, replace all of the
  '#include "OpenShot.h"' invocations with includes of the
  individual headers actually needed by each test file.
@ferdnyc
Copy link
Contributor Author

ferdnyc commented Dec 26, 2020

OK, to mitigate the increased compile times in the unit tests, I've gone through all of the source files and replaced #include "OpenShot.h" with individual includes for each header required in the code. PR #607 does that for the existing unit tests in the develop branch, and that commit is cherry-picked onto this branch as well, along with a second one that applies the same changes to the CVfoo_Tests.cpp files.

ferdnyc and others added 8 commits December 26, 2020 06:24
* Delete label.yml

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Frank Dana <ferdnyc@gmail.com>
- To prevent slow compiles of unit tests, replace all of the
  '#include "OpenShot.h"' invocations with includes of the
  individual headers actually needed by each test file.
…failed experiement, not to mention that it destroys performance on the "Transform" tool.
Revert cache-busting-on-seek Experiment
Since commit bfa0504 (2015-08-24),
there is no code in libopenshot which ever throws TooManySeeks.

- Removed catch() statements for TooManySeeks from multiple functions
- Removed the exception from Exceptions.h
- in Qt/AudioPlaybackThread.h:
  - Removed the "SafeTimeSliceThread" class definition, as it only
    existed to catch TooManySeeks.
  - Replaced SafeTimeSliceThread with a standard juce::TimeSliceThread
@github-actions
Copy link

Merge conflicts have been detected on this PR, please resolve.

@github-actions github-actions bot added the conflicts A PR with unresolved merge conflicts label Jan 11, 2021
@ferdnyc
Copy link
Contributor Author

ferdnyc commented Jan 13, 2021

@BrennoCaldato I fixed up this PR, and verified that it works with CMake all the way back to 3.5. I also double-checked that the OpenCV-based effects are 100% for sure visible in the Python bindings.

@ferdnyc
Copy link
Contributor Author

ferdnyc commented Jan 13, 2021

When I run make os_test from the build dir, I still get this:

[ INFO:0] global /builddir/build/BUILD/opencv-4.3.0/modules/core/src/ocl.cpp (891) haveOpenCL Initialize OpenCL runtime...
[ INFO:0] global /builddir/build/BUILD/opencv-4.3.0/modules/core/src/ocl.cpp (433) OpenCLBinaryCacheConfigurator Successfully initialized OpenCL cache directory: /home/ferd/.cache/opencv/4.3/opencl_cache/
[ INFO:0] global /builddir/build/BUILD/opencv-4.3.0/modules/core/src/ocl.cpp (457) prepareCacheDirectoryForContext Preparing OpenCL cache configuration for context: NVIDIA_Corporation--GeForce_GT_710--455_45_01


 Error: 
  Loaded Data. Saved Time Stamp: 2021-01-13T17:16:06Z


 Error: 
Frame: 1 - good optical flow: 72
Frame: 2 - good optical flow: 72
Frame: 3 - good optical flow: 71
Frame: 4 - good optical flow: 67
Frame: 5 - good optical flow: 71
Frame: 6 - good optical flow: 73
Frame: 7 - good optical flow: 71
Frame: 8 - good optical flow: 72
Frame: 9 - good optical flow: 70
Frame: 10 - good optical flow: 72
Frame: 11 - good optical flow: 69
Frame: 12 - good optical flow: 73
Frame: 13 - good optical flow: 70
Frame: 14 - good optical flow: 72
Frame: 15 - good optical flow: 68
Frame: 16 - good optical flow: 68
Frame: 17 - good optical flow: 70
Frame: 18 - good optical flow: 72
Frame: 19 - good optical flow: 70
Frame: 20 - good optical flow: 68
Frame: 21 - good optical flow: 73

AVERAGE DX: 4.2783 AVERAGE DY: 2.99797 AVERAGE A: 0.00169399
MAX X: -1.68234 MAX Y: 9.09679 MAX A: 0.00234863

Frame: 1 - good optical flow: 72
Frame: 2 - good optical flow: 72
Frame: 3 - good optical flow: 71
Frame: 4 - good optical flow: 67
Frame: 5 - good optical flow: 71
Frame: 6 - good optical flow: 73
Frame: 7 - good optical flow: 71
Frame: 8 - good optical flow: 72
Frame: 9 - good optical flow: 70
Frame: 10 - good optical flow: 72
Frame: 11 - good optical flow: 69
Frame: 12 - good optical flow: 73
Frame: 13 - good optical flow: 70
Frame: 14 - good optical flow: 72
Frame: 15 - good optical flow: 68
Frame: 16 - good optical flow: 68
Frame: 17 - good optical flow: 70
Frame: 18 - good optical flow: 72
Frame: 19 - good optical flow: 70
Frame: 20 - good optical flow: 68
Frame: 21 - good optical flow: 73

AVERAGE DX: 4.2783 AVERAGE DY: 2.99797 AVERAGE A: 0.00169399
MAX X: -1.68234 MAX Y: 9.09679 MAX A: 0.00234863

  Loaded Data. Saved Time Stamp: 2021-01-13T17:16:06Z
Success: 119 tests passed.
Test time: 55.27 seconds.
----------------------------

Which is a bit disconcerting. If there's an "Error:", shouldn't the unit test fail?

@ferdnyc ferdnyc removed the conflicts A PR with unresolved merge conflicts label Jan 13, 2021
@BrennoCaldato
Copy link
Collaborator

When I run make os_test from the build dir, I still get this:

I think I removed these messages in the keyframe-refactor branch. I'll check

@BrennoCaldato BrennoCaldato merged commit 1fa4e87 into OpenShot:opencv Jan 13, 2021
@BrennoCaldato
Copy link
Collaborator

@ferdnyc I tested this PR and so far I could not reproduce these error messages on my system

@ferdnyc
Copy link
Contributor Author

ferdnyc commented Jan 13, 2021

@ferdnyc I tested this PR and so far I could not reproduce these error messages on my system

@BrennoCaldato
I figured out where it's coming from. In CVTracker_Tests.cpp you have a*

        std::cout<<"\n\n Error: "<< processingController.GetErrorMessage() <<"\n";

Which will always display a message, even if there's no error. (Hence the empty string that gets printed following the "Error:".)

* — correction, two. one in each test.

@ferdnyc ferdnyc deleted the opencv_build_config branch January 13, 2021 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues related to compiling or installing libopenshot and its dependencies
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants