Giter Club home page Giter Club logo

cwds's Introduction

cwds submodule

This repository is a git submodule providing standard-ish support code for applications that use libcwd.

It provides the following features,

  • defines all libcwd debug macros as empty (with the exception of LibcwDoutFatal) when not compiling with debug support.
  • defines the extra helper macros:
    • CWDEBUG_ONLY(...)
    • COMMA_CWDEBUG_ONLY(...)
    • DEBUG_ONLY(...)
    • COMMA_DEBUG_ONLY(...)
    • ASSERT(expr)
  • and when compiled with debugging, the macros,
    • NAMESPACE_DEBUG
    • NAMESPACE_DEBUG_START
    • NAMESPACE_DEBUG_END
    • NAMESPACE_CHANNELS
    • DEBUGCHANNELS
    • NAMESPACE_DEBUG_CHANNELS_START
    • NAMESPACE_DEBUG_CHANNELS_END
    • DoutEntering
  • Declares initialization functions for libcwd to be called from the top of main and the start of threads.
  • Defines a global mutex to be used for std::cout (if you want output to std::cout not to interfer with debug output).
  • Defines a class tracked::Tracked<&name> that can be used to track proper use of move/copy constructors and assignment operators.
  • Provides a function to turn an address into a string with filename and line number.
  • Provides code for benchmarking (declared in cwds/benchmark.h).
  • Support for plotting graphs (using gnuplot).
  • Defines exception safe struct for indenting debug output (Indent) and making temporarily making allocation invisible (InvisibleAllocations).
  • Provides a function to print simple variables from a signal handler (cwds/signal_safe_printf.h).
  • Defines a streambuf class that can be used to turn background color of all debug output green.
  • Defines ostream serializers for many types to pretty-print them easily to a debug stream, like
    • timeval
    • boost::shared_ptr<T>
    • boost::weak_ptr<T>
    • std::pair<T1, T2>
    • std::map<T1, T2, T3>

Checking out a project that uses the cwds submodule

To clone a project example-project that uses cwds simply run:

git clone --recursive <URL-to-project>/example-project.git
cd example-project
./autogen.sh

The --recursive is optional because ./autogen.sh will fix it when you forgot it.

Adding the cwds submodule to a project

To add this submodule to a project, that project should already be set up to use cwm4.

Then simply execute the following in the root of that project:

git submodule add https://github.com/CarloWood/cwds.git

This should clone cwds into the subdirectory cwds, or if you already cloned it there, it should add it.

Typically you should use gitache to install libcwd itself. In that case, set the GITACHE_ROOT environment variable as described in the documentation of gitache and add the following to the root CMakeLists.txt file of your project:

 ... [cmake_minimum_required, project and CMAKE_CXX_STANDARD]
# Begin of gitache configuration.
set(GITACHE_PACKAGES libcwd_r)
include(cwm4/cmake/StableGitache)
# End of gitache configuration.

# This project uses aicxx modules.
include(cwm4/cmake/AICxxProject)

include(AICxxSubmodules)
 ...

And add ${AICXX_OBJECTS_LIST} to every target that uses cwds (aka, debugging). For example,

add_executable(sum_first_n_primes sum_first_n_primes.cxx)
target_link_libraries(sum_first_n_primes PRIVATE ${AICXX_OBJECTS_LIST})

To use gitache for libcwd you also have to create the file <project_root>/cmake/gitache-configs/libcwd_r.cmake with normally the following content (see gitache for more information):

gitache_config(
  GIT_REPOSITORY
    "https://github.com/CarloWood/libcwd.git"
  GIT_TAG
    "master"
  CMAKE_ARGS
    "-DEnableLibcwdAlloc:BOOL=OFF -DEnableLibcwdLocation:BOOL=ON"
)

As described in the documentation of libcwd, each (C++) source file must begin with #include "sys.h" and use #include "debug.h" when containing any debug code. This submodule provides those header files, but there is some room for tuning the namespace used for the debugging specific code of the application.

The following namespaces are relevant:

namespace example {
  namespace debug {
    namespace channels {
      namespace dc {

Where namespace example is optional, in fact, anything inside namespace debug can be put anywhere, we're just using example::debug as the example right now.

Also the name of namespace channels can be changed, although that is only necessary in special cases when writing a library that wishes to reuse the name of an existing debug channel. You'll know when you need that, until then I suggest you'll just leave it at channels.

By default (which is ok for any application, but not for libraries) the debug namespace is just debug::, thus no namespace example. This is the case when directly including the debug.h provided by this submodule. Hence, a library should provide yet another debug.h file and make sure that is first in the include path. Other submodules, which don't know if such a debug.h is provided should therefore use the following order of include paths: first the top build directory, then the top source directory and last the cwds directory in the top source directory.

So that library projects (or applications) can put a debug.h in their top source directory that contains something like

#pragma once

// These three defines are only necessary if you want the 'example' namespace.
// The default is just 'debug'.
#define NAMESPACE_DEBUG example::debug
#define NAMESPACE_DEBUG_START namespace example { namespace debug {
#define NAMESPACE_DEBUG_END } }
#include "cwds/debug.h"

#ifdef CWDEBUG
NAMESPACE_DEBUG_CHANNELS_START
extern channel_ct my_channel;
extern channel_ct ...
NAMESPACE_DEBUG_CHANNELS_END
#endif

or if they don't, that then cwds/debug.h will be included directly. The top build directory include is needed to find any generated header files, most notably sys.h.

Debug channels that are only used in a single compilation unit can be defined by just adding

#include "sys.h"
#include "debug.h"

[...]

#ifdef CWDEBUG
NAMESPACE_DEBUG_CHANNELS_START
channel_ct my_channel;
NAMESPACE_DEBUG_CHANNELS_END
#endif

of the respective source file, of course.

In order to initialize libcwd properly, the following has to be added to the top of main:

int main()
{
  Debug(NAMESPACE_DEBUG::init());

The first three lines are actually something from ai-utils, just shown here to show the typical order.

Threads on the other hand need to begin with the following code:

  Debug(NAMESPACE_DEBUG::init_thread());

Finally, run

./autogen.sh

to let cwm4 do its magic, and commit all the changes.

There is a tutorial video on youtube that shows how to set up a project with cwds and libcwd here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.