Cinder on Linux - the newb frontier... ( moved from old forum )

The original post can be found here :
https://forum.libcinder.org/#Topic/23286000002719015

Some info on your setup would be greatly appreciated! Most probably boost is already installed in your system ? If so could you share which version exactly and which components ? Also an ldd output of your binary result would also be nice to have.

Cinder is known to run well on 16.04 *Ubuntu variants so most probably, as you already mention, there is some mismatch happening with the linking of boost that causes things to go south.

I noticed that you discovered the CINDER_BOOST_USE_SYSTEM which is exactly there for the fact that you also mention on your post( e.g pain with precompiled libs and Linux ) and should work in theory ( at least it worked last time I tested it but its been a while ) . In case that you changed this var after your initial build I would suggest to start clean ā€“ I noticed also that you are trying in-source builds so here is what I would suggest as first steps toward debugging the issue :

  1. Remove all build artifacts that you have already with a hard rm -f.
  2. Perform and out-of-source build of Cinder and samples :
    cd /Your/Cinder/Dir && mkdir build && cd build && cmake .. -DCINDER_BOOST_USE_SYSTEM && make -j4
    cd /Your/Cinder/Dir/samples/BasicApp/proj/cmake && mkdir build && cd build && cmake .. && make

It might be also helpful to have the output of CMake during the configuration step.

The cibuilder script and way of building Cinder is obsolete and it will be completely removed in the next daysā€¦

Lets us know how it goes!

Best,
Petros

2 Likes

Hey @petros I just wanted to say these build instructions worked for me! I was struggling the other day trying to get this to work (I think I was trying to use the cibuilder script or something). I did not have to include the -DCINDER_BOOST_USE_SYSTEM flag, however. Otherwise, it worked perfectly on Ubuntu 16.04.

Thanks for the quick reply and the happy news that cibuilder is obsolete.
A clean out-of-tree rerun had the same problem; see log at
http://kegel.com/linux/cinder.txt
It should have all the details you were looking for.

Also, the small test program

#include <boost/filesystem.hpp>
#include
#include
#include <limits.h>

boost::filesystem::path getDefaultExecutablePath()
{
std::vector buf( PATH_MAX );
std::memset( &(buf[0]), 0, buf.size() );
ssize_t len = ::readlink("/proc/self/exe", &(buf[0]), buf.size() - 1 );
if( ( -1 != len ) && ( len < buf.size() ) ) {
buf[len] = ā€˜\0ā€™;
}
return boost::filesystem::path( std::string( &(buf[0]), len ) ).parent_path();
}

main(int argc, char **argv)
{
std::cout << getDefaultExecutablePath();
}

works when built with
g++ x.cc -lboost_filesystem -lboost_system
but reproduces the problem when built with
g++ x.cc -lboost_filesystem -lboost_system -D_GLIBCXX_USE_CXX11_ABI=0
So, it looks like CINDER_BOOST_USE_SYSTEM needs to turn off that wayward option.

  • Dan

Hi @mike,

thanks for sharing your results! The CINDER_BOOST_USE_SYSTEM flag is completely optional and exists for cases like the one described in this post. Since on a Linux box its not uncommon at all to have some of the Cinder lib dependencies pre-installed ( FreeType being another candidate besides Boost ) this option aims to give an alternative if someone runs into issues due to library version mismatching.

At least this is my impression of what is happening here ā€“ The only other possibility that comes to mind regarding the root of this issue, if not a Boost-mismatch problem, would be trying to build and/or run samples on some kind of shared filesystem thats causing Boostā€™s parent_path to fail.

EDIT: Dan, replied while posting this so this seems to be definitely a Boost issue now.

Cheers,
Petros

Hey Dan,

super, thanks for looking into this and providing all the info.

You can remove the -D_GLIBCXX_USE_CXX11_ABI=0 option here rebuild Cinder and sample and see if that works for you?

Best,
Petros

EDIT:

