Skip to content
Snippets Groups Projects
Commit fbcfb7f6 authored by Bienchen's avatar Bienchen
Browse files

First kind of tutorial

parent 6f5f97e4
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,9 @@ documented inline. One exception exists on the example-driven approach: ...@@ -11,6 +11,9 @@ documented inline. One exception exists on the example-driven approach:
following the :mod:`~promod3.core` module for your setup is not advisable. This following the :mod:`~promod3.core` module for your setup is not advisable. This
one is a bit special and provides core functionality to everybody else. one is a bit special and provides core functionality to everybody else.
In the end of this chapter you will find a little walk-through on how to get
started.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
|git| Branches |git| Branches
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
...@@ -201,16 +204,17 @@ will provide you with a target ``test_awesome_feature.py_run``. ...@@ -201,16 +204,17 @@ will provide you with a target ``test_awesome_feature.py_run``.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Writing Documentation Writing Documentation
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
To create documentation, we use |sphinx|_ to go from |restructuredtext|_ files To create documentation, we use |sphinx|_ to go from |restructuredtext|_
and API documentation in source files to HTML or man pages. (|restructuredtext_abrv|) files and API documentation in source files to HTML
or man pages.
For each module, at least one |restructuredtext| document exists, that gives an
idea of concepts and pulls in interfaces from source. Copying files to the For each module, at least one |restructuredtext_abrv| document exists, that
build directory, issuing the |sphinx| call and everything else that is needed gives an idea of concepts and pulls in interfaces from source. Copying files to
to create the actual documentation is done by |cmake| and its makefiles. Hence, the build directory, issuing the |sphinx| call and everything else that is
the :file:`CMakeLists.txt` of the :file:`doc` directory of a module is crucial. needed to create the actual documentation is done by |cmake| and its makefiles.
For documentation which does not relate to a particular module, the repository Hence, the :file:`CMakeLists.txt` of the :file:`doc` directory of a module is
comes with a top-level :file:`doc` directory. crucial. For documentation which does not relate to a particular module, the
repository comes with a top-level :file:`doc` directory.
While you should not spend to much time thinking about how to format While you should not spend to much time thinking about how to format
documentation, here is a helpful list of standard formatters: documentation, here is a helpful list of standard formatters:
...@@ -219,8 +223,272 @@ http://sphinx-doc.org/markup/inline.html ...@@ -219,8 +223,272 @@ http://sphinx-doc.org/markup/inline.html
If you write new functionality for |project|, or fix bugs, feel free to extend If you write new functionality for |project|, or fix bugs, feel free to extend
the Changelog. It will be automatically pulled into the documentation. the Changelog. It will be automatically pulled into the documentation.
--------------------------------------------------------------------------------
How To Start Your Own Module
--------------------------------------------------------------------------------
This is just a walk-through how the topics from above work together when you
start your own module. For the entry point, lets assume that you already cloned
the repository into a directory and just changed into it.
All new features should take off from the ``develop`` branch. That way, they
work fine with all the other new fellows waiting for release right from the
beginning. Therefore you need to switch branches as a first step. |git| will
tell you for which branch you went, a story of failure otherwise.
.. code-block:: console
$ git checkout develop
Switched to branch 'develop'
$
Sitting on top of the right code basis, you should just spawn your own branch
from it. As an example, your feature will go by the name of 'sidechains'.
.. code-block:: console
$ git checkout -b sidechains
Switched to a new branch 'sidechains'
$
This time, |git| should tell you about going for **a new** branch.
Now create the directory structure where your project will live. Here is the
list of directories which are likely to be used in every project.
.. code-block:: console
$ mkdir -p sidechains/doc
$ mkdir -p sidechains/pymod
$ mkdir -p sidechains/tests
$
If you run ``git status`` at this point, you will see basically nothing. That
is, |git| does not admire empty directories. Before you bring your module under
version control, create a couple of files which are always needed.
.. code-block:: console
$ touch sidechains/pymod/__init__.py
$ echo "FOO" >> sidechains/doc/index.rst
$ echo ":mod:\`~promod3.sidechains\` - ProMod3 side chain optimiser" >> sidechains/doc/index.rst
$ echo "================================================================================" >> sidechains/doc/index.rst
$
Having an empty :file:`__init__.py` is perfectly fine for |python|, it just
announces a directory as a module. But a blank :file:`index.rst` has the chance
to give |sphinx| quite a headache so you already fill it with a headline for
your documentation.
For integration with :command:`make`, the build system needs to now about the
new module and its members. This goes for setting up new |cmake| files and
extending some around the directory root.
.. code-block:: console
$ touch sidechains/CMakeLists.txt
$ touch sidechains/pymod/CMakeLists.txt
$ touch sidechains/doc/CMakeLists.txt
$
Each of those files still needs a bit of content. The simplest one comes from
the module's root, :file:`sidechains/CMakeLists.txt`:
.. code-block:: cmake
:linenos:
add_subdirectory(pymod)
add_subdirectory(doc)
Those two directives just tell |cmake| to go and look in directories
:file:`pymod` and :file:`doc` below the current path for more |cmake|
configurations. The next level in :file:`CMakeLists.txt` magic comes for the
:file:`doc` directory:
.. code-block:: cmake
:linenos:
set(SIDECHAINS_RST
index.rst
)
add_doc_source(NAME sidechains RST ${SIDECHAINS_RST})
``add_doc_source`` is our custom |cmake| macro to register
|restructuredtext_abrv| files for the documentation. On running
:command:`make`, those files are placed in a :file:`doc/source` directory tree
within the build directory. Each new submodule in your project should be
covered by its own documentation entity, extending the list in ``RST``.
Maintaining readability, its good practice to store this list in a separate
variable, called ``SIDECHAINS_RST`` here.
For the actual code, you should keep in mind that a |python| module may be
rather complex. There is for sure |python| code, there could be a bit of |C++|
and conditional compilation. In rare cases you also want to modify the
directory structure of the package. All this has to be declared in the
:file:`pymod` subtree. We cannot enumerate all specialities but there should be
a couple of examples around in this repository. Here is the most basic
:file:`CMakeLists.txt`:
.. code-block:: cmake
:linenos:
set(SIDECHAINS_PYMOD
__init__.py
)
pymod(NAME sidechains PY ${SIDECHAINS_PYMOD})
Source files should be again listed in a dedicated variable. Later, you
probably add some |C++| code and settings diverging from the defaults via the
``pymod`` macro. This is where things clutter up quite quickly. As set up here,
your project would be added as a module ``sidechains`` in the |project|
|python| package tree.
The final step towards |cmake| is to register your module's directory in the
top level :file:`CMakeLists.txt`:
.. code-block:: cmake
:linenos:
:emphasize-lines: 80
#-------------------------------------------------------------------------------
# Author: Bienchen
#-------------------------------------------------------------------------------
# Options to CMake:
# DISABLE_DOCUMENTATION: Don't build documentation, don't search for Sphinx
# DISABLE_DOCTEST: Don't run example code from documentation on 'make check'
# DISABLE_LINKCHECK: Don't test links from documentation on 'make check'
# (if documentation is disabled, there is no doctest, linkcheck at all)
cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake_support)
project(PROMOD3 CXX C)
include(PROMOD3)
set(PROMOD3_VERSION_MAJOR 0)
set(PROMOD3_VERSION_MINOR 1)
set(PROMOD3_VERSION_PATCH 0)
set(PROMOD3_VERSION_STRING ${PROMOD3_VERSION_MAJOR}.${PROMOD3_VERSION_MINOR}.${PROMOD3_VERSION_PATCH})
if (CMAKE_COMPILER_IS_GNUCXX)
exec_program(gcc ARGS --version OUTPUT_VARIABLE CMAKE_C_COMPILER_VERSION)
if(CMAKE_C_COMPILER_VERSION MATCHES ".*4\\.[5-9].*")
set(PROMOD_GCC_45 true)
else()
set(PROMOD_GCC_45 false)
endif()
endif()
if (OPTIMIZE)
set(CMAKE_BUILD_TYPE Release)
set(_OPT ON)
else()
set(CMAKE_BUILD_TYPE Debug)
set(_OPT OFF)
endif()
setup_stage()
file(MAKE_DIRECTORY ${STAGE_DIR}
${EXECUTABLE_OUTPUT_PATH}
${HEADER_STAGE_PATH}
${LIB_STAGE_PATH}
${LIBEXEC_STAGE_PATH})
setup_compiler_flags()
setup_boost()
find_package(Python 2.7 REQUIRED)
if(NOT DISABLE_DOCUMENTATION)
find_package(Sphinx ${PYTHON_VERSION} REQUIRED)
set(PYTHON_DOC_URL "https://docs.python.org/${PYTHON_VERSION}")
# set this to the URL corresponding to the version of OST you are using
set(OST_DOC_URL "http://www.openstructure.org/docs/1.3")
endif()
find_package(OPENSTRUCTURE 1.4 REQUIRED
COMPONENTS io mol seq seq_alg mol_alg conop)
if (CMAKE_COMPILER_IS_GNUCXX)
# do not write back into cache, otherwise the compile command line gets
# expanded with multiple -fno-strict-aliasing flags, triggering a complete
# rebuild whenever cmake is run
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-strict-aliasing")
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER "4.6")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes")
endif("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER "4.6")
endif()
# basic environment
include_directories(${Boost_INCLUDE_DIRS}
${OST_INCLUDE_DIR})
set(FILES_TO_BE_REMOVED ${PROJECT_BINARY_DIR}/stage)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
"${FILES_TO_BE_REMOVED}")
## sub dirs to be recognised by CMake
## e.g. add_subdirectory(src), subdirs have their own CMakeLists.txt
add_subdirectory(config)
add_subdirectory(core)
add_subdirectory(sidechains)
add_subdirectory(scripts)
add_subdirectory(actions)
if(NOT DISABLE_DOCUMENTATION)
add_changelog_to_doc(FILE "${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG")
add_subdirectory(doc)
endif()
## report setup
message(STATUS "PROMOD3 will be built with the following options:\n"
" OpenStructure (-DOST_ROOT) : ${OST_ROOT}\n"
" Optimized (-DOPTIMIZE) : ${_OPT}\n"
" Python : ${PYTHON_BINARY}\n")
All that needs to be done for |cmake| to recognise your module is adding its
directory as shown in line 80.
This was the final step to set up the build system. Running |cmake| at this
point would create the build environment in place. But building software in
your code repository has several drawbacks. First of all, it puts all kind of
new files in the directory tree and ``git status`` would show them all. Then
its very likely, that manual intervention is needed after ``make clean``. Plus,
this would be very static. Imagine at one point you want to switch on all
debugging flags for your |C++| code. So you either clean the whole repository
and rebuild or you go by two separated repositories copying code changes from A
to B. The solution to this is instead of 'in place' you go 'out of source'. You
still can stay in your repository while being out of the source tree by using
sub-directories. |project| comes with a dedicated prefix 'build*' in
:file:`.gitignore`. Have a directory :file:`build` and :file:`build-dbg` and it
will not show up in ``git status``.
.. code-block:: console
$ mkdir build
$ cd build
$
To actually create all the makefiles and generated files, you may use one of
the configuration scripts from the :file:`conf-scripts` directory. Usually
those scripts only need to be pointed to an |ost_s| staging tree. Even if you
are on a system not covered by available scripts, their code may help you at
the |cmake| command. Once you managed to conquer a new system, feel free to add
a new configuration script. The following example assumes |fedora| 19.
.. code-block:: console
$ ../conf-scripts/fedora-19-conf ../../ost.git/stage
From this point, :command:`make` should work and you could start adding your
files to the repository using ``git add``.
.. _restructuredtext: http://docutils.sourceforge.net/rst.html .. _restructuredtext: http://docutils.sourceforge.net/rst.html
.. |fedora| replace:: Fedora
.. LocalWords: cmake hotfix doctest linkcheck rebase BRANCHNAME rebasing py .. LocalWords: cmake hotfix doctest linkcheck rebase BRANCHNAME rebasing py
.. LocalWords: CMakeLists txt rst pymod init submodule src restructuredtext .. LocalWords: CMakeLists txt rst pymod init submodule src restructuredtext
.. LocalWords: makefiles formatters Changelog codetest promod .. LocalWords: makefiles formatters Changelog codetest promod sidechains io
.. LocalWords: mkdir linenos subdirectory abrv emphasize CXX GNUCXX gcc fno
.. LocalWords: ARGS endif OPTIMIZE LIBEXEC Wno DIRS dirs subdirs config dbg
.. LocalWords: changelog Optimized DOPTIMIZE gitignore cd conf
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment