sccn / lsl_archived

Multi-modal time-synched data transmission over local network

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

INSTALL.md out of date

dmedine opened this issue · comments

The build_windows.bat script (which was working quite well) disappeared with this commit sccn/labstreaminglayer@6256a86 but it is still referred to in INSTALL.md.

It would probably be good to have a complete list of possible arguments for the top level CMake command. It's a pain to have to scan through 5 or more files all named CMakeList.txt (CMake is wonderful in effect but horrible to use) in order to understand how it all works.

Also, LSLAppBoilerplate is now gone? No more LSL_INSTALL_ROOT? Doesn't that invalidate all of the apps' CMakeLists files?

I am not even anywhere near in the vicinity of close to ok with this situation.

I have some meetings this morning but I’ll take a look after.

I recently rebuilt LabRecorder on Windows. It was pretty painful. My goal is to make the documentation and build procedure straightforward in the new repository for all apps and platforms before the conference. That's a pretty big target considering how messy things have gotten, and this should be a goal for everyone.

If you ever want to know what top-level options are available to CMake then you can use the cmake-gui. The workflow for the cmake-gui is to Configure, which scans the cmakelists files and populates the table of options with whatever it finds (and their default values), then if any new variables appear (always true for the first Configure) or any variable values are changed then you must Configure again. Finally after Configure returns no changes you can Generate the project.

But yes, it is always nice to have a list of common cmake options. Even in the most recent BUILD.md, this is missing and should be added.

@mgrivich I'd like to know more about your pain points with building LabRecorder so we can write better documentation. Were you using the new repository or the old one? Were you doing an in-tree build or out-of-tree build (definitions)?

By the way, I just updated the new repository's build instructions with some more details about cmake. Please feel free to add your own cmake command to the list under "Here are some example cmake commands".

For reference, realize that I have not built any of the official apps for 5+ years. Most of my interaction with LSL is at a pretty low level or on unique projects. That being said, it should not have taken me most of a day to build LabRecorder as I have worked with many developer environments and projects over the years.

I had to figure out that the magic command is

c:\nbs\external\labstreaminglayer-official-git-master\build>cmake .. -G "Visual Studio 14 2015" -DQt5_DIR="C:/Qt/5.10.1/msvc2015/lib/cmake/Qt5" -DBOOST_ROOT=C:\boost\boost_1_65_1 -DLSLAPPS_LabRecorder=ON

The appropriate versions of Qt and boost had to be found and installed.

As of this writing, I haven't been able to get the directories set from camke-gui.

Before running the LabRecorder project in Visual Studio, I had to manually copy liblsl.dll, several Qt dl's and the Qt platforms folder into my executable location. Maybe setting LSL_INSTALL_ROOT would fix this? I haven't tested yet.

The errors messages I received at various points ranged from hard crashing to cryptic to helpful. I did use those build instructions heavily.

I will be improving the documentation at some point, but I am not quite there yet (I want my procedures to go smoothly and reasonably correct). Basically, what you have is fine, as far as it goes, but it is written as a reference manual, while copy-pasteable recipes for common use cases are what most people (especially non-experts) will find helpful.

It was an "in-tree" build.

The appropriate versions of Qt and boost had to be found and installed.

The versions don't matter except Qt > 5.5 on Ubuntu (otherwise 5.x should work) and boost < whatever is supported by your cmake. This is laid out in the BUILD-ENVIRONMENT.md, but I figured that these problems would be relatively rare so I didn't think to elevate this to top-level.

As of this writing, I haven't been able to get the directories set from camke-gui.

I've encountered this before too. I'll take another look. It's really unfortunate that cmake-gui does something different than cmake commandline.

Before running the LabRecorder project in Visual Studio, I had to manually copy liblsl.dll, several Qt dl's and the Qt platforms folder into my executable location. Maybe setting LSL_INSTALL_ROOT would fix this? I haven't tested yet.

I think it's possible to do a post-build step to copy the dlls to the intermediate directories where VS stores the built binaries before INSTALL. reference for later

