Tup: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(inital edit)
 
No edit summary
Line 1: Line 1:
[[Category:HowTo]]
[[Category:HowTo]]
{{ambox|text=Under Construction}}
{{ambox|text=Under Construction}}
<span style="font-size:.8em;">by [[User:Simow|Simon Wilper]]</span>
== Introduction ==
== Introduction ==
According to the [http://gittup.org/tup/ homepage]
According to the [http://gittup.org/tup/ homepage]
Line 111: Line 112:
</code>
</code>


I built my own Qt5.8 and installed it to /opt/qt5.
I built my own Qt5.8 and installed it to <tt>/opt/qt5</tt>.
 
<code>
# Allow Tup to search the src directory
preload src
</code>
 
Tup needs clearance for each single directory it possibly can find source or header files. In our example we only have two files in the <tt>src<tt> subdirectory so we just need to preload this one.
 
Next we need some tup rules for creating the {{DocLink|moc}} output files. As soon you need e.g. the signal slot system of Qt or any other functionality of the Qt Meta Object system you need to generate a further cpp file with moc:
 
<code>
# Create rules for the MOC by grepping cpp files for Q_OBJECT             
run find src/ -name '*.hpp' | xargs grep -H Q_OBJECT |\                   
  awk -F: '{print ": " $1 " |> moc -o %f_moc.cpp %f |> %f_moc.cpp"}'
</code>
 
This line does the following:
 
* use <tt>find</tt> to find all header files (*.hpp)
* pipe the results to xargs using <tt>grep</tt> to find the string <tt>Q_OBJECT</tt>. We want only these headers to be processed by moc
* use <tt>awk</tt> to print the rule
 
The result should look like this:
 
<pre>
: src/mainwindow.hpp |> moc -o %f_moc.cpp %f |> %f_moc.cpp
</pre>
 
The <tt>-H</tt> commandline parameter passed to grep ensures that the output always includes the filename so that awk can easily split by colon (<tt>-F:</tt>) and print the rule.
 
Now for all headers found below <tt>src/</tt> a rule of the form above is created on the fly so that tup will execute moc for each header.

Revision as of 12:26, 8 April 2016

Under Construction

by Simon Wilper

Introduction

According to the homepage Tup is a file-based build system for Linux, OSX, and Windows. It inputs a list of file changes and a directed acyclic graph (DAG), then processes the DAG to execute the appropriate commands required to update dependent files. Updates are performed with very little overhead since tup implements powerful build algorithms to avoid doing unnecessary work. This means you can stay focused on your project rather than on your build system.

This article is going to show how tup can be used to build Qt GUI projects. Creating a project based on tup primarily evolves around creating and editing a Tupfile followed by some tup commands.

Lets assume the following small Qt project, a QtWidget containing a label, nothing fancy:

QWidget Example

main.cpp

#include "mainwindow.hpp"

void MainWindow::initialize() {
  setWindowTitle("Small QWidget Example");
  QWidget *wCmdBar = new QWidget(this);
  QHBoxLayout *layoutCmdBar = new QHBoxLayout;
  wCmdBar->setLayout(layoutCmdBar);

  mBtnClose = new QPushButton("Close",this);
  layoutCmdBar->addStretch();
  layoutCmdBar->addWidget(mBtnClose);

  QVBoxLayout *layoutCentral = new QVBoxLayout;
  mLabelInfo = new QLabel( "This is a label in a QWidget", this );
  layoutCentral->addWidget(mLabelInfo);
  layoutCentral->addWidget(wCmdBar);

  setLayout(layoutCentral);

  connect( mBtnClose, SIGNAL(clicked()), this, SLOT(handleQuit()) );
}

void MainWindow::handleQuit() {
  if ( QMessageBox::question(this, "Question", "Really quit?") == QMessageBox::Yes ) { 
    qApp->quit();
  }
}


int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  MainWindow w;
  w.initialize();
  w.show();

  return app.exec();
}

mainwindow.hpp

#ifndef __mainwindow_hpp
#define __mainwindow_hpp

#include <QApplication>
#include <QWidget> 
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
  
class MainWindow : public QWidget {
  Q_OBJECT

  public:
    void initialize();

  private slots:
    void handleQuit();

  private:
    QPushButton *mBtnClose;
    QLabel *mLabelInfo;

};

#endif

When the user clicks the close button a QMessageBox shall ask for confirmation. A slot handle_quit() is responsible for that.

Directory Structure

For this howto the following directory structure is assumed:

.
├── src
│   ├── main.cpp
│   └── mainwindow.hpp
└── Tupfile

The Tupfile

Analogous to a Makefile in a make project for tup we need a Tupfile. Unlike in cmake, qmake or qbs where things like moc files get generated automatically we need to take some extra steps in tup but nothing too difficult.

Create the Tupfile in the root directory of your project and start with some variables for the Qt installation location:

# Change the base directory to your Qt installation
qt_base=/opt/qt5
qt_include_base = $(qt_base)/include
qt_lib = $(qt_base)/lib

I built my own Qt5.8 and installed it to /opt/qt5.

# Allow Tup to search the src directory
preload src

Tup needs clearance for each single directory it possibly can find source or header files. In our example we only have two files in the src subdirectory so we just need to preload this one.

Next we need some tup rules for creating the moc output files. As soon you need e.g. the signal slot system of Qt or any other functionality of the Qt Meta Object system you need to generate a further cpp file with moc:

# Create rules for the MOC by grepping cpp files for Q_OBJECT              
run find src/ -name '*.hpp' | xargs grep -H Q_OBJECT |\                    
  awk -F: '{print ": " $1 " |> moc -o %f_moc.cpp %f |> %f_moc.cpp"}'

This line does the following:

  • use find to find all header files (*.hpp)
  • pipe the results to xargs using grep to find the string Q_OBJECT. We want only these headers to be processed by moc
  • use awk to print the rule

The result should look like this:

: src/mainwindow.hpp |> moc -o %f_moc.cpp %f |> %f_moc.cpp

The -H commandline parameter passed to grep ensures that the output always includes the filename so that awk can easily split by colon (-F:) and print the rule.

Now for all headers found below src/ a rule of the form above is created on the fly so that tup will execute moc for each header.