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

Linux/MacOSX port of DriverLoader #10

Merged
merged 12 commits into from
Apr 25, 2016

Conversation

a1batross
Copy link
Contributor

Not tested this at all. But this must work on Linux and OSX too, since they are provide same POSIX dlfcn.h.

Also here is little changes in exceptions, because it's too important to know why library isn't loaded.

This must be compiled with -ldl. (${CMAKE_DL_LIBS} variable in CMake)

@a1batross
Copy link
Contributor Author

#4 #5

@@ -100,7 +100,7 @@ add_library(ViveLoaderLib STATIC
VRSettings.h)
target_link_libraries(ViveLoaderLib
PUBLIC
OpenVRDriver osvr::osvrUtil linkable_into_dll
OpenVRDriver osvr::osvrUtil linkable_into_dll ${CMAKE_DL_LIBS}
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer for this to be conditional on if(NOT WIN32), if you don't mind. It might also be able to be a PRIVATE library dependency, rather than public, not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As Far As I Know, CMake will return a null string on Win32.
And -ldl on OSX/Linux.

Copy link
Contributor

Choose a reason for hiding this comment

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

$CMAKE_DL_LIBS is set to an empty string on platforms that don't need to link to a library for dlopen()/dlclose().

@rpavlik
Copy link
Member

rpavlik commented Apr 7, 2016

Wow, great, thanks for the contribution, it's really appreciated! I just have two little tweaks to suggest (the one in the build file, then the one to remove the unnecessary ifdefs around constructors), and then just a general question about libdl usage, since that's something I write libraries to keep me from dealing with too often... then I'll be more than happy to merge this!

FWIW, you can actually "test" and run this without Vive hardware, as long as you have SteamVR installed, it'll have the driver in the expected location, so running the ViveLoader app (built with the project, just not installed) should take it through its basic paces. It won't get too far without the hardware but you'll be able to see if the loading of the library and such works properly.

@a1batross
Copy link
Contributor Author

Yes, I have installed SteamVR. Ok, I will try to run it and fix all issues tomorrow.
Thanks for review!

CouldNotLoadDriverModule(const char *errString)
: std::runtime_error(
"Could not load driver module." +
std::string(errString)) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

You should probably add a space between the hard-coded C-string and the appended error string.

@a1batross
Copy link
Contributor Author

a1ba@KubuntuPortable:/home/a1ba/projects/OSVR-Vive/build  git:(linux_osx_driverloader_port*) $ ./ViveDisplayExtractor 
[DisplayExtractor] Driver loaded, but no Vive is connected. Exiting

Finally, got it running. Also I fixed some mistypes in code, forgotten includes.

NOTE: it requires setting LD_LIBRARY_PATH variable(SteamVR dependencies). It may be useful for they, who have Vive and want use OSVR.

export LD_LIBRARY_PATH=${HOME}/.steam/steam/steamapps/common/SteamVR/drivers/lighthouse/bin/linux64/:${HOME}/.steam/ubuntu12_32/steam-runtime/amd64/lib/x86_64-linux-gnu/

NOTE2: For some reason, Valve have an invalid GCC detection macro. Here is a confirmation: ValveSoftware/openvr#58
Maybe you need to define it somewhere. Something like:

#if defined(__GNUC__)
#define GNUC
#endif

@a1batross
Copy link
Contributor Author

Ah... I forgot a charger for my laptop in home. If there is some issues, I will fix in next Monday.

@a1batross
Copy link
Contributor Author

Is anyone alive here?

@rpavlik
Copy link
Member

rpavlik commented Apr 12, 2016

Sorry, I thought we were waiting for you to test this again.

@@ -40,14 +41,26 @@
namespace osvr {
namespace vive {
struct CouldNotLoadDriverModule : std::runtime_error {
CouldNotLoadDriverModule()
Copy link
Member

Choose a reason for hiding this comment

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

I actually meant leave both constructors - a default constructor and one that takes an extra error message, with no platform ifdefs in this header at all...

@rpavlik
Copy link
Member

rpavlik commented Apr 12, 2016

FWIW, SearchPathExtender.h is supposed to handle the extension of LD_LIBRARY_PATH - if it's not doing it, or not doing it right, could you look at it and see what I got wrong when I sort of wrote the non-Windows part without testing?

@a1batross
Copy link
Contributor Author

Okay, I will look for it.
On Apr 12, 2016 3:12 AM, "Ryan Pavlik" [email protected] wrote:

FWIW, SearchPathExtender.h is supposed to handle the extension of
LD_LIBRARY_PATH - if it's not doing it, or not doing it right, could you
look at it and see what I got wrong when I sort of wrote the non-Windows
part without testing?


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#10 (comment)

@a1batross
Copy link
Contributor Author

a1batross commented Apr 16, 2016

Sorry, I was been busy for a week.

There is a problem with libdl. Library does getenv("LD_LIBRARY_PATH") before the program starts and only once. So setting LD_LIBRARY_PATH in runtime is useless.

I see some workarounds:

  1. Use execve() on *nix. One-line solution. Portable. But need to access filename of executable and original argv. (reading /proc data is non-portable, so it's better save argv from main()).
  2. Recursively resolve dependencies of driver library and dlopen() each.
    It requires tons of code: parsing each ELF file, loading it by absolute path and so on.
  3. Write a "run.sh" script for *nix-es.
  4. Have your own libdl.

@rpavlik
Copy link
Member

rpavlik commented Apr 20, 2016

That's fine, I've been busy too. Think I may as well merge this as-is, but would be good to figure out how to improve the libdl situation.

I wonder what SteamVR does, since they have the same problem: they have to add each driver's directory to the library search path. In libfunctionality, which is basically the only other place I've done substantial dlopening of libraries myself cross-platform (Unity/.NET doesn't really count), I'd contemplated/thought we might need/want a libltdl backend, but I wasn't familiar enough with it and didn't do enough research to see if it allowed the flexibility we wanted, but it does have a concept of user search dirs - don't know if it handles transitive dependencies: https://www.gnu.org/software/libtool/manual/html_node/Libltdl-interface.html#index-lt_005fdladdsearchdir

In any case, while option 2 in the general case is difficult, for the specific case of just loading the Vive driver, we could manually look up and hard-code its dependencies and preload them - that's essentially what we had to do with Unity loading OSVR...

@rpavlik
Copy link
Member

rpavlik commented Apr 20, 2016

Yeah, I'll just go ahead and merge this as-is, after skimming some related things, if that sounds good with you - let me know if you're ready for me to merge it!

If you wouldn't mind, could you submit a pull request updating this page with the LD_LIBRARY_PATH workaround info under a Linux section? https://github.com/OSVR/OSVR-Docs/blob/master/Configuring/HTC-Vive.md

@a1batross
Copy link
Contributor Author

a1batross commented Apr 20, 2016

I wonder what SteamVR does

I think it does the same thing as Steam itself. Just setting LD_LIBRARY_PATH before starting program. It's most easy and secure way.
AFAIK, Steam before starting adds Steam Runtime path which provides libraries with same versions on different Linux distributions. Now Steam Runtime enabled by default(I remember that on early Steam Linux versions it was disabled and I recompiled libraries by hand XD).

I may write an example shell script which will detect steam-runtime, add it to LD_LIBRARY_PATH and start the app. But I little busy now. I will update both linux_osx_driverloader_port branch and the OSVR-Docs on a holidays.

reset();
throw CouldNotLoadEntryPoint(dlerror());
}
factory_ = reinterpret_cast<DriverFactory>(proc); \
Copy link

@phiresky phiresky Apr 20, 2016

Choose a reason for hiding this comment

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

Why is there a backslash at the end of this line (line 108)? Seems to break the build for me

@rpavlik
Copy link
Member

rpavlik commented Apr 25, 2016

Merging this - thanks for your contribution!

@rpavlik rpavlik merged commit 864f9d8 into OSVR:master Apr 25, 2016
@rpavlik
Copy link
Member

rpavlik commented Apr 26, 2016

Just looked at the commits again - you got a lot more in than Linux support, thanks for catching my bugs! thank you so much!

@her001 her001 mentioned this pull request Jun 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants