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

Compilation does not work out-of-the-box when external libraries are not installed #407

Closed
qianyizh opened this issue Jun 22, 2018 · 25 comments
Assignees

Comments

@qianyizh
Copy link
Collaborator

I checked out the code on windows. I compiled following the guide:
http://www.open3d.org/docs/getting_started.html#windows
I got error messages:

CMake Error at External/CMakeLists.txt:37 (message):
  EIGEN3 dependency not met.


CMake Error at External/CMakeLists.txt:51 (message):
  GLEW dependency not met.


CMake Error at External/CMakeLists.txt:82 (message):
  GLFW dependency not met.


CMake Error at External/CMakeLists.txt:93 (message):
  LIBJPEG dependency not met.


CMake Error at External/CMakeLists.txt:113 (message):
  JSONCPP dependency not met.


CMake Error at External/CMakeLists.txt:131 (message):
  LIBPNG dependency not met.

There are no instructions to fix it. I think this is unfriendly to new users.

Also, there are window users who do not use CMake GUI (e.g., I use CMake console command in Windows), and there is not hint regarding turning on BUILD_EIGEN3 switch etc. I have to read through the CMakeLists files to find the error message. And the only way to fix it is to add 6 switches to the cmake command. This is unfriendly.

The root cause are these lines in External/CMakeLists.txt:

# Eigen 3.2.7 version is required for pybind11 included in Open3D
if (BUILD_EIGEN3)
    message(STATUS "Building EIGEN3 from source")
    set(EIGEN3_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/External/Eigen")
    INSTALL_HEADERS(Eigen)
elseif (EIGEN3_FOUND)
    message(STATUS "Using installed EIGEN3 ${EIGEN3_VERSION}")
else ()
    message(SEND_ERROR "EIGEN3 dependency not met.")
endif ()

I don't think we should report error. When everything fails, we should just enable BUILD_EIGEN3.

Any thoughts? @syncle @takanokage

@syncle
Copy link
Contributor

syncle commented Jun 22, 2018

Umm, can cmake build automatically from source if dependencies are not installed?

@qianyizh
Copy link
Collaborator Author

No. You need to manually set the switches such as BUILD_EIGEN3, or cmake fails.
That's the current status.

@takanokage
Copy link
Contributor

I have mentioned this aspect in a previous communication.
I have matched the behavior of OpenCV which doesn't make assumptions regarding which third party packages must be built from source. Let's say someone already has it's own working version of GLFW on Windows. Why should they be forced to use the version that comes with Open3D?
Another reason is the fact that we used to have an all or nothing behavior: either we build all from source or none. This affected all OSs not just Windows. Basically, if you wanted headless rendering you had to build all third party libraries from source not just GLFW.

This is not a bug, I have designed it this way in order to provide more flexibility to the user.

@qianyizh
Copy link
Collaborator Author

Let's say someone already has it's own working version of GLFW on Windows. Why should they be forced to use the version that comes with Open3D?

I think the default behavior should be:
a. find_package decides if there is a native version of external library installed, if so, link to it
b. If (a) fails, falls back to use the source code distributed by Open3D
c. The user has options to force compiling from source for a certain library (e.g., GLFW)

Currently we have (a) and (c) which are great. But I'd like to see the logic of (b) also built in so that it is more friendly to new users.

@takanokage
Copy link
Contributor

I personally disagree with that approach ( :) nothing new).

OpenCV third party

The libraries and headers are preferably to build Win32 and Win64 versions of OpenCV.
On UNIX systems all the libraries are automatically detected by configure script.
In order to use these versions of libraries instead of system ones on UNIX systems you
should use BUILD_<library_name> CMake flags (for example, BUILD_PNG for the libpng library).

After showing the OpenCV example I have to admit I'm personally pretty much against building the third party dependencies from source altogether. It's maybe ok when Open3D is used only in a lab. But when Open3D is integrated into a larger/existing application (and we want Open3D to grow to that point) there are all kinds of scenarios where this will be a cause of failure: symbol conflicts, linking to multiple versions of the same (third party) library, to enumerate just a few. We can save ourselves the time and effort by limiting the opportunities for such errors to arise in the future.

I also believe that this form of convenience (building the third party dependencies from source for the user) is causing us all kinds of problems already. Take GLFW for example. Rather then spending time improving core features of Open3D we're somewhat stuck trying to figure out how to install GLFW together with Open3D after building it from source (#393). Even regarding the rest of the third party libraries the install logic of Open3D would be much simpler and would have taken much less time to complete if we didn't have to build from source.

@qianyizh
Copy link
Collaborator Author

symbol conflicts, linking to multiple versions of the same (third party) library

