Skip to content
hadjian edited this page Nov 11, 2014 · 5 revisions

November, 9th 2014

Final RPATH Configuration

Out-of-Source Build with Make

I adjusted the Makefile-based GLEW project, so it will build out-of-source. Apparently the Makefile way to do out-of-source is by passing the VPATH=<path-to-src> argument to the call to make. It's just important to know, that VPATH should point to the source files and not the binary dir as described in [1].

VPATH specifies an alternative search path for the source files specified in the rules of the Makefile (local path is still searched first). Since this prefix only counts for files referenced in rules, I needed to modify file references outside rules, e.g. in compiler command line arguments or in include statements, that include "sub"-Makefiles. Example for the compiler invocation that uses a search path (stupified for brevity):

  $(CC) -I include/ $(CFLAGS.SO) -o $@ -c $<

was changed to

  $(CC) -I ${VPATH}/include/ $(CFLAGS.SO) -o $@ -c $<

because Make just executes the command but doesn't understand it (and doesn't know which part is actually a file reference).

[1] Makefile and VPATH

October, 12th 2014

Add GLEW Search Path to ToyRenderer

Annoying. It took me too long (one hour, multiple hours, I don't know) to insert the search path for include files into the ToyRenderer project. Supposedly one of the options is to store a list of paths into the CMAKE_PREFIX_PATHvariable.

As usual, I generated the toyrenderer_inject_variables.cmake file in my superproject, which held two lines:

set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "@INJECT_GLEW_PATH@" CACHE PATH "Path to our project glew.")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "@INJECT_GLEW_INCLUDE_PATH@" CACHE PATH "Path to our project glew.")

, which I thought would add two paths to the variable. The file is used to preinitialize variables in the CMakeCache.txt before the actual cmake . call is invoked in the ToyRenderer project. My way of sneaking in variables into a subproject.

This didn't work and inspecting the generated CMakeCache.txt in the ToyRenderer project, I saw that only the first set() had an effect.

I changed the line to:

set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "@INJECT_GLEW_PATH@" "@INJECT_GLEW_INCLUDE_PATH@" CACHE PATH "Path to our project glew.")

and it worked. It works for now, but I one day would like to know how to append a string to an already initialized variable. Even more annoying is that some changes didn't have an effect, because I forgot to delete the CMakeCache.txt, so preinitialization didn't work (it is a cache you know).

September, 28th 2014

libGlew not Found by toyrendererexample (Mac OS X)

When a library like glew (which is not found by my binary) is compiled, an install_path can be inserted into the libraries binary. This serves the linker as a reference to insert into dependent binaries. This way binaries will find the library, even if it is installed in a non-standard system path. Stupid thing is, you will never be able to move it somewhere else.

Also, if the library is only available in the build tree and not yet installed to the system, this reference will resolve to nothing, like in my case. This can be checked with

otool -D libGLEW.1.10.0.dylib
libGLEW.1.10.0.dylib:
/usr/lib/libGLEW.1.10.0.dylib

and in the toyrenderer binary:

otool -L toyrendererexample 
toyrendererexample:
    /Users/hadjian/src/toyprojects/ToyProjects/build/ToyRenderer-Release/Src/libtoyrenderengine.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libGLEW.1.10.0.dylib (compatibility version 1.10.0, current version 1.10.0) 
    ...

The proposed solution is to use a macro in the install path, which can be expanded by each linked binary, so these binaries can replace the macro with a path relative to their own location. The provided macro is called @rpath, such that the install_path compiled into the library is able to only specify its relative location. In the glew project, the install_path is specified as a linker argument in config/Makefile.darwin:

  ... -install_name @rpath/$(DIST_NAME)/lib/$(LIB.SHARED) ...

The $(DIST_NAME) expands to the correct build directory (release or debug).

As for the ToyRenderer example, we append the following lines to the CMakeLists.txt file in ToyRenderer/Examples/CMakeLists.txt:

add_custom_command(TARGET toyrendererexample 
  POST_BUILD COMMAND 
  ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../../"
  $<TARGET_FILE:toyrendererexample>)

The @executable_path macro expands to the executable path, such that the e.g. an .app directory can be moved, as long as the relative location of executable and library remains the same. Pretty convoluted, but works.

The offical Apple documentation can be found under [1]. CMake will handle this mess in 2.8.12 (see [2]) and I am using 2.8.10. What an irony.

[1] [CMake adds Support for RPATH in 2.8.12] (http://www.kitware.com/blog/home/post/510)

[2] [Apple Documentation of RPATH] (https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html)

September, 27th 2014

My project currently compiles under Ubuntu and OS X. For each OS I had to change some things to make it work. What a hassle. Right now I returned to this project after a loooooooong time. Work duties were and are still bustin my ass.

Now I have to get an overview again of what I have done so far. Using --no-ff in git is definitely a good idea, as feature branches become more clear in the log output.

Right now I have two minor tasks: Make the final ToyRenderer example find the dylibs it is looking for and finally start using Qt Creator instead of vim. Code completion and fast navigation should be useful, if this project grows.