CMakeLists.txt

CMakeLists.txt

Top-level build file for TeXworks, a simple editor for TeX and friends.

This buildsystem uses CMake and consists of the following files:

  TeXworks
  ├── CMakeLists.txt
  ├── src
  │   └── CMakeLists.txt
  ├── plugins-src
  │   ├── TWLuaPlugin
  │   │   └── CMakeLists.txt
  │   └── TWPythonPlugin
  │       └── CMakeLists.txt
  └── CMake
      └── packaging
          ├── CMakeLists.html
          └── mac
              └── MacPackagingTasks.cmake.in

Using CMake as a buildsystem offers some nice advantages:

  • Supports component discovery and configuration for all three major operating systems and can set TeXworks up to be built using GNU Makefiles, XCode or Visual Studio.

  • Includes CPack, a tool which simplifies the task of packaging the TeXworks app for release after it has been built. CPack can generate Drag N' Drop installers for the Mac, Nullsoft installers for Windows and .deb or .rpm packages for Linux.

Comments in the CMake files follow Markdown formatting conventions. This convention allows the CMakeLists.txt files to be passed through a tool such as Docco to create a nicely annotated README for the benefit of future developers and maintainers.

Setup and User Options

Set project name.

PROJECT(TeXworks)

We require CMake v2.8 or greater because it is the first version that provides support for certain parts of Qt, such as the ScriptTools.

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(CMAKE_COLOR_MAKEFILE ON)

Always add the current source and binary directories to the header include path when compiling.

SET(CMAKE_INCLUDE_CURRENT_DIR ON)

IF ( WIN32 )
  MESSAGE( WARNING
    "The CMake build system has only been tested on Mac OS X and Linux."
    "\nIt probably won't work on Windows. Patches containing fixes are"
    "\nwelcomed at:"
    "\n  https://github.com/Sharpie/TeXworks"
  )
ENDIF ()

Determine Version Numbers

The values recovered here are used in the filenames of packaged builds and influence parts of the application such as the “About” dialog.

Recover canonical (x.y.z) version number from src/TWVersion.h.

FILE(STRINGS ${PROJECT_SOURCE_DIR}/src/TWVersion.h TeXworks_VER_MAJOR REGEX "VER_MAJOR")
STRING(REGEX MATCH "([0-9]+)" TeXworks_VER_MAJOR ${TeXworks_VER_MAJOR})
FILE(STRINGS ${PROJECT_SOURCE_DIR}/src/TWVersion.h TeXworks_VER_MINOR REGEX "VER_MINOR")
STRING(REGEX MATCH "([0-9]+)" TeXworks_VER_MINOR ${TeXworks_VER_MINOR})
FILE(STRINGS ${PROJECT_SOURCE_DIR}/src/TWVersion.h TeXworks_VER_PATCH REGEX "VER_BUGFIX")
STRING(REGEX MATCH "([0-9]+)" TeXworks_VER_PATCH ${TeXworks_VER_PATCH})
SET(TeXworks_VERSION ${TeXworks_VER_MAJOR}.${TeXworks_VER_MINOR}.${TeXworks_VER_PATCH})

Recover SVN revision from src/SvnRev.h.

FILE(STRINGS ${PROJECT_SOURCE_DIR}/src/SvnRev.h TeXworks_SVN_REV LIMIT_COUNT 1)
STRING(REGEX MATCH "([0-9]+)" TeXworks_SVN_REV ${TeXworks_SVN_REV})

Declare Project Options

These are options that users can set at configure-time to determine how the application is built and what functionalities it will have. Here we declare these options by setting default values.

SET(TW_BUILD_ID "personal" CACHE STRING "A distribution-specific identifier for TeXworks")

On UNIX, CMake installs to /usr/local by default. However, Mac users will probably find /Applications a more convenient default.

IF( APPLE AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local" )
  SET( CMAKE_INSTALL_PREFIX "/Applications" )
ENDIF()

Do an optimized release build by default

IF ( NOT CMAKE_BUILD_TYPE )
  SET(CMAKE_BUILD_TYPE "Release")
ENDIF ()

Options controlling the creation of scripting language plugins.

OPTION(WITH_LUA "Build TeXworks Lua plugin?" ON)
OPTION(WITH_PYTHON "Build TeXworks Python plugin?" ON)

On OS X we default to linking against the Python libraries provided by Apple even if other Pythons are available. This helps when building re-distributable .app packages. By disabling this option, a Mac user can link against whatever Python they wish for a personal build.

IF ( APPLE )
  OPTION(USE_SYSTEM_PYTHON "Link against Python Framework distributed with OS X?" ON)
ENDIF ()

Dependency Configuration

Make the contents of CMake/Modules available. Among other things, this directory contains scripts that locate project components such as Poppler.

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/Modules ${CMAKE_MODULE_PATH})