But even easier than doing all that is to use Visual Studio 2017 which has a CMake menu with an option to "Debug in Install Folder".

Does anyone reading this have a specific need to use an older version of visual studio? If not then maybe we can make sure everything works well on VS 2017 and use that as our primary way to debug apps.

FYI I updated BUILD.md with a few more details for using Visual Studio 2017. Changing any CMake settings requires editing a CMakeSettings.json file (easily accessible from VS 2017's CMake menu). Also interesting is that this method allows both x86 and x64 in the same solution, if you have the Qt and boost libs installed for both.

From this same CMake menu you can do Debug from Install Folder which seems to work!

However, the default install dir is different to what is set by commandline. e.g. My build went into C:/Users/Chad/CMakeBuilds/c8dd12c1-94ba-2539-b8a4-7e3c92991420/install/x64-Debug. I'm sure this can be overcome...

It would probably be good to have a complete list of possible arguments for the top level CMake command.

That's not that easy, because CMakeLists.txt in subfolders can add options as well, (e.g. the endian conversion option for LabRecorder) and the list of available options can depend on other set options, but CMake can output a list with cmake -L from the build folder.

Also, LSLAppBoilerplate is now gone? No more LSL_INSTALL_ROOT? Doesn't that invalidate all of the apps' CMakeLists files?

For several reasons (I'm currently out of town with only my cell phone, so I can't explain in detail) the LSLAppBoilerplate and the other CMake files were moved to LSL/liblsl/LSLCMake.cmake.

Before running the LabRecorder project in Visual Studio, I had to manually copy liblsl.dll, several Qt dl's and the Qt platforms folder into my executable location. Maybe setting LSL_INSTALL_ROOT would fix this? I haven't tested yet.

Seems like the rpath wasn't set correctly for the compiled, but not installed, libraries. VS2017 does the right thing, so the only affected platforms are Windows with VS <2017 we'll need a solution for.

Seems like the rpath wasn't set correctly for the compiled, but not installed, libraries. VS2017 does the right thing, so the only affected platforms are Windows with VS <2017 we'll need a solution for.

I've explored this further. By using the build command:

c:\nbs\external\labstreaminglayer-official-git-master\build>cmake --build . --config Release --target install

liblsl.dll and default_config.cfg are put in the build/install/LabRecorder folder.

The Qt files are still missing. However, inspecting LSLCMAKE.cmake (from the new repository), I discovered that, within the if(WIN32) section,

execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${QT_DEPLOYQT_EXECUTABLE})

shows that QT_DEPLOYQT_EXECUTABLE is C:/Qt/5.11.1/winrt_x86_msvc2017/bin/windeployqt.exe which is wrong, both in the Qt version and the msvc version. It must be hard coded somewhere, as the generator is msvc2015 and Qt 5.11.1 is not installed. My Qt5_DIR points to 5.10.1.

shows that QT_DEPLOYQT_EXECUTABLE is C:/Qt/5.11.1/winrt_x86_msvc2017/bin/windeployqt.exe

Is there any chance that you have a cached cmake config from a previous attempt that is conflicting?
I don't know how this could happen otherwise.

Deleting the build folder would get rid of this, yes? I can try that in the morning (California time).

Exactly. Windeployqt is searched for/ set once and then not touched, even if the Qt path changes. It's only started from one point in LSLCMake, so at that point t we could check the return code and if it failed unset the windeployqt_path var and print an explanation with instructions to start the build once again

Deleting the build folder worked. Exploring more, none of the dependent qt folders in CMakeCache.txt update based on changing the command line parameter. These should either update, or an error should be thrown when changing this folder (likes happens when the user attempts to change the generator) to notify the user that he must delete the build folder and start again when changing Qt versions.

There's no way to detect a change in the Qt dir setting (or more accurately, settings, as there are several standard ways Qt is detected).

I'll add a function to check for Qt when I get back so the apps which use Qt can see if Qt and Windeployqt is (still) in the right path and print an error message with a link to the relevant documentation if it's not.