Btw, the reason this wayward option exists in the CMake configuration is because there are breaking ABI changes between the version of libstdc++ that ships with gcc versions < 5.0 compared with the version of libstdc++ that ships with gcc >= 5.0 . More info on this here and here . For *Ubuntu flavors this means that everything under 15.10 ships with gcc < 5.0 .

The current boost libs that ship with Cinder have been compiled with gcc 4.8 AFAIK and this is why we need this as we also have devices like the RPi and the TK1 which also ship with gcc versions < 5.0

It would definitely be helpful though in scenarios like this to be able to turn off this optionā€¦

This patch plus -DCINDER_BOOST_USE_SYSTEM:BOOL=true lets me build and run BasicApp on Ubuntu 16.04:

ā€” a/proj/cmake/platform_linux.cmake
+++ b/proj/cmake/platform_linux.cmake
@@ -206,4 +206,9 @@ else() # Rpi
list( APPEND CINDER_DEFINES ā€œ-DCINDER_GL_ES_2ā€ ā€œ-DCINDER_LINUX_EGL_ONLYā€ )
endif()

-list( APPEND CINDER_DEFINES ā€œ-D_UNIX -D_GLIBCXX_USE_CXX11_ABI=0ā€ ${GLFW_FLAGS} )
+list( APPEND CINDER_DEFINES "-D_UNIX " ${GLFW_FLAGS} )
+if( NOT CINDER_BOOST_USE_SYSTEM )

  • The precompiled Boost libraries in the source tree were compiled

  • with the older g++ ABI.

  • list( APPEND CINDER_DEFINES " -D_GLIBCXX_USE_CXX11_ABI=0" )
    +endif()

I wonder why other people donā€™t need this with Ubuntu 16.04?

Though really, given how all Linux distros include boost, the right fix is simply to make this the default on Linux and delete the precompiled Linux boost.

1 Like

I think this issue manifests only if you have the development packages installed along with the runtime libs of boost which ship by default ( at least on *untu distros ) which could explain why some people hit this issue and some not.

Initially I was also quite hesitant with providing pre-compiled libs on Linux but the initial rationale has been to try and avoid maintenance issues that might arise because of using different versions of the same lib in different platforms ( OS X vs Windows vs Linux ) but also just to keep the symmetry on how things are handled in the various platforms that Cinder supports.

Cinder ships with 1.60 while on 16.04 the default one is 1.58 for example and on the TK1 1.56 ( I think ) and so onā€¦

In any case lets keep the discussion open and see how things work and we might need to reconsider this approach in the future.

In the mean timeā€¦what about a PR with your fix ?

Best,
Petros

I suspect that the problem may have been due to the git footgun ā€“ I may have neglected to do ā€˜git submodule updateā€™ after doing ā€˜git checkout linux_androidā€™.

In any case, see followup issues:





Iā€™m impressed with how responsive the maintainers are to my merge requests, getting one in so quickly is great.

Hello everyone, not really contributing to the conversation other than by giving encouragementā€“I was finally able to build and (sort of) use Cinder on Linux for the first time. Woohoo! :grinning: Iā€™ve been trying on and off for a loooong time, but was just too noobish to get it working.

Anyway, I cloned the latest android_linux repo, and followed the install instructions here:

Iā€™m really happy I can start learning Cinder on Linux, so thanks to all the great devs who havenā€™t forgotten those of us who arenā€™t on Windows or OSX.

I still have trouble building about half of the samples by the approach
// cd to sample dir
mkdir build
cd build
cmake ā€¦/proj/cmake
make

Most of the time the error message is about not finding the header file ā€˜Resources.hā€™ or some other header file. Pic related:

But again, about half of them work correctly, like the FallingGears sample.
now if we just had Tinderbox on Linuxā€¦ :wink:

1 Like

I tried to fix the cmake file

cmake_minimum_required( VERSION 3.0 FATAL_ERROR )
set( CMAKE_VERBOSE_MAKEFILE ON )

project( Kaleidoscope )