Declare Qt libraries required by this project.

SET (QT_COMPONENTS
    QtCore
    QtGui
    QtUiTools
    QtScript
    QtScriptTools
    QtXML
)

IF ( UNIX AND NOT APPLE )
  LIST(APPEND QT_COMPONENTS QtDbus)
ENDIF ()

Locate Qt. INCLUDE(UseQt4) brings in a set of macros that helps us deal with Qt-specific tasks such as compiling resources or running moc.

FIND_PACKAGE(Qt4 COMPONENTS ${QT_COMPONENTS} REQUIRED)
INCLUDE(UseQt4)

FIND_PACKAGE(ZLIB REQUIRED)
FIND_PACKAGE(Hunspell REQUIRED)
FIND_PACKAGE(Poppler REQUIRED)

The only thing Poppler should need is the location of the include directories in order to access header files. The library loader should be able to find libfontconfig on standard search paths.

IF ( POPPLER_NEEDS_FONTCONFIG )
  FIND_PACKAGE(Fontconfig REQUIRED)
ENDIF ()

Aggregate library names and include directories into variables for easy access.

SET(TeXworks_INCLUDE_DIRS
  ${QT_INCLUDE_DIR}
  ${HUNSPELL_INCLUDE_DIR}
  ${POPPLER_QT4_INCLUDE_DIR}
  ${ZLIB_INCLUDE_DIR}
)
IF ( POPPLER_NEEDS_FONTCONFIG )
  LIST(APPEND TeXworks_INCLUDE_DIRS ${FONTCONFIG_INCLUDE_DIR})
ENDIF ()

SET(TeXworks_LIB_DIRS ${QT_LIBRARY_DIR})

SET(TeXworks_LIBS
  ${QT_LIBRARIES}
  ${POPPLER_LIBRARIES}
  ${HUNSPELL_LIBRARIES}
  ${ZLIB_LIBRARIES}
)

Configure Optional Dependencies

CMake 2.8 has separate find scripts for Lua 5.1 and Lua 5.0. We assume that the most recent Lua version is installed.

IF ( WITH_LUA )
  FIND_PACKAGE(Lua51)
ENDIF()

IF ( WITH_PYTHON )
  IF ( USE_SYSTEM_PYTHON )
    SET(PYTHON_LIBRARIES "-F/System/Library/Frameworks -framework Python" CACHE PATH "Python library.")
    SET(PYTHON_INCLUDE_DIR "/System/Library/Framework/Python.framework/Headers" CACHE PATH "Python framework.")
    MARK_AS_ADVANCED(PYTHON_LIBRARIES)
    MARK_AS_ADVANCED(PYTHON_INCLUDE_DIR)
    SET(PYTHONLIBS_FOUND TRUE)
  ELSE ()

NOTE For some reason, FindPythonLibs.cmake always seems to default to /System/Library/Frameworks/Python.framework/Headers as the include path on OS X.

    FIND_PACKAGE(PythonLibs)
  ENDIF ()
ENDIF()

Update Header Templates

Some header files contain components that must be dynamically generated. For example, getDefaultBinPaths.sh is a script that tries to figure out the appropriate path to TeX binaries on UNIX-like systems.

IF ( UNIX )
  IF ( NOT EXISTS ${TeXworks_SOURCE_DIR}/src/DefaultBinaryPaths.h )
    MESSAGE(STATUS "Generating DefaultBinaryPaths.h")

    EXECUTE_PROCESS(
      COMMAND ${TeXworks_SOURCE_DIR}/getDefaultBinPaths.sh
      WORKING_DIRECTORY ${TeXworks_SOURCE_DIR}
    )
  ENDIF ()
ENDIF ()

Building

Build main TeXworks application

ADD_SUBDIRECTORY(src)

Build Plugins

Set the plugin installation path. This is a good default for UNIX-like systems, but is not appropriate for Windows.

SET(TeXworks_PLUGIN_DIR lib)

On OS X, the plugins should live inside the application bundle.

IF ( APPLE )
  SET(TeXworks_PLUGIN_DIR ${PROJECT_NAME}.app/Contents/PlugIns)
ENDIF ()

Build scripting language plugins if the required libraries are available.