It looks to me like the problem is likely in Qt5CoreConfigExtras.cmake not being smart about validating the cache before use. Since we can't reasonably edit files maintained by other organizations, that is a bit of a dead end.

What do you think of automatically deleting CMakeCache.txt every time that cmake configure is run? That fixes the problem in limited testing, but I'm not sure on what side effects this might cause. It is more gentle than deleting all build products every time configure is run.

It is pretty bad gotcha to have configure not really reconfigure based on changing of flags, and I worry that having this cache persist can be asking for trouble.

What do you think of automatically deleting CMakeCache.txt every time that cmake configure is run?

It's been a while since I tried using that as a workflow but I remember it not doing a good enough job of clearing out cached variables, but that was a while ago and things may have changed. Anyway, it's because of this that my 'seasoned cmake-user' workflow is to delete the build folder and start over. On my multi-boot systems I usually have several different build folders (i.e., build_win32, build_win64, build_linux). I don't think the build directory is designed to be a generic staging ground for multiple configurations.

It might be worth taking a closer look at what VS2017 cmake-integration does. It seemed like VS2017 created a separate build dir for each configuration (32/64 release/debug) and re-ran cmake from scratch for each configuration. I also noticed that whenever I changed cmake code that it automatically re-configured, but I didn't notice if it cleared the cache.

Are user set variables preserved when the CMakeCache is deleted?

Anyway, it's because of this that my 'seasoned cmake-user' workflow is to delete the build folder and start over.

Okay. I'll put warnings in the documentation that I'm writing that significant changes to cmake flags requires the user to delete the build folder (or create a new one). Tristan can add any checks and warnings that he thinks are reasonable to the scripts.

If it was up to me, alone, I would take something like this as a reason to nuke cmake from orbit and go back to platform dependent, hand built projects.

The whole point of modern make/build systems to avoid having to rebuild everything from scratch every time you make a change, because you don't know if you are required to or not. Cmake just seems broken at a fairly fundamental level. Here is a similar, related issue: https://gitlab.kitware.com/cmake/community/wikis/FAQ#cmake-does-not-generate-a-make-distclean-target-why, especially "CMake has no way of tracking exactly which files are
generated as part of running CMake," so it seems fairly fundamental to cmake's design.

However, if the majority desire is to stick with cmake, I won't get into a big argument about it, especially since I didn't put in the time to learn cmake when the decision was made to switch to cmake.

Fortunately, LSL and the associated apps are small enough that they can be rebuilt from scratch in a somewhat reasonable amount of time.

If it was up to me, alone, I would take something like this as a reason to nuke cmake from orbit and go back to platform dependent, hand built projects.

If we were to go back to hardcoded paths and versions for the compilers and all libraries (e.g. VS2008 with Qt 5.9.3 installed in C:\Qt\5.9.3\msvc2008_32\) we could do that with CMake as well (incidentally, that's almost what we're doing right now - a recent Qt version, 5.10.1 I think, and most recent Boost versions are automatically detected, other have to be configured via user defined variables).

The whole point of modern make/build systems to avoid having to rebuild everything from scratch every time you make a change, because you don't know if you are required to or not.

I agree that a separation between user supplied variables and deduced variables would be great so changes in build settings would propagate properly, but I don't know a single IDE that handles this either.

