========================================================================================================
| INTEL CONFIDENTIAL
| Copyright (C) Intel Corporation All Rights Reserved.
|
| The source code contained or described herein and all documents related to
| the source code ("Material") are owned by Intel Corporation or its suppliers
| or licensors. Title to the Material remains with Intel Corporation or its
| suppliers and licensors. The Material contains trade secrets and proprietary
| and confidential information of Intel or its suppliers and licensors. The
| Material is protected by worldwide copyright and trade secret laws and
| treaty provisions. No part of the Material may be used, copied, reproduced,
| modified, published, uploaded, posted, transmitted, distributed, or disclosed
| in any way without Intel's prior express written permission.
|
| No license under any patent, copyright, trade secret or other intellectual
| property right is granted to or conferred upon you by disclosure or delivery
| of the Materials, either expressly, by implication, inducement, estoppel or
| otherwise. Any license under such intellectual property rights must be
| express and approved by Intel in writing.
|
========================================================================================================
   ____                   ________  ______   _____                               ______          __
  / __ \____  ___  ____  /  _/ __ \/ ____/  / ___/____  __  _______________     / ____/___  ____/ /__
 / / / / __ \/ _ \/ __ \ / // /_/ / /       \__ \/ __ \/ / / / ___/ ___/ _ \   / /   / __ \/ __  / _ \
/ /_/ / /_/ /  __/ / / // // ____/ /___    ___/ / /_/ / /_/ / /  / /__/  __/  / /___/ /_/ / /_/ /  __/
\____/ .___/\___/_/ /_/___/_/    \____/   /____/\____/\__,_/_/   \___/\___/   \____/\____/\__,_/\___/
    /_/

=================
| Introduction: |
=================

Welcome to the OpenIPC source code. This document will help you navigate your way through the code.
It will also teach you how to compile it, and how to add your own projects to it.

========================
| Directory Structure: |
========================

The OpenIPC source code directory structure is aimed at allowing the developer to have a rough idea
regarding the scope of a library/module given its location in the source tree. The general guideline
for the directories is as follows (your specific source release may be missing some of these directories):

<root>
|
+--- CMakeIncludes              : General CMake helper scripts
|    |
|    +--- recipes               : All supported build recipes (more on that below)
|         |
|         +--- ingredients      : All the possible ingredients (more on that below)
|
+--- IPC                        : The IPC API SDK
|
+--- OpenIPC                    : OpenIPC source code and dependencies
     |
     +--- Source                : Main OpenIPC source code
     |    |
     |    +--- Components       : Libraries that implement core OpenIPC functionality (e.g. implementations of IPC API services)
     |    |
     |    +--- Foundation       : Libraries that implement basic functionality needed by most OpenIPC components (e.g. Logging, Error handling, dealing with bit-level data, etc...)
     |    |
     |    +--- Framework        : Main OpenIPC executable, and the OpenIPC implementation of the IPC API
     |    |
     |    +--- PluginComponents : Implementations of OpenIPC RunControl and Probe plugins
     |    |
     |    +--- PluginSDK        : Main headers/source files needed by RunControl and Probe plugins
     |    |
     |    +--- Public_Include   : The headers that define the external C APIs for the modules/libraries in the "Components" and "Foundation" directories.
     |    |                       If some libraries expose C++ APIs, their headers should be under a "Public" directory in the module's main source directory
     |    |
     |    +--- Tools            : Home-grown utilities that are used during the build process, or that provide some diagnostics functionality post-release
     |
     +--- StructuredDataStore   : The repository for all target-specific information. This includes OpenIPC configuration XMLs as well as helper python scripts and target description XMLs
     |
     +--- ThirdParty            : Location of all third-party dependencies needed for building OpenIPC
     |
     +--- Tools                 : Third-party tools that may or may not be used during the OpenIPC build process (e.g. CMake executables)

=========================
| OpenIPC Build System: |
=========================

OpenIPC employs CMake as its build system. This provides us with flexibility regarding which development environment individual developers use,
as well as a maintainable, clean, cross-platform build system.

If you're not familiar with CMake, we suggest going through a few tutorials first. Helpful links:
    - "Learning CMake", by Pau Garcia i Quiles: http://www.elpauer.org/stuff/learning_cmake.pdf
    - Official CMake Wiki: https://cmake.org/Wiki/CMake
    - Official CMake Reference Documentation: https://cmake.org/cmake/help/latest/

The minimum version of CMake that's required in order to build OpenIPC is 3.7.2. There is no maximum version constraint, so you can just use the latest CMake version.

Here's a quick reference for how the CMake files are laid out in the source tree:

<root>
|
+--- CMakeIncludes                    : Includes all CMake files that are required by the "CMakeLists.txt" file that's present in the current directory
|    |
|    +--- globals.cmake               : Defines the compiler flags for the compilation
|    |
|    +--- helper_functions.cmake      : Defines functions that are used throughout our various CMake files
|    |
|    +--- recipes                     : Includes the different OpenIPC recipes
|         |
|         +--- ingredients            : Includes the different OpenIPC ingredients
|         |    |
|         |    +--- IngredientA.cmake : Includes one or more components into the build
|         |    |
|         |    +--- IngredientB.cmake : Includes one or more components into the build
|         |
|         +--- MyRecipe.cmake         : Defines some configuration knobs, extra compiler flags, and a list of ingredients that make up this OpenIPC build
|
+--- Path/to/my/component             : Includes the source code for my component
|    |
|    +--- CMakeIncludes               : Includes all CMake files that are required by the "CMakeLists.txt" file that's present in the current directory
|    |    |
|    |    +--- sources.cmake          : Defines a list of all the source files that this component requires (along with how they should be structured in the IDE)
|    |
|    +--- CMakeLists.txt              : Defines the MyComponent component
|
+--- CMakeLists.txt                   : Main CMake project

