obsproject / obs-studio

OBS Studio - Free and open source software for live streaming and screen recording
https://obsproject.com
GNU General Public License v2.0
58.52k stars 7.81k forks source link

[28.0.0-beta1] fails to build due to wrong CMAKE_INSTALL_DATAROOTDIR handling #6928

Open tgurr opened 2 years ago

tgurr commented 2 years ago

Operating System Info

Other

Other OS

Exherbo Linux

OBS Studio Version

Other

OBS Studio Version (Other)

28.0.0-beta1

OBS Studio Log URL

-

OBS Studio Crash Log URL

No response

Expected Behavior

CMake build completing without error.

Current Behavior

CMake build failure.

Steps to Reproduce

  1. pass -DCMAKE_INSTALL_DATAROOTDIR:PATH=/usr/share/ to CMake
  2. see INSTALL DESTINATION "/usr/share/obs/libobs" in generated libobs/cmake_install.cmake (28.0.0-beta1_cmake_install.cmake.txt)
  3. see CMake wrongly trying to install directly into the root file system (catched and prevented by the sandbox of our package manager in this this case - see full build log: obs-studio-28.0.0-beta1_build.log)

obs-studio 27.2.4 had INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/obs" in generated libobs/cmake_install.cmake which in our specific case was also never correct as architecture independent data shoulnd't have ended up under PREFIX, but at least it worked.

So probably for 28.0.0-beta1 this should end up in something like INSTALL DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/obs/libobs" instead of /usr/share/obs/libobs in the generated libobs/cmake_install.cmake

Anything else we should know?

No response

tgurr commented 2 years ago

Same for 28.0.0-beta2 obviously, the actual error output:

[...]
Installing OBS rundir
cd /var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build/libobs && /usr/x86_64-pc-linux-gnu/bin/cmake --install .. --config None --prefix /var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build/rundir/None --component obs_libobs > /dev/null
make[2]: Leaving directory '/var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build'
make[1]: Leaving directory '/var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build'
sydbox: 8< -- Access Violation! --
sydbox: mkdir(`/usr/share/obs')
sydbox: proc: cmake[111431] (parent:111430)
sydbox: cwd: `/var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build/libobs'
sydbox: cmdline: `/usr/x86_64-pc-linux-gnu/bin/cmake --install .. --config None --prefix /var/tmp'
sydbox: >8 --
sydbox: 8< -- Access Violation! --
sydbox: mkdir(`/usr/share/obs/libobs')
sydbox: proc: cmake[111431] (parent:111430)
sydbox: cwd: `/var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build/libobs'
sydbox: cmdline: `/usr/x86_64-pc-linux-gnu/bin/cmake --install .. --config None --prefix /var/tmp'
sydbox: >8 --
CMake Error at cmake_install.cmake:172 (file):
  file INSTALL cannot make directory "/usr/share/obs/libobs": Operation not
  permitted.
Call Stack (most recent call first):
  /var/tmp/paludis/build/media-video-obs-studio-28.0.0-beta2/work/build/cmake_install.cmake:57 (include)

make[2]: *** [libobs/CMakeFiles/libobs.dir/build.make:1415: libobs/libobs.so.28] Error 1
make[2]: *** Deleting file 'libobs/libobs.so.28'
make[1]: *** [CMakeFiles/Makefile2:929: libobs/CMakeFiles/libobs.dir/all] Error 2
make: *** [Makefile:159: all] Error 2

Complete build log for 28.0.0-beta2: obs-studio-28.0.0-beta2.log

PatTheMav commented 2 years ago

The main problem is that you pass an absolute path as CMAKE_INSTALL_DATAROOTDIR, but the default value of this variable is "share" as the actual path is usually composed with the CMAKE_INSTALL_PREFIX in mind (and we make heavy use of custom prefixes, e.g. to use install to set up the rundir in the build tree).

If you want to change the location into which OBS will be installed, change the CMAKE_INSTALL_PREFIX with an absolute path or adjust the other components as relative path elements. The prefix is always prepended to the install location by CMake anyway, which is why it's not used explicitly in the calls to install anymore and on linux all support files are installed at ${CMAKE_INSTALL_DATAROOTDIR}/obs (which by default would be ${CMAKE_INSTALL_PREFIX}/share/obs).

tgurr commented 2 years ago

@PatTheMav according to CMake docs it's perfectly fine to pass absolute paths to CMAKE_INSTALL_<dir> see https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html#module:GNUInstallDirs

CMAKE_INSTALL_<dir>

Destination for files of a given type. This value may be passed to the DESTINATION options of install()
commands for the corresponding file type. It should typically be a path relative to the installation prefix
so that it can be converted to an absolute path in a relocatable way (see CMAKE_INSTALL_FULL_<dir>).
However, an absolute path is also allowed.

And we need this because our distributions is full cross/multiarch, e.g. architecture specific binaries, libraries, etc. being installed into arch specific locations /usr/x86_64-pc-linux-gnu/{bin,include,lib} while the arch-independent files are still supposed to be installed into /usr/share. We have this in our exlib (https://git.exherbo.org/arbor.git/tree/exlibs/cmake.exlib#n198) which is used for ALL CMake based builds/packages on Exherbo.

PatTheMav commented 2 years ago

While CMake supports it in general, our build system does not because we use install for other purposes than just installing the project on the system and we rely on composing relative path components with the CMAKE_INSTALL_PREFIX.

See the trigger here: https://github.com/obsproject/obs-studio/blob/2ca0e7cc1af0314d4564f501b956fd58919ac30b/cmake/Modules/ObsHelpers.cmake#L56, and the part using the data dir variable here: https://github.com/obsproject/obs-studio/blob/2ca0e7cc1af0314d4564f501b956fd58919ac30b/cmake/Modules/ObsHelpers.cmake#L152.

The latter part is also what throws the errors in your build process, as we change the prefix to point into the build tree's rundir to create a temporary build for debugging. Setting an absolute path for the data dir breaks this obviously.

A possible solution would be to override the setup_target_resources and add_target_resource functions for Linux only and accept a different variable for the obs_${target} component data dir that only contains a relative path.

Feel free to open a PR that changes this to your needs.