Hi,
Thanks for this. I tested #1560 with the SimplexNoise block and it works fine.
-Gabor
Hi,
Thanks for this. I tested #1560 with the SimplexNoise block and it works fine.
-Gabor
Hi,
I am excited to see that there has been some significant work done towards implementing CMake into the build workflow of Cinder. I have some previous experience with porting OpenFrameworks to CMake. Both on the lib side (static/shared) and on the examples side as I do not use any IDEs and like using CMake for project configuration.
So I am new to Cinder and I would like to give it a try under OSX. Thanks for the hard work.
Cheers,
Milen
First Impression:
libcinder.a and libcinder_d seems to be building fine with XCode under OSX. The examples are running. The only issue is that boost is missing in the original project structure and every project would fail at the #include <boost/filesystem.hpp>
directive including the libcider. Once that problem is fixed, everything builds and runs.
With CMake, obviously the boost issue is there, however once that is fixed libcinder.a builds fine.
TODO:
Thanks.
boost headers are part of a submodule, make sure you do a git submodule update --init
after any time you update your cinder repo.
Thanks rich.e,
That solved the boost issues. I would like to ask couple of questions:
Right now, I am running CMake from within cinder-dev-0.9.1/build
by running cmake ..
which seems to be working so far. Is this the intended approach?
To build an example, from within the build folder cinder-dev-0.9.1/build
I would be running cmake .. -DCINDER_BUILD_SAMPLE="BezierPathIteration"
which also seems to be working but partially. The sample application would be placed under cinder-dev-0.9.1/build/Debug
however non of the assets would be placed under the package Resources
folder. So the application would crash. Only after any dependent content such as svn
assets or images are manually copied, the application will function as intended. Maybe because the COPY
functionality has not been implemented yet?
What would be the ideal workflow to build a cinder project outside of the samples
folder. Do you guys have a solution to that, or do you expect the user to come up with their own CMake scripts?
Letās say, I have a project that is a clone of the the BasicApp
sample but is inside myDevFolder/cinder_projects/ci_MyCinderApp
folder. Should I be writing my own CMakeLists.txt
or is there a way to invoke your CMake approach from with in my project?
Thanks.
Hey @symbolix,
We have tried to keep Cinderās CMake configuration aligned as much as possible with the way you would use any other CMake-based project. This means that for 1) this would be the ādefaultā way for building Cinder but there should be nothing that stops you to build Cinder from another directory. If you try a different dir structure and you hit any issues drop a line here so that we can have a look on it.
Your observations about 2) are correct. My personal opinion on that would be to have a custom post-build command that copies the assets to the binary directory from the source directory through add_custom_command.
Regarding 3) we donāt have any template generator system at the moment in place so for using a custom dir or even for creating a new app under the samples folder you would need to copy one of the existing CMakeLists.txt files and modify it for your particular needs. This should be quite straightforward since the only thing that would need to be changed besides things like project name etc. would be the CINDER_PATH variable which helps locate the exported config file of Cinder.
HTH,
Petros
build/Debug/SampleApp
or whatever), as this is the typical place where out-of-source cmake builds place the resulting binary. But yep, no assets can be found there because they live relative to the application directory. So lets discuss how to solve this.
The thing I donāt like about copying the assets folder to the build directory is that it will hinder the ability to update assets during runtime, whether with a filewatcher or just reloading your application. Either a) youād mistakenly be modifying the assets that live in the sampleās directory, or b) youād be modifying the assets in the build directory that arenāt versioned and will be overwritten during your next build.
What do people think about sym-linking the assets folder into the runtime output directory?
This isnāt just an issue for cinderās samples and tests, by the way. Iām seeing the same thing in a personal project setup, which AFAICT is the recommended way to organize a project with many dependencies and executable targets. Basically this is the structure:
[root]
CMakeLists.txt # <- carries global flags and brings in all targets from sub-projects, including libcinder
app/ # main application
-- assets/
-- proj/cmake/CMakeLists.txt
-- src/
test/ # test suite for app's various components
-- assets/
-- proj/cmake/CMakeListst.txt
-- src/
common/ # shared library used by both app and test
-- proj/cmake/CMakeLists.txt
src/ # common source files
cinder/ # where cinder lives, as a dependency of common, test, and app
blocks/ # any cinderblocks live in here
-- OSC
-- Cinder-View/
-- -- assets/
In the layout above, both the app
and test
targets have separate assets folders, and they live relative to their project folder. So if all build products end up somewhere in [root]/build
, they wonāt be automatically found.
Itās also a problem if you want to run a target from a sub-project that needs to find its own assets, such as Cinder-View in this case. Its test suite is looking for some button images that live in blocks/Cinder-View/assets/images/
, but the build product ends up in the root build dir.
Hi rich.e,
I can look into that. There are quite a few options that CMake provides. Just let me get up to speed with some of the aspects you guys have been working on
I have just managed to compile an independent cinder project, outside the cinder project structure using bits and pieces from your CMake scripts. I will create a case-study repo in a second. It will be messy but, for me, it should server as a good starting point, something I know that works.
Hello again,
This here is the initial repo:
Please let me know if there are any issues related to this. I have put this together as a case study to help myself understand the process of building a cinder application outside the cinderās own project structure.
I have added verbose messages etc. only to get a better understanding of what is happening. The idea of building libcinder
and preparing it to become an imported target is cool.
My initial question is, how can one make the build process of libcinder
a dependency for the ci_BezierPathIteration
application. Meaning, starting the build process for both libcinder
(as a dependency) and as ci_BezierPathIteration
from within the ci_BezierPathIteration/build
folder.
Maybe something like this?
ExternalProject_Add(
ci_static
SOURCE_DIR ${CINDER_PATH}
INSTALL_DIR ${cinder_install_dir}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
CMAKE_CACHE_ARGS -DCINDER_VERBOSE=On -DCMAKE_BUILD_TYPE=Release
)
In that way, the build process of libcinder
can be invoked within the project itself. Is this possible or is it a good idea?
Thanks.
Iām trying to implement some post build action like supporting make run
and post build copy.
This is what I managed to do for make run
. It should use CMAKE_RUNTIME_OUTPUT_DIRECTORY
instead of the CMAKE_BUILD_TYPE
hack, but I could not access that variable.
add_custom_target( run
COMMAND open ${CMAKE_BUILD_TYPE}/${APP_NAME}.app
DEPENDS ${CMAKE_BUILD_TYPE}/${APP_NAME}.app/Contents/MacOS/${APP_NAME}
WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}
)
I also have to define CMAKE_BUILD_TYPE
in my CMake file to make this work.
It is also often necessary to copy a shared library from a block next to the application executable. It would be more elegant to do this from the block config cmake than hacking it into the application cmake. This is what I have for a block with Leap Motion dynamic libraries in the app cmake. Iām not sure if it is possible to put this in the block cmake.
if( CINDER_MAC )
add_custom_command( TARGET ${APP_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${APP_DIR}/blocks/Cinder-Leap/lib/macosx/libLeap.dylib
${CMAKE_BUILD_TYPE}/${APP_NAME}.app/Contents/MacOS/
)
elseif( CINDER_LINUX )
...
elseif( CINDER_MSW )
...
endif()
Do you have any suggestions to make these solutions simpler, more elegant? Or is it not possible to do this with the current cinder cmake system?
Hi Gabor,
just looking into thisā¦
For the first issue I think we could get away by making the CMAKE_RUNTIME_OUTPUT_DIRECTORY
visible in the parent scope. Something like :
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} PARENT_SCOPE )
at the end of cinderMakeApp.cmake
should do the trick for this issue.
For your second issue I m not entirely sure yet what would be the best way to handle it ā Right now personally I could imagine that the BLOCKNAME_LIBRARIES
var that we introduced for non-target blocks could be of use and help here i.e we could check for this var even with blocks that define targets and if set copy these next to the binary.
Any other ideas are of course more than welcome!
Hey Rich,
I havenāt encountered a symlink approach for handling assets on a CMake project before but this should not be something that stops us from trying it out and check how it works! From the top of my head I donāt see any obvious downsides with this approach and what you mention about copying assets definitely holds true i.e you have to be really aware of which directory you are actually watching/modifying etc.
Cheers,
Petros
Hi Petros,
Thanks for the suggestions. It would be nice to have CMAKE_RUNTIME_OUTPUT_DIRECTORY
available in parent scope if you think it is a valid use case. Would it make sense to do the same with ARG_APP_NAME
as well? CMAKE_RUNTIME_OUTPUT_DIRECTORY
only contains the directory, but the executable is placed in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${ARG_APP_NAME}.app/Contents/MacOS/
on OS X. The easiest path for the dynamic libraries is next to the executable, but from the block config file this path is not possible to guess I think. Additionally, if the app name was available it would be possible to use it as a target in add_custom_command
in post build actions.
-Gabor
A warm thank you to all the team!
Videodrƶmm now runs on Linux!!!
I had to put some #if (defined( CINDER_MSW) ) || (defined( CINDER_MAC )) to compile it and avoid some segfaults, but this is very promising.
Here is my CMakeLists.txt file if you need, Iām glad to have imgui, warping, osc blocks compiling fine.
Hi @rich.e and everyone. Thanks very much for bringing CMake into the mix. Iām pretty sure that this is the primary reason Iāve been able to get Cinder running on Linux now and itās much appreciated.
I noticed that CLion support is made explicitly. As this is a RFC thread, Iād like to ask if juCi++ could possibly be supported as well? It also uses CMake as itās build system and hopefully could be integrated into your system as well.
Apologies for the silence, been working on totally unrelated thingsā¦
Re @petros exporting CMAKE_RUNTIME_OUTPUT_DIRECTORY to parent scope - Iām slightly hesitant here, as subsequent targets are going to pick this build variable up. What about defining a new variable in the parent scope, ex. CINDER_RUNTIME_OUTPUT_DIRECTORY
?
Re @gabor_papp copying dylib: yes perhaps if it is a dylib passed into cinderMakeApp()
, we should copy it to the appropriate place for the current platform. Although Iām not sure how to distinguish when we need to copy a library to be local to the app executable and when the app should be using a shared lib at some global location (ex /usr/local/lib). Open to thoughts here, but if we canāt then perhaps cinderblocks can define a custom property like CINDER_APP_COPY_LIBS
or something.
I think this weekend I will go ahead with trying out symlinking the assets folder. This will change the build folder layout slightly as on some platforms (linux) we need one extra folder with the appās name, but I donāt think it will have any side effects.
@hurpyderpy do we need to make changes to support juCi++? For CLion, it was necessary to make the cinder assets system work.
juCi++ expects a CMakeLists.txt file to be in the base folder of a project. Is it possible to accommodate this via the CMake
add_subdirectory()
command? I suppose this would mean 'add_subdirectory()'ing the other folders needed in this base CMakeLists.txt file, and CMake will find them properly thereafter.
With this addition, Juci could then pick up the other CMakeLists.txt files automatically and it seems like this is a more general approach and would accommodate more development environments both now and in the future.
edit: Clarification
juCi++ expects a CMakeLists.txt file to be in the base folder of a project.Is it possible to accommodate this via the CMake add_subdirectory() command?
Thereās a CMakeLists.txt file at the root of the repo that builds libcinder and optionally the samples. Does this work in juCi++?
After discussing, we decided for the samples themselves that they wouldnāt contain a CMakeLists.txt file in the their base folder (instead it is in proj/cmake/CMakeLists.txt) as weāre moving all build files into the proj folder to reduce clutter. This isnāt a problem in CLion at least, as you can tell it where the base directory of your project is. Thereās no feature like this in your IDE?
Edit: I also saw that juC++ is planning to ditch cmake support in favor of Bazel (yet another build language from google)ā¦
TBH, I donāt know enough about Cinder and building with it to be certain. But just now I was able to remove the previous ābuildā dir inside the Cinder checkout dir, fire up Juci in the Cinder dir, and run a project build on that folder. As far as I can tell, it worked correctly. I included a capp of my desktop for you from after the fact, and if all the output obj files and the build output info text looks right to you, then it seems safe to assume the answer is yes.
Not that Iām able to discern, no. However I wouldnāt be surprised to learn that Iām simply unaware of it.
Haha you know Juci better than I do! I was unaware of that. To me, itās a great editor with itās auto-complete and syntax error analysis and Iāve quickly become rather attached to it (even though itās still very early in itās development cycle).