The main "CMakeLists.txt" file that drives the OpeIPC build process is located in the root directory of this source repository. This file defines some common CMake variables
and options, and includes the "globals.cmake" and "helper_functions.cmake" files.

OpenIPC's build system is structured to allow for many different "recipes" to be defined. A recipe describes _how_ the OpenIPC build should be done (through configuration knobs and compiler flags),
as well as _what_ should go into the build. The latter part is enabled by the fact that we have split groups of projects into "ingredients". Each ingredient includes one or more projects into the build.
A recipe therefore only has to list the ingredients that it's made out of, and they will be built.

Important Note: Do not define the same project in more than one ingredient, and do not include other ingredients from within one ingredient. If you feel like an ingredient is including more projects than you need,
                just split it up into multiple ingredients

The "CMakeLists.txt" that's in your component's directory needs to do the following:
    - Include the "sources.cmake" file
    - Define the component project (e.g. using CMake's "add_library()", "add_executable", etc...)
    - Define how this component should be installed

The "sources.cmake" file needs to do the following:
    - List all the source files that belong to your component
    - Define their IDE organization (using CMake's "source_group()")
    - Define which source files need to be shipped as part of a source release (using "ShipSources()" that's defined in "helper_functions.cmake")

So, in summary, in order to add a new component/project to the OpenIPC build you'll need to do the following:
    - Add CMakeLists.txt and sources.cmake for your component
    - Add your component to an existing ingredient or add a new ingredient
    - Include this ingredient in the recipes you want
    - Surf reddit for 30min as a reward for a job well done

==========================
| Building Requirements: |
==========================

The OpenIPC build process has very few requirements:
    1. CMake 3.9.3 or newer
        a. This is provided already under OpenIPC/Tools/CMake
    2. Python 2.7.8 or newer
    3. Platform-specific compiler:
        a. On Linux, this should be G++ 4.9.x (preferably 4.9.3)
        b. On macOS, this should be AppleClang 8.0.x (though 7.3.x should still work but is not recommended)
        c. On Windows, this should be Visual Studio 2015 Update 2 (i.e. 'cl.exe' version 19.00.24215.1)

=====================
| Building OpenIPC: |
=====================

One of the great advantages of CMake is the fact that it's designed to perform an "out-of-source" build.
This means that it will ensure that none of the build artifacts end up polluting your source tree.
The way it does this is by concentrating all build artifacts and results into a directory called a CMake workspace.

So the first step to building OpenIPC is to create a CMake workspace.
    1. Pick a location where your workspace should reside. This could be anywhere except your source tree.
       Do not run CMake and tell it to generate files in the source tree. One other restriction is the fact that deep directory nesting may hit OS file path length restrictions.
    2. Now that you've picked a location, create an empty directory for the workspace (call it whatever you want, there are no restrictions either)
    3. Open up a command terminal and "cd" into that empty directory
    4. Execute the following: cmake -G "<generator>" -DBUILD_RECIPE=<recipe> -DCMAKE_BUILD_TYPE=<config> <path>
        a. <generator>:                 This is the generator that CMake should use (e.g. "Visual Studio 14 Win64", or "Unix Makefiles"). For a list of all generators supported by CMake, run: cmake -G
        b. -DBUILD_RECIPE=<recipe>:     This tells our root CMakeLists.txt which recipe file it should load. The given recipe name should not include the file extension (e.g. "MyRecipe").
                                        This parameter is optional if you only have one recipe under the "recipes" directory
        c. -DCMAKE_BUILD_TYPE=<config>: Possible values for "<config>" are "Debug" or "Release". This is the build configuration. This parameter is not needed (and inconsequential) on generators where
                                        the user can select the configuration right before building (i.e. "Visual Studio", "Xcode", and some others)
        d. <path>:                      This is the path to the OpenIPC source directory (the directory that contains the main "CMakeLists.txt" file)

The workspace that you've just generated includes everything you need in order to build OpenIPC. If you used the "Visual Studio" generator, you'll find an "OpenIPC.sln" file there that you can open.
If you used "Xcode", you'll find "OpenIPC.xcodeproj". If you used "Unix Makefiles", there will be a "Makefile", and you can just run "make" to compile OpenIPC.

After compiling OpenIPC in your favorite development environment, you can find the generated binaries under the "build/<recipe>" directory inside your CMake workspace.
These generated binaries include some unnecessary build artifacts though, so if you're interested in generating a clean package of OpenIPC, you should build the "INSTALL" project in the OpenIPC solution
(if you're using Makefiles, you can just run "make INSTALL"). After this completes, you'll find a clean version of OpenIPC under the "Deploy" folder in your CMake workspace.

As a concrete example, this is what you'll need to do with a freshly downloaded OpenIPC source release:
    - Unpack the archive somewhere (e.g.: "C:\sauce")
    - Create a directory where the CMake workspace should reside
    - Open a command terminal in that directory
    - Suppose you're on Windows and are using Visual Studio 2015, you'll run: cmake -G "Visual Studio 14 2015 Win64" C:\sauce
    - Open the OpenIPC.sln file
    - After building the solution, you'll find the binaries under "build/<recipe>"

=============================
| Generating Documentation: |
=============================

Documentation is generated automatically at build time if the user has Doxygen installed and accessible through the PATH environment variable.
You will know whether Doxygen has been found by the output of the CMake workspace generation step.
If Doxygen has been found, you will see "-- Found Doxygen: /path/to/doxygen". If not, you will get the following warning: "Doxygen not found. Build will not have documentation".

This includes the following Doxygen generated documentation files:
  OpenIPC_documentation.html
  OpenIPC_Users_Guide.html