These are the exact reasons I strongly think we should always include a copy of external library source code in Open3D. Other libraries can change, API can change, header files can change. We have no control of it. In order to maintain Open3D in a status that it works with all possible versions of a certain external dependency is a very heavy job. (In a larger scope, the operating systems can be regarded as a type of dependency. And we are still struggling with compatibility issues with different versions of Ubuntu, Windows, compiler, etc.) The small external libraries (GLFW, Jsoncpp, pybind11, etc) change more frequently and less organized than the operating systems. I don't think we have enough resource to maintain compatibility to all of them.

Given the amount of resource we have, the best solution is to always provide a fallback mechanism: building from source. It is not optimal, but Open3D should always be able to be compiled from source, no matter which operating system is used. If someone wants to go sophisticated, he/she always have the option to install native external dependencies and link to it.

Think of a scenario, assume in the future, pybind11 makes a major upgrade from 2.2 to 3.0, it goes native with Ubuntu (apt-get directly gets pybind11 3.0), and deprecates all APIs currently in 2.2. In order to compile Open3D, we only have 3 options:

  1. We provide a detailed instruction to instruct the users how to downgrade pybind11 from 3.0 to 2.2, and the user may not cooperate (he/she may already have other libraries linked to pybind11 3.0 and cannot downgrade)
  2. We rewrite everything in the python module to support both pybind11 2.2 and pybind11 3.0, since it breaks the compilation chain, we need to hotfix it
  3. We provide a copy of source code of pybind11 2.2 and make it the default compilation option for Open3D, while at the same time, we discuss if we should upgrade Open3D to support pybind11 3.0, and take time to develop it

To me, (3) is the only practical option. This is the reason I made it a design principle. It is written in our paper.

The source code of all dependencies is distributed as part of Open3D.
The dependencies can thus be compiled from source if not automatically
detected by the configuration script. This is particularly useful for
compilation on operating systems that lack package management
software, such as Microsoft Windows.

@takanokage
Copy link
Contributor

Well, the scenario I was describing was not a compatibility problem. It's the problem of having different components of an application link to different versions of the same library for example. We cannot control how the user decides to embed Open3D in his application. For this reason building from the third party dependencies from source might (likely will) be a problem when Open3D is integrated in larger projects.

I respectfully disagree with option 3 also. In fact, specifically to pybind11, I've recently become aware that pybind11 can be installed as a pip package and also can be installed on Ubuntu 18.04 using apt. I think it's worth researching removing the source code for pybind11 and always using the installed pybind11.

I'm sure there's pros and cons for all these approaches that I didn't even consider. Ultimately, just like you, I just want us to take the path that puts the least burden on us both today and in the future - there's plenty of valuable work that needs to be done.

@qianyizh
Copy link
Collaborator Author

If we don’t do option 3, what should we do? We can’t leave Open3D in a status that is not compilable. I think we agree on that?

So should we do option 1 or option 2? Or is there any other better idea?

Also, maintaining package compatibility is a big business. The main purpose of Anaconda is this. I’d really like to know if there is any lightweight solution...

@takanokage
Copy link
Contributor

I agree with you. Luckily Open3D is compilable today out of the box just like OpenCV.
The user is alerted when one of the dependency constraints is not met.
The user then has two choices:

  1. install the dependency package if available.
  2. turn the BUILD_<dependency> switch to ON and regenerate the project.

There are exceptions to the above: tinyfiledialogs it's so small it might never get it's own package in Ubuntu (or elsewhere) - it is always built from source. For consistency I've added a BUILD_TINYFILEDIALOGS default ON build option but I'm kind'a doubting my judgement, it's not like turning that option OFF helps with anything.

Regarding package compatibility - I don't know how to address that. As you mentioned it's a big complicated business that has no end.

@oarriaga
Copy link

As guide to any user interested in building the software and the missing dependecies:

  1. Switch to ON the missing dependencies in the Open3D/src/CMakeLists.txt file.
  2. (Optional) I also had to install sudo apt-get install xorg-dev libglu1-mesa-dev since the RandR library and headers were missing in Ubuntu 16.04.

@takanokage
Copy link
Contributor

@oarriaga

My recommendation is to always use the installed dependencies on UNIX systems. The script <open3d_path>/util/scripts/install-deps-ubuntu.sh will install all of these on Ubuntu, including the xorg-dev & libglu1-mesa-dev. Building the dependencies from source on UNIX systems should be reserved for special use cases like headless rendering for example which at this time requires a GLFW version higher than that available as a package or when the package simply doesn't exist (pybind11 is available as a package on Ubuntu 18.04 but not on previous versions).

@syncle
Copy link
Contributor

syncle commented Jun 26, 2018

On Windows, I had another issue.
I used CMakeGUI, manually selected dependent libraries, but I got the following:

