Chi-Tech
Using Chi-Tech as a library

So you want to use Chi-Tech as a library

Step 1 - Make a application directory and empty source file

Wherever you like, create a folder that will contain your application.

mkdir TestApp
cd TestApp

Now create an empty source file

>test.cc

_

Step 2 - Create CMakeLists.txt file

In the folder you just created create a text file called CMakeLists.txt

>CMakeLists.txt

_

Step 3 - Edit the cmake file to connect to Chi-Tech

We need to specify a few values to be included in the CMakeLists.txt file.

  • The desired application/executable name, for now we will call that test.
  • The Chi-Tech "downstream" cmake include, Downstream.cmake.
cmake_minimum_required(VERSION 3.12)
set(TARGET test_app)
project(test CXX)
#------------------------------------------------ DEPENDENCIES
if (NOT DEFINED CHI_TECH_DIR)
if (NOT (DEFINED ENV{CHI_TECH_DIR}))
message(FATAL_ERROR "***** CHI_TECH_DIR is not set *****")
else()
set(CHI_TECH_DIR "$ENV{CHI_TECH_DIR}")
endif()
endif()
message(STATUS "CHI_TECH_DIR set to ${CHI_TECH_DIR}")
include("${CHI_TECH_DIR}/resources/CMakeMacros/Downstream.cmake")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
file (GLOB_RECURSE SOURCES "*.cc")
add_executable(${TARGET} "${SOURCES}")
if(UNIX AND NOT APPLE)
target_link_libraries(${TARGET} ${CHI_LIBS} -Wl,--whole-archive ChiLib -Wl,--no-whole-archive )
elseif(APPLE)
target_link_libraries(${TARGET} ${CHI_LIBS} -Wl,-all_load ChiLib )
endif()
file(WRITE ${PROJECT_SOURCE_DIR}/Makefile "subsystem:\n" "\t$(MAKE) -C chi_build \n\n"
"clean:\n\t$(MAKE) -C chi_build clean\n")

The set(TARGET test_app) line sets the name of the eventual executable to be used. You can use any name other than test. The include statement allows you to connect to all the resources connected to Chi-Tech, including lua, PETSc, etc. Make sure that this environment variable is set. You will have to find the location where you compiled Chi-Tech in order to properly specify the location of Downstream.cmake. Once this is properly specified, the cmake-variable CHI_LIBS will be defined and the necessary include-files will be usable. The line file (GLOB_RECURSE SOURCES "*.cc") adds all .cc files, in the current directory, to the list of sources to compile. To specify specific source-file names use set(SOURCES "test.cc"). Alternatively cmake functionality can be googled to determine how to add sub-directories.

_

Step 4 - Add the basic code to test.cc

#include "chi_runtime.h"
#include "chi_log.h"
int main(int argc, char* argv[])
{
chi::Initialize(argc,argv);
chi::RunBatch(argc, argv);
chi::log.Log() << "Hello World!";
//We will add code here
chi::Finalize();
return 0;
}
int main(int argc, char **argv)

This code is the minimum needed to have everything available in Chi-Tech. The basic namespace access is provided via #include "chi_runtime.h"

MPI initialization and PETSc initialization is handled via the call to chi::Initialize().

Finally all MPI and PETSc related items are destroyed via the call to chi::Finalize().

_

Step 5 - Compile the code

Well, we should probably state here that you should make sure ChiTech compiled. This can be done by running the test cases. If all is well then proceed to make build directory (TestApp/build) for this app.

mkdir build
cd build

Next execute cmake from this directory, giving it the directory-location of the CMakeLists.txt created in step 2.

cmake ../

If all is well here then simply run make:

make -j4

_

Adding lua-input to library-using apps

For this section we refer to the section above where we created a test application.

Step 1 - Create folder to contain lua sources.

Purely for categorization, create a lua folder in the TestApp folder

cd ../TestApp
mkdir lua
cd lua

Step 2 - Create a source file

Let us pretend that we will have a status update message that we want to be printed from a lua call. Create a file called testapp_statusmess.cc with the following contents:

#include "chi_lua.h"
#include "chi::log.h"
int chiPrintStatus(lua_State *L)
{
ChiLog& log = ChiLog::GetInstance();
log.Log() << "Hello from here";
return 0;
}

_

Step 3 - Modify the CMakeLists.txt file to compile this code

In preparation for adding many more sources to the lua folder, edit the CMakeLists.txt file as follows:

cmake_minimum_required(VERSION 3.2)
SET(TARGET test)
project(${TARGET} C CXX)
include(~/Desktop/ChiTech/chi-tech/CHI_RESOURCES/Macros/Downstream.cmake)
include(~/Desktop/ChiTech/chi-tech/CHI_RESOURCES/Macros/Filter.cmake)
set(SOURCES "test.cc" )
file (GLOB_RECURSE MORE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/lua/*.cc")
set(SOURCES ${SOURCES} ${MORE_SOURCES})
add_executable(${TARGET} "${SOURCES}")
target_link_libraries(${TARGET} ${CHI_LIBS})

This will allow any .cc file in the lua folder to be compiled with the project. The line

file (GLOB_RECURSE MORE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/lua/*.cc")

recursively searches through the specified folder and pumps any filenames ending with .cc into the variable MORE_SOURCES. This variable gets added to the manually specified SOURCES variable using the line

set(SOURCES ${SOURCES} ${MORE_SOURCES})

_

Step 4 - Modify test.cc to register the lua function

Modify your test.cc source file to be

#include "chi_runtime.h"
int main(int argc, char* argv[])
{
ChiTech::Initialize(argc,argv);
ChiConsole& console = ChiConsole::GetInstance();
auto L = console.consoleState;
#include "ChiMacros/lua_register_macro.h"
RegisterFunction(chiPrintStatus);
ChiTech::Finalize();
return 0;
}

Notice here that we firstly included the header file for the ChiConsole object. This is the object that allows us to connect to the lua state.

#include "ChiConsole/chi_console.h"

Next we obtained a reference to the console through

ChiConsole& console = ChiConsole::GetInstance();

We then setup the variable L, which is needed by the macro file ChiMacros/lua_register_macro.h.

auto L = console.consoleState;
#include "ChiMacros/lua_register_macro.h"

This macro file exposes numerous lua macros, one of which is the RegisterFunction(x) macro where we will supply the x as the function call we defined earlier:

RegisterFunction(chiPrintStatus);