get_filename_component( CINDER_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../.." ABSOLUTE )
get_filename_component( SAMPLE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../" ABSOLUTE )

include( "${CINDER_PATH}/proj/cmake/modules/cinderMakeApp.cmake" )

ci_make_app(
    SOURCES     ${SAMPLE_DIR}/src/InstascopeApp.cpp
                ${SAMPLE_DIR}/src/InstagramStream.cpp
                ${SAMPLE_DIR}/src/TextRibbon.cpp
                ${SAMPLE_DIR}/src/TrianglePiece.cpp
    INCLUDES    ${SAMPLE_DIR}/include
    RESOURCES   ${SAMPLE_DIR}/resources/Asap-Regular.ttf
                ${SAMPLE_DIR}/resources/Kreon-Bold.ttf
    CINDER_PATH ${CINDER_PATH}
)

This builds for me on OS X, but it wonā€™t work in linux Iā€™m afraid, because resources are not supported in linux. You have to move them to assets.

But even if you do this the sample will crash, because something is wrong with the instagram api call, and it returns an invalid response.

@gabor_papp Thanks for the help. I have a long way to go until I have a handle on build part of creating software. As Andrew Bell quipped, ā€œJust in practical terms, that stuff is a lot of what keeps people out of C++, that stuff sucks.ā€ :slight_smile:

I really C++ as a language but Iā€™m not very good with this (inevitable) part of C++ development. Tinderbox on Linux would be wonderful.

Iā€™m currently trying to try and learn CMake so I can try and understand how to interpret the web of CMakeLists.txt files in Cinder so I can figure out how to build my own Cinder apps w/o having to place my code directly inside the samples folders inside the local android_linux checkout folder of Cinder which atm is my only real option to make forward progress learning Cinder with my own apps. Now Iā€™ll try to understand your CMake code and see if I can use it for my own attempts so thanks again. BTW, I was able to replace the local CMake file in the Kaleidescope sample and with it and confirm that it now builds but that it didnā€™t run properly on Linux yet.

Hey,

depending on the complexity of your project( external dependencies, folder structure etc ) it should not be that difficult to have your app in a custom directory actually.

Take BasicApp for example, you could place it in a random directory in your filesystem and the only thing that would need to change in order for the app to build, would be the path to find the root directory of Cinder.

For projects that require finer control Cinder provides currently the ci_make_app macro. This macro is the entry point for applications that want to include directories, blocks and/or external libraries. You can see the argument it accepts here . The forum thread here is also a good resource regarding Cinder and CMake. That said, it would be great to have a proper documentation of the current CMake workflow and a guide is definitely on the todo list for when the time first allows. Until then you can always come back here if something is not clear or not working!

HTH,
Petros

@petros Hi and thanks very much for the great advice and all the helpful links. Since I donā€™t really know too much about CMake yet, I didnā€™t know about the different ways to use it. BTW, I use juCi++, and it also uses CMake as a build system thankfully, so at least I had some exposure too using CMakeLists.txt over the last couple of months, but never really needed to edit one really.

So, anyway, I took your advice, created my own simple folder away from the Cinder checkout tree, and in Juciā€™s CMakeLists.txt added similar lines to the ones in the BasicAppā€™s. After several trial and errors I finally got past all the errors and came up with something that finally worked for me, though I donā€™t doubt it looks pretty amateurish to the pros here:

Also, I discovered I needed to add a

export CPATH="$HOME/Cinder/include" 

line into my .profile file before the #include statements in the main.cpp file would work. But I finally was able to build and run a separate Cinder application w/o having to leave it inside the Cinder samples folder and ā€˜reuseā€™ a sampleā€™s directory structure and CMakeLists.txt files.

So thanks again for all the help Petros (and everyone else ofc). I feel like I can finally start playing around in the shallow end of the Cinder pool, and donā€™t have to stay always in the kiddie pool.:sweat_smile:

I have whatā€™s sure to be a newb question: Is there a simple flag in a CMakeLists.txt file somewhere to specify a Release build instead of Debug?:confused:

You can add the set( CMAKE_BUILD_TYPE "Release" ) line to your CMakeLists.txt file or run cmake with the -DCMAKE_BUILD_TYPE=Release option to build a release version. Or use "Debug" instead of "Release" for a debug build.

1 Like

Perfect. Thanks @gabor_papp! :smiley:

Perfect. Thanks @gabor_papp! :smiley:

Hi I have another basic question. I noticed @paul.houx comment about the the CPP Rest library in another thread:

So, Iā€™m trying to build it but getting an error related to Boost on my machine. The funny part is, I noticed that the Boost files that were being used were in the Cinder subdirectories, even though Iā€™m not actually trying to build a Cinder app currently. Did I do something wrong when I installed Cinder, and is it possible to fix things to look at the systemā€™s copy of Boost instead while trying to build the CPP Rest SDK in case that fixes the error? Pic related:

The boost libraries are also used by Cinder, as they contain a lot of great tools and classes. Historically, although not officially, they have been where most C++ experimental features were being developed before ending up in the language specs. Cinder is now slowly moving away from boost as most of what we need has become part of C++11 and the upcoming C++14.

As said in my post, I can not offer any support for my C++ REST SDK block, because I have only used it once myself and on Windows only. My advice would be to follow the official docs for Linux. Feel free to use Cinderā€™s boost instead of the SDKā€™s version, but note that the version may be incompatible. Lastly, on Windows I had to build a static library instead of a dynamic one in order for it to work. This required changes to the SDKā€™s build process.

Edit: the reason the SDKā€™s build process uses Cinderā€™s boost is probably because there is a system wide path set for it (similar to a Windows environment variable).

-Paul

Hi Paul,

Thanks for the info. :slight_smile: I saw that you had created a block (sp?) for this, but as Iā€™m on Linux I donā€™t think Tinderbox is available. Also, I noticed on your github for this the comment that static libraries were needed. MS pointed out an optional cmake flag

on the Linux build instructions page that should make it straightforward to build that way.

Heh, so yea if I ever get Casablanca to build, Iā€™ll try to utilize it in Cinder. If Iā€™m successful, Iā€™ll make another post here about it. :sunny:

So yea, I have a mixed news update.

Once I figured out how to use the Boost 1.61 files (instead of the Cinder ones which didnā€™t work) I was able to build the example test CPPRest code on Linux successfully. This is what my CMakeLists.txt file looks like for it to work:

cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Release)
project(cpprest_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wextra -Wno-unused-parameter -O3")
add_executable(cpprest_test main.cpp)
target_link_libraries(cpprest_test cpprest boost_system boost_thread crypto ssl pthread)

So far, so good, everything builds and runs, and the correct results.html file is produced. If I try to include building a Cinder app w/ CPP Rest included, I get a
number of ā€˜undefined reference to xā€™ linker errors, for example:

undefined reference to `web::uri_builder::to_string()'

I imagine it is some mistake Iā€™m making trying to set up my CMakeLists.txt file or some other build misconfiguration on my part. Hereā€™s the CMakeLists.txt file where Iā€™ve attempted to combine them (Iā€™ve commented out a couple of lines I had tried so far):

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
set(CMAKE_VERBOSE_MAKEFILE ON)

project(cinder_cpprest)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wextra -Wno-unused-parameter")

get_filename_component(cinder_dir "~/Cinder/" ABSOLUTE)
get_filename_component(source_dir "${CINDER_CURRENT_SOURCE_DIR}" ABSOLUTE)

include("${cinder_dir}/proj/cmake/modules/cinderMakeApp.cmake")

#include_directories(/usr/local/include/cpprest)
#link_directories(/usr/local/lib)

ci_make_app(
  CINDER_PATH  ${cinder_dir}
  SOURCES      ${source_dir}/main.cpp
  LIBRARIES    cpprest boost_system boost_thread crypto ssl pthread
)