Disable unit tests since this feature is not fully supported on Windows.
Compiling on Windows
Compiling with MSVC
Using installed OpenMP 
Building EIGEN3 from source
Building GLEW from source
Building GLFW from source
Could NOT find Vulkan (missing:  VULKAN_LIBRARY VULKAN_INCLUDE_DIR) 
Using Win32 for window creation
Building LIBJPEG from source
Building JSONCPP from source
Building LIBPNG from source
Building PYBIND11 from source
pybind11 v2.2.1
Building LIBREALSENSE from source
Building TINYFILEDIALOGS from source
CMake Error: Target Core has dependency information when it shouldn't.
Your cache is probably stale. Please remove the entry
  Core_LIB_DEPENDS
from the cache.
CMake Error: Target IO has dependency information when it shouldn't.
Your cache is probably stale. Please remove the entry
  IO_LIB_DEPENDS
from the cache.
CMake Error: Target Visualization has dependency information when it shouldn't.
Your cache is probably stale. Please remove the entry
  Visualization_LIB_DEPENDS
from the cache.
Build experimental projects
Configuring incomplete, errors occurred!
See also "C:/git/Open3D/build/CMakeFiles/CMakeOutput.log".

I had followed this tutorial:
http://open3d.org/docs/getting_started.html#windows

@takanokage
Copy link
Contributor

CMake is suggesting that you delete the cache and configure/generate the project again from scratch. Does that help?

@syncle
Copy link
Contributor

syncle commented Jun 26, 2018

You're right. I just tried removing the release folder. The issue was resolved when I completely delete the whole Open3D folder, clone, and build again (not very sure why this works though). I had to manually check dependencies to configure.

@takanokage
Copy link
Contributor

That works however recloning should not be necessary.
Either of the following options deletes the cache:

  1. CMake File Menu -> Delete Cache
  2. Delete binaries folder

@syncle
Copy link
Contributor

syncle commented Jun 26, 2018

Yes. I tried both but it didn't work out.
BTW, I am also encountering the following errors when I do "INSTALL" using visual studio 2015. Can you check on this too?

Error	MSB3073	The command "setlocal
"C:\Program Files (x86)\CMake\bin\cmake.exe" -DBUILD_TYPE=Release -P cmake_install.cmake
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
:VCEnd" exited with code 1.	INSTALL	C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets	133	

@takanokage
Copy link
Contributor

yep, right away.

@takanokage
Copy link
Contributor

This is a permissions issue - you don't have permission to write to C:\Program Files.
I changed the default install destination to C:\Open3D_install and it works.

@syncle
Copy link
Contributor

syncle commented Jun 26, 2018

Aha you're right. As you explained this is because cmake INSTALL prefix copies libraries and headers to the system folder, which was not in the case in our previous Open3D versions. Can you add some note on our document to clarify this potential issue? Without knowing about why this is happening, it is hard to figure out from the error message.

@takanokage takanokage self-assigned this Jul 1, 2018
@takanokage
Copy link
Contributor

do we agree on this being addressed?

@syncle
Copy link
Contributor

syncle commented Jul 2, 2018

Umm I am not quite sure. I hope the first user don't have to worry about explicitly turnning on switches for building dependent libraries. @qianyizh what do you think?

@qianyizh
Copy link
Collaborator Author

qianyizh commented Jul 3, 2018

This is also related to #408 and #425

There are three use cases

  1. pip install open3d-python
  2. git clone, then compile Open3D from source code
  3. download prebuilt packages (or install on windows or apt-get on Ubuntu or brew on OSX), then build an external C++ program and link to it

There are three most frequently used OS/tool chains:

  • Ubuntu 16/17/18 + gcc 5/6/7
  • OSX + clang
  • Windows 10 + Visual Studio 2015/2017

For each use case under each tool chain (9 combinations in total), on a fresh installed system, there should be a getting_started instruction to show how to do it.

Let's not worry about use case (3) for now. But for the other two use cases: (1) is broken. We have received multiple complaints and it is tracked in #408 . We need to hot fix it. (2) is working with Ubuntu and OSX tool chain, but for the Windows tool chain I can't make it by following this guide:
http://www.open3d.org/docs/getting_started.html#windows

Let's track the progress of (2) in this thread. We either need to fix the documentation of http://www.open3d.org/docs/getting_started.html#windows . Elaborate how to download and install all dependent libraries. Or let's make compiling from source an out-of-box default option...

@takanokage
Copy link
Contributor

I would personally close this, there's nothing wrong with CMake on Windows. As I've mentioned before this use case is perfectly valid and to support this I would give the example of OpenCV which works exactly the same way.

The second part of this thread looks like a duplicate of #408 and #430.
In fact I would keep only #430.

@qianyizh
Copy link
Collaborator Author

qianyizh commented Jul 8, 2018

I will take over the ownership to fix this.

@qianyizh qianyizh added bug and removed development labels Jul 8, 2018
@syncle
Copy link
Contributor

syncle commented Jul 8, 2018

Addressed in #444.

@syncle syncle closed this as completed Jul 8, 2018
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

No branches or pull requests

4 participants