In my experience, CMake handles most changes (checking out another branch/commit, changing CMakeLists.txt files and changes to build options that don't propagate, e.g. most compiler flags, include paths and some build options but not Qt5_DIR and BOOST_DIR) very well.

CMake has no way of tracking exactly which files are generated as part of running CMake

With Qt (moc, rcc, uic, windeployqt) that's true for most other build systems as well. At least MSVC, QtCreator and CLion store the user supplied variables separately, so the build folder can be deleted and rebuild quickly. That's also what Travis and Appveyor do.

Fortunately, LSL and the associated apps are small enough that they can be rebuilt from scratch in a somewhat reasonable amount of time.

FWIW, my 5 years old laptop compiles liblsl, LabRecorder and 3-4 other apps in under 10 minutes and our new slightly older build server takes about 2 minutes.

I agree that a separation between user supplied variables and deduced variables would be great so changes in build settings would propagate properly, but I don't know a single IDE that handles this either.

Visual Studio's settings propagate properly with every build, unless the developer does something silly. So do the other developer environments I've used, though Visual Studio is the one I have the most experience with at this point.

If we were to go back to hardcoded paths and versions for the compilers and all libraries (e.g. VS2008 with Qt 5.9.3 installed in C:\Qt\5.9.3\msvc2008_32) we could do that with CMake as well (incidentally, that's almost what we're doing right now - a recent Qt version, 5.10.1 I think, and most recent Boost versions are automatically detected, other have to be configured via user defined variables).

It's been a long time since I've looked at the 2008 projects, but generally the way this kind of thing is handled is that there is a small number of settable parameters (Qt5_DIR, BOOST_DIR, etc.) that are set by the developer in one place. I prefer in the project settings rather than a system parameter, so that different projects (or different instances of the same project) don't conflict with each other. Everything else is determined at build time from those parameters: ${Qt5_DIR}/bin, ${SolutionDir}/../shared_includes/, etc. Relative paths are used.

@mgrivich If you can, please try using VS2017 with its cmake integration to see if you like it and if it propagates variable changes properly. From what I've used so far I really like it, but I'm hardly in Windows anymore so I'm not able to spend enough time in it to evaluate it properly.

EDIT: VS2017 might be a bad choice if we are building libs that are to be linked to during Cython compilation with python <= 3.4. This EXCLUDES pylsl which uses ctypes and doesn't require compilation on the user's machine. I don't know anyone that links liblsl in Cython-based packages and also has a hard dependency on python <= 3.4 so we're probably OK to make VS2017 the recommended IDE in Windows.

The Cmake generation of VS2017 projects is not great.

  • Dependent libraries (such as Qt and lsl) are never copied into Visual Studio target folders, so launch of XDF_Browser (for example) from inside visual studio fails with dlls and other support files not found. The "real" install is in build/install, which Visual Studio doesn't understand.
  • Changing Qt versions and rerunning cmake does not update the Visual Studio paths (this is just the same thing as what we've been discussing).
  • The paths in Visual Studio are hard coded absolute paths. So the project can't be moved without failing. This breaks Visual Studio project best practice.
  • There is this odd CMakePredefinedTargets folder, which is a graphical wrapper around the cmake command line commands. It doesn't really follow standard Visual Studio design.

I was looking into fixing these issues, realized that a lot of it was really core to how CMake works, then started looking more at CMake directly. I'm not convinced at this point that CMake knows how to make a standard visual studio project, but some of the issues could possibly be worked around.

Dependent libraries (such as Qt and lsl) are never copied into Visual Studio target folders, so launch of XDF_Browser (for example) from inside visual studio fails with dlls and other support files not found. The "real" install is in build/install, which Visual Studio doesn't understand.

Are you using VS2017 to configure cmake, or command-line? For what I'm talking about, don't use command-line. You can either open VS2017 first then File-Open the CMakeLists.txt file, or you can right click on empty space in the labstreaminglayer folder in Explorer then choose "Open in Visual Studio". Then, after a few moments (with apparently nothing happening...), VS2017 will run through the cmake configuration. The CMake menu should then become available. In the CMake menu there is an option to "Debug in install directory" (or something close to that). The DLLs are copied as part of the install, so this will copy the DLLs for you and you can still launch the app from within the IDE.

We can also add a post-build command to run windeployqt (or macdeployqt, etc) to fix this pain point generally, and it's not that difficult to do, I just haven't gotten around to it yet. I was hoping in the meantime that you could make your workflow easier by using VS2017's cmake integration.

Sorry I forgot an important detail that I don't want you to miss:

When using VS2017's integrated cmake, you don't provide command-line arguments so you have to set boost and Qt5_DIR somewhere. There are some instructions a little further down from here on how to do that.

I was using the command line to generate the Visual Studio project. Using these new instructions, the result is even less Visual Studio. It looks and feels like some other build process hijacked the Visual Studio GUI and is doing it's completely own thing. You can't even open Visual Studio's Project Properties anymore.

Attempting the process you describe: I was able to run SendStringMarkers, but for whatever reason, after I added

"variables": [
{
"name": "Qt5_DIR",
"value": "C:\Qt5.11.1\5.11.1\msvc2015\lib\cmake\Qt5 "
},
{
"name": "BOOST_ROOT",
"value": "C:\local\boost_1_65_1"
},
{
"name": "LSLAPPS_LabRecorder",
"value": "ON"
}
]

to CMakeSettings.json, Cmake didn't reconfigure and turn LabRecorder on. So I don't see how to run LabRecorder. It doesn't show up in the "Select Startup Item" drop down.

It looks and feels like some other build process hijacked the Visual Studio GUI

Yeah if you read the console output it isn't using the MSVC generator but instead it generates Ninja makefiles. Ninja build systems are used with other IDEs too, though I doubt they're portable across. IMO the less proprietary Microsoft is, the better, so I'm happy they're integrating support for 3rd party build systems.

Cmake didn't reconfigure and turn LabRecorder on

Sometimes I didn't have to trigger anything and it just seemed to detect when I hit Ctrl+S, but that might have been when I was editing CMakeLists.txt. Sometimes it didn't seem to detect my changes so I triggered reconfigure by changing the platform (32/64 or debug/release) then changing back. There's probably a better way to do this but as I said I haven't had too much time to play with it.

"value": "C:\Qt5.11.1\5.11.1\msvc2015\lib\cmake\Qt5 "

I copy-pasted that, so it probably worked... but this should probably be msvc2017. I'll check when I'm back at my Windows box tomorrow then update the BUILD.md

I'm away from keyboard till Tuesday, and will continue testing then. 2015 is correct. https://forum.qt.io/topic/80583/prebuild-qt-32-bit-versions-for-visual-studio-2017

I added the variables block in the wrong section, at the end instead of within the desired configuration. It runs now. The CMake configure is rerun every time I save CMakeSettings.json.

I added detailed BUILD.md files to

Apps/Examples
Apps/LabRecorder
Apps/XDFBrowser
LSL/liblsl

for Windows/CMake in the new repository. That took way longer than it should have. I need to switch to some other tasks now, and return to this later.

That's great, thank you.

Do you mind if I tweak the formatting a little? A line-break in raw .md doesn't render an actual line break, so the lists of steps all get concatenated into one long line when viewing the files in a MD renderer (i.e., the GitHub page).

Would you like the hyperlinks to be rendered fully or would you like there to be marked-up text?

A. Get example from here: https://www.example.com
B. Get example from here

When viewing B in a text editor, it looks like [here](https://www.example.com), but in GitHub it just has a blue here

I'll do another pass on Monday. After that, you are welcome to improve it further.

I got delayed, but did the updates today. Feel free to make additional changes if you feel that it is necessary.

I am working on an app that will merge the actiCHamp and LiveAmp connectors. I copied the CMakeLists from the LiveAmp app and made the appropriate changes. A couple of comments.

I was able to use CMake to do an in tree build, but I cannot do it out of tree. When I run CMake just on this directory it tells me that LSLAppBoilerplate is missing. I cannot find this file. Also, I know that I will ultimately have to copy all the dependencies into the build folder at the end because this is how it was with the LiveAmp project.

So it works, but it isn't perfect. I would like to run CMake locally from within an app directory so that my visual studio solution doesn't contain liblsl and lslboost. I would also like to see all the libraries copied automatically.

Also, I had a hard time understanding the LabRecorder md file: https://github.com/sccn/labstreaminglayer/blob/master/Apps/LabRecorder/BUILD.md

The instructions make it seem like each cmake flag gets set by a different call to cmake (which I guess works because it will cache everything?) but for me, I had to have everything set correctly in one command in order for it not to complain at me. Maybe it acts differently on non-Windows? Don't know. I'd be happy to re-write this.

Finally, I just want to say, that cmake is a total headache. A whole bunch of files called CMakeLists.txt is hard to work on and debug, there is this caching issue discussed above, I hate the fact that you have to manually delete a folder and a file (don't make a mistake!) in order to switch configurations, and I can probably think of a couple of other complaints. But, when it's working and you know how to use it, it is very, very, very handy. Setting up a new app project with this architecture is a lot nicer now. And, without cmake, we would have had to go into every single app we want to keep alive and make a whole new visual studio project. So I for one am really happy that we have this now, and thanks you guys for making it!

@dmedine What is your list of required libraries? If it includes some libs from a BrainProducts SDK then this is still possible but will require a little work to help cmake find the SDK. If the SDK has an installer which puts the bin files into a predictable directory then this should be straightforward. Even if not, it is just a matter of having the user pass an argument to cmake specifying something like BPSDK_DIR.

Do you want them copied only when "installing" the app, do you want them copied into the build directory (e.g. for debugging), or even before that? Copied-when-installing is already implemented in many cases; I'm sure it won't be too hard to get it working for you. Copy-after-build is unnecessary for debugging if using VS2017 (with its "debug in install directory" option), but for other environments it is something that can be achieved but we just haven't done it yet. I have some notes on that somewhere...

Currently on mobile, long explanation follows tomorrow.

LSLBoilerplate was a misleading name and ist contains a lot more utility functions now so it got merged into the LSLCMake module, see the labstreaminglayer/App-BestPracticesGUI CMakeLists.txt for the most robust way to find the rest of LSL and the utility functions.

You can either give all CMake options at once or piece by piece, the only options you can't change are the generator (e.g. Ninja, Visual Studio XY solution file) and the build folder path.

Switching configurations is nearly impossible to do over multiple platforms / compilers so separate build folders (I have build/ and build_release/) are the best approximation. Vs2017 does this automatically, but then again it handles CMake a lot better as Chadwick already said

Of the LiveAmp version that is on the submodule, it looks like the .lib and .dll files and Amplifier_LIB.h all have to be in the same dir as the source code. The include file is already there. If they aren't there, then maybe cmake is searching the path to find them.

This line says to link against the .lib file.

Then at the bottom we have some cmake functions that we've previously defined that are called for 'installing' apps.
installLSLAuxFiles here is defined here.

So there's nothing fancy happening here, and certainly nothing being downloaded from a third party. If you do want to download from a third party then have a look at the OpenVR app's CMakeLists.txt. It looks to see if OpenVR is present, and if not it just downloads a GitHub repository and collects it into something cmake recognizes as a library. You would have the added step of unpacking whatever .zip file you have your SDK in.

I will look more closely at this. Thank you for the tip.

I seem to remember that after running cmake with the right magic words, the .lib and .dll (confusingly) appeared automatically in the source code directory, but I could be wrong. I will check when I start to revamp this mechanism.

Now I'm having the hangup that there is no reference to ui_mainwindow.h. I am guessing that there is some black magic going on that is negotiated between cmake and Qt so that the moc_compilation.cpp file is all I need, but this is incredibly opaque. For some reason the new project I'm working on doesn't compile moc_compliation.cpp (though it is indeed part of the project) and so there is no ui class. This worked perfectly with the LiveAmp.

Now I'm having the hangup that there is no reference to ui_mainwindow.h. I am guessing that there is some black magic going on that is negotiated between cmake and Qt so that the moc_compilation.cpp file is all I need, but this is incredibly opaque.

Yes, it's hidden along with most of the other helpful but opaque options. When it works, it works beautifully but when not it's confusing. The options you're looking for are AUTOUIC (generate ui_XY.h from XY.ui when necessary) and AUTOMOC (generate moc_XY.cpp from XY.cpp when needed), the documentation lists the exact conditions for it to work.

@dmedine I've pushed my (in the works) TobiiPro connector, so if you want to reuse an existing SDK (header file + library file) this would be a good starting point