IF ( LUA51_FOUND )
  ADD_SUBDIRECTORY(${TeXworks_SOURCE_DIR}/plugins-src/TWLuaPlugin)
ENDIF ()

IF ( PYTHONLIBS_FOUND )
  ADD_SUBDIRECTORY(${TeXworks_SOURCE_DIR}/plugins-src/TWPythonPlugin)
ENDIF ()

Packaging

This section is responsible for executing all tasks that run when a user invokes cpack or make package after executing their platform’s equivalent of of make. The packaging tasks are responsible for two things:

  • Applying transformations to the compiled binaries such that they can be distributed to another machine.

  • Gathering all binaries and libraries and packaging them into an archive suitable for distribution such as a Windows installer or Mac disk image file.

Gather all libraries related to Qt plugins used by TeXworks so that they can be bundled into packages.

SET(QT_PLUGINS
  ${QT_QTACCESSIBLEWIDGETS_PLUGIN_RELEASE}
  ${QT_QCNCODECS_PLUGIN_RELEASE}
  ${QT_QJPCODECS_PLUGIN_RELEASE}
  ${QT_QKRCODECS_PLUGIN_RELEASE}
  ${QT_QTWCODECS_PLUGIN_RELEASE}
  ${QT_QGIF_PLUGIN_RELEASE}
  ${QT_QJPEG_PLUGIN_RELEASE}
  ${QT_QTIFF_PLUGIN_RELEASE}
)

The file cmake/packaging/CMakeLists.txt controls the execution of tasks specific to preparing binaries for packaging on a given platform. This script is invoked via ADD_SUBDIRECTORY so that it executes after TeXworks and its components are built and installed. You cannot fixup an application bundle before it has been created…

ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/cmake/packaging)

Set CPack variables.

SET(CPACK_PACKAGE_VERSION_MAJOR ${TeXworks_VER_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${TeXworks_VER_MINOR})
SET(CPACK_PACKAGE_VERSION_PATCH ${TeXworks_VER_PATCH})
SET(CPACK_PACKAGE_VERSION ${TeXworks_VERSION})

SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}.${CPACK_PACKAGE_VERSION}-${TeXworks_SVN_REV}")

Configure Drag N' Drop installer.

IF ( APPLE )
  SET(MAC_PACK_BITS "${CMAKE_SOURCE_DIR}/cmake/packaging/mac")
  SET(CPACK_GENERATOR DragNDrop)
  SET( CPACK_DMG_BACKGROUND_IMAGE "${MAC_PACK_BITS}/texworks_dmg_background.png" )

Configure an AppleScript for applying a nice window layout to Drag N' Drop disk image.

  CONFIGURE_FILE( ${MAC_PACK_BITS}/set_dmg_layout.scpt.in
    ${PROJECT_BINARY_DIR}/set_dmg_layout.scpt
    @ONLY
  )
ENDIF ()

INCLUDE(CPack)

Summary

This section displays a nice configuration summary for the user.

These macros borrowed from the Poppler CMake scripts. They add some nice formatting to configuration info.

MACRO(CONFIG_INFO what value)
  STRING(LENGTH ${what} length_what)
  MATH(EXPR left_char "35 - ${length_what}")
  SET(blanks)
  FOREACH(_i RANGE 1 ${left_char})
    SET(blanks "${blanks} ")
  ENDFOREACH()

  MESSAGE("  ${what}:${blanks} ${value}")
ENDMACRO()

MACRO(CONFIG_YESNO what enabled)
  IF(${enabled})
    SET(enabled_string "yes")
  ELSE(${enabled})
    SET(enabled_string "no")
  ENDIF()

  CONFIG_INFO("${what}" "${enabled_string}")
ENDMACRO()

Print out configuration summary.

MESSAGE("TeXworks has been configured:\n")

CONFIG_INFO("Version" ${TeXworks_VERSION})
CONFIG_INFO("SVN Revision" ${TeXworks_SVN_REV})
CONFIG_INFO("Build ID" ${TW_BUILD_ID})
CONFIG_INFO("Compiler optimization" ${CMAKE_BUILD_TYPE})
MESSAGE("")

CONFIG_YESNO("Lua scripting plugin" LUA51_FOUND)
CONFIG_YESNO("Python scripting plugin" PYTHONLIBS_FOUND)
IF( APPLE )
  CONFIG_YESNO("  OS X system python" USE_SYSTEM_PYTHON)
ENDIF()
MESSAGE("")

MESSAGE("  TeXworks will be installed to:")
MESSAGE("      ${CMAKE_INSTALL_PREFIX}")
MESSAGE("")