How to version control out-of-source build directory using CMake and SVN

CMake recommends out-of-source builds. Typically what I have are small build scripts for each build so I don’t have to manually execute the CMake command. For example my build directory might look like:

build
|--linux
|  |--build.sh
|--arm
   |--build.sh

where arm/build.sh might look like:

  • How to set up git and maven to work together?
  • Generating API documents in Git Workflow
  • Couldn't find any revision to build. Verify the repository and branch configuration for this job. Finished: FAILURE
  • git submodules as part of a build
  • Intermittent Build Failure on Jenkins
  • Jenkins/Hudson - How to run multiple jobs in parallel more than 1 level deep?
  • cmake \
        -D CMAKE_CXX_COMPILER=${CROSS_COMPILE}g++ \
        -D CMAKE_C_COMPILER=${CROSS_COMPILE}gcc \
        -D CMAKE_CXX_FLAGS="-mcpu=cortex-a9" \
        -D CMAKE_C_FLAGS="-mcpu=cortex-a9" \
        -D CMAKE_BUILD_TYPE="" \
        -G "Unix Makefiles" ../..
    

    I like how this approach informs the developer as to which platforms are supported and overall it is fine – until I want to version control the build.sh scripts. The problem I have is that when I add build to version control I pick up all the CMake build files and build directories. I know I can “ignore” the relevant directories and files, but consider what happens if I add a new build or add a new library to my top level – I then to update the ignore property in SVN for each build each time.

    This doesn’t feel very maintainable and I’m sure there’s a better way. Does anyone have any suggestions for scripting the CMake commands for each build while maintaining a ‘clean’ SVN status after a build?

  • What does the subversion error “Could not read status line” mean?
  • Work with Git and SVN at the same time
  • Bazaar and $Id$
  • How to Integrate TortoiseSVN with Eclipse IDE?
  • Better Merge Tool for Subversion
  • Ignore empty results for xargs in Mac OS X
  • 3 Solutions collect form web for “How to version control out-of-source build directory using CMake and SVN”

    You should put your build script or scripts where the source code is. It doesn’t matter if you’re doing an out-of-source build, a reusable build script belongs to the source code (just like makefiles, CMakeLists.txt).

    If I understood your problem correctly (“I will have a lot of files in tree, but want to version only small predefined subset of it”), you can use lazy-way

    1. Ignore all inside build directory
    2. Add by hand svn add FILE only needed files
    3. Repeat previous step when new configuration(s) will appear

    As result you’ll get permanent over time svn:ignore and all build-articacts will not appear in repo

    Cmake distributions usually come with a FindSubversion.cmake in the Modules folder. You just use it like this:

       find_package( Subversion )
       if( SUBVERSION_FOUND )
         Subversion_WC_INFO( ${CMAKE_CURRENT_SOURCE_DIR} MyProj )
         add_definitions( -DSVN_WC_REVISION=${MyProj_WC_REVISION}" )
       endif( SUBVERSION_FOUND )
    

    Now you have SVN_WC_REVISION defined as a preprocessor macro in your source code. It’s available to your “about” dialogue or your .rc files where you can add metadata properties to your DLL. In addition, you have no locally modified files left over after building. It’s that simple!

    Here’s some reference material from the distributed FindSubversion.cmake:

    The minimum required version of Subversion can be specified using the
    standard syntax, e.g.  find_package(Subversion 1.4)
    
    If the command line client executable is found two macros are defined:
       Subversion_WC_INFO(<dir> <var-prefix>)
       Subversion_WC_LOG(<dir> <var-prefix>)
    
    Subversion_WC_INFO extracts information of a subversion working copy
    at a given location.  This macro defines the following variables:
       <var-prefix>_WC_URL - url of the repository (at <dir>)
       <var-prefix>_WC_ROOT - root url of the repository
       <var-prefix>_WC_REVISION - current revision
       <var-prefix>_WC_LAST_CHANGED_AUTHOR - author of last commit
       <var-prefix>_WC_LAST_CHANGED_DATE - date of last commit
       <var-prefix>_WC_LAST_CHANGED_REV - revision of last commit
       <var-prefix>_WC_INFO - output of command `svn info <dir>'
    
    Subversion_WC_LOG retrieves the log message of the base revision of a
    subversion working copy at a given location.  This macro defines the
    variable:
       <var-prefix>_LAST_CHANGED_LOG - last log of base revision
    
    Example usage:
    
       find_package(Subversion)
       if(SUBVERSION_FOUND)
         Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project)
         message("Current revision is ${Project_WC_REVISION}")
         Subversion_WC_LOG(${PROJECT_SOURCE_DIR} Project)
         message("Last changed log is ${Project_LAST_CHANGED_LOG}")
       endif()
    

    I know it’s a little late, but I hope this helps you or someone else who stumbles on your question like I did as I was researching the answer (only to find the answer locally on my own machine in the Cmake modules folder).

    Git Baby is a git and github fan, let's start git clone.