Developer’s guide
Information for developersBuilding framework
For precise control over the framework or for utilizing experimental features, you can build the framework from the source. Here we will describe the step for build the framework from the latest source on github.
Dependencies
- cmake (>= 3.2)
- Boost C++ Libraries (>= 1.59)
- Intel Threading Building Blocks
- yaml-cpp
- Freeimage
- tinyobjloader
- assimp (Optional)
- If omitted,
trianglemesh::assimp
is not available.
- If omitted,
- Embree2 (Optional)
- If omitted,
accel::embree
is not available.
- If omitted,
Windows
Prerequisite
- Visual Studio 2015
- You can obtain community edition for free
- Also, the following step assumes Git for Windows is installed on your machine.
Steps
Install or build boost library
Obtain the source and the external dependencies.
$ git [email protected]:hi2p-perim/lightmetrica-v2.git $ cd lightmetrica-v2 $ git clone [email protected]:hi2p-perim/lightmetrica-v2-external.git external
NoteThe name of the directory for the external dependencies must be
external
, and placed under the root of the repository (in this case,lightmetrica-v2
).Create build directory, and generate the solution. Replace the directory for boost installation appropriately for your environment.
$ mkdir build $ cd build $ BOOST_ROOT="" BOOST_INCLUDEDIR="C:\boost\boost_1_59_0" BOOST_LIBRARYDIR="C:\boost\boost_1_59_0\lib64-msvc-14.0" TBB_ROOT="`pwd`/../external/src/tbb44_20150928oss" TBB_ARCH_PLATFORM="intel64" cmake -G "Visual Studio 14 2015 Win64" ..
Open
lightmetrica.sln
in the build directory and build (pressCtrl+Shift+B
)
Mac OS X
Prerequisite
- Install MacPorts
- Install XCode for Clang
Steps
Install dependencies
$ sudo port install cmake tbb assimp freeimage $ sudo port install boost -no_static
Install embree.
Build & install google-ctemplate
$ cd <some directory> $ git clone https://github.com/OlafvdSpek/ctemplate.git $ cd ctemplate $ ./configure $ make -j $ make install
Build & install yaml-cpp
$ cd <some directory> $ git clone https://github.com/jbeder/yaml-cpp.git $ cd yaml-cpp $ mkdir build $ cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ make -j $ make install
Build lightmetrica-v2
$ cd <some directory> $ git clone [email protected]:hi2p-perim/lightmetrica-v2.git $ cd lightmetrica-v2 $ mkdir build $ cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ make -j
Linux
The following step is checked with Ubuntu 14.04. The installation step is a little complex and disturbs your build environment, so we recommend to use docker build for use with Linux.
Steps
Install some packages
$ apt-get update -qq $ apt-get install -qq -y git software-properties-common $ add-apt-repository -y ppa:george-edison55/cmake-3.x $ apt-get update -qq $ apt-get install -qq -y python cmake build-essential libfreeimage-dev freeglut3-dev libxmu-dev libxi-dev libtbb-dev libeigen3-dev wget
Update to gcc-4.9
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test $ sudo apt-get update -qq $ sudo apt-get install -y gcc-4.9 g++-4.9 $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9
Install boost
$ wget -O boost_1_60_0.tar.bz2 "http://sourceforge.net/projects/boost/files/boost/1.60.0/boost_1_60_0.tar.bz2/download" $ tar --bzip2 -xf boost_1_60_0.tar.bz2 $ cd boost_1_60_0 && ./bootstrap.sh --with-libraries=program_options,filesystem,system,regex,coroutine,context && ./b2 -j8
Install assimp
$ git clone --depth=1 --branch v3.1.1 https://github.com/assimp/assimp.git assimp $ mkdir -p assimp/build && cd assimp/build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j 1 && make install
Install embree
$ git clone --depth=1 --branch v2.8.0 https://github.com/embree/embree.git embree $ mkdir -p embree/build && cd embree/build && cmake -D CMAKE_BUILD_TYPE=Release -D ENABLE_ISPC_SUPPORT=OFF -D RTCORE_TASKING_SYSTEM=INTERNAL -D ENABLE_TUTORIALS=OFF .. && make -j 1 && make install && cp libembree.so /usr/local/lib
Install google-ctemplate
$ git clone --depth=1 https://github.com/OlafvdSpek/ctemplate.git ctemplate $ cd ctemplate && ./configure && make -j 1 && make install
Install yaml-cpp
$ git clone --depth=1 https://github.com/jbeder/yaml-cpp.git yaml-cpp $ mkdir -p yaml-cpp/build && cd yaml-cpp/build && cmake -DCMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON .. && make -j 1 && make install
Build lightmetrica
$ mkdir -p lightmetrica/build && cd lightmetrica/build && BOOST_ROOT="" BOOST_INCLUDEDIR="/boost_1_60_0" BOOST_LIBRARYDIR="/boost_1_60_0/stage/lib" cmake -DCMAKE_BUILD_TYPE=Release .. && make -j 1
Recommended practices (C++)
This section explains some coding practices specific to this project. We introcues some coding practices necessary to implement robust application suitable to the research-oriented application. Some topics says the coding convension (as Google C++ Style Guide, which basically depends on) and some says useful coding practices for extending or reading the implementation.
The practices are based on our experience of developing research-oriented applications. Some practices might be uncommon for usual software development, however we find them effective for constructing research-oriented applications. Although they are not mandatory, we recommend to follow the practices described in this section.
File name
- The file name should be separated by underbar (_).
- e.g.,
some_header_name.h
- e.g.,
Project name
- The project name should be separated by hyphen (-).
- e.g.,
lightmetrica-test
- e.g.,
File headers
- All header and implementation file should include the license header.
- The header file should begin with
#pragma once
and should not include addtional include guards.- Rationale
- Most modern compilers support
#pragma once
. - Lack of
#endif
in traditional include guards causes tricky bugs.
- Most modern compilers support
- Rationale
Macro
- All macros should begin with
LM_
prefix- e.g.,
LM_SAFE_DELETE
- e.g.,
Namespace
- All application specic implementation should be wrapped with
LM_NAMESPACE_BEGIN
andLM_NAMESPACE_END
macros
Header files
- Headers files must not be order-dependent, so that the user of the header do not have to care about the include order.
- That is, include all dependencies in the header files
Commenting
- Use
#pragma region
as possible- To explain the code structure hierarchically
- cf. Literate programming.
Code organization
This section contains some uncommon practices. The main motto for the following practice to increase the locality of the implementation.
- Avoid to create a function that is called only once
- Instead, use scope wrapped by
#pragma region
and#pragma endregion
- Instead, use scope wrapped by
- Prefer local lambda function to private member function
Optimization
This is a topic specific to the research-oriented
application.
- The implementation should not be optimized from the first time
- If you are to optimize the application, be sure to implement 2 versions and check consistency between two results, and measure performance improvement.
- Minimize the number of states or member variables
- You should not introduce unnecessary state variables for a small optimization
- Specially in the non-optimized version, the number of cached values should be zero.
Binary boundary
- All interface should support compiler-level portability
- Use builtin component system
- All data structure should be POD type
Tab size
- The tab should be by 4 spaces. Avoid to use
\t
character.
Function
- The function declaration should use
trailing return types
supported from C++11.- Consistent handling of return types
- Keeping visually arranged looking of the code
- The return type of the lambda function should be specified
Enums
- The internal type of
enum class
should always be specified. - Ordinary
enum
type should be wrapped with a namespace
Recommended practices (CMake)
We also have the recommneded practice for writing CMake scripts.
Variables
- The local variable should begin with underbar (_).
- e.g.,
_SOURCE_FILES
- e.g.,
Project and library/executable name
- The project and library/executable names should be accessed via variables
- For project name, use
${PROJECT_NAME}
- For library or executable name, define and use local variable
${_PROJECT_NAME}
- e.g.,
set(_PROJECT_NAME "lightmetrica-test")
pch_add_executable(${_PROJECT_NAME} ...)
- e.g.,
- For project name, use