[CMake] Migrating from another build system that maintains its own source file lists

Kevin Houlihan khouli at gmail.com
Tue Jun 9 21:12:57 EDT 2015


>From Alan's suggestions and some fiddling here's the solution I came up
with to the problem I posted a while back. Seems to work.

(I have no idea what the etiquette is on a mailing list like this for
posting chunks of code so just tell me if I'm doing anything wrong.)

The problem is that there's some existing build system that maintains
authoritative lists of files and we want to create a CMake build system
that updates appropriately according to this list of files.

Here's the directory structure for a simple example:

ex/
    prj/
        f1.h
        f1.cpp
        lib1_files.txt
    new_cmake_system/
        CMakeLists.txt
        make_cmakelists.sh

'lib1_files.txt' is part of some existing build system and so for the time
being it must remain the authoritative list of source files. We want a
CMake build system that can coexist with the current build system and
perhaps supplant it later. The example shown is intended to read from
lib1_files.txt and create a CMakeLists.txt as appropriate and "do the right
thing" when rebuilding.

*prj/lib1_files.txt*:

f1.cpp

*new_cmake_system/CMakeLists.txt*:

cmake_minimum_required(VERSION 2.8.11)
project(prj)

set(REL_PRJ_DIR ../prj)
get_filename_component(PRJ_DIR ${REL_PRJ_DIR} ABSOLUTE)

# command that generates the CMakeLists.txt file for a library
set(GEN_LIB1_CMAKELIST_CMD ${CMAKE_CURRENT_LIST_DIR}/make_cmakelists.sh)

# initial bootstrapping of the CMakeLists.txt file
execute_process(
    COMMAND ${GEN_LIB1_CMAKELIST_CMD}
    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
    )

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_LIST_DIR}/lib1/CMakeLists.txt
    COMMAND execute_process(COMMAND ${GEN_LIB1_CMAKELIST_CMD})
    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
    )
add_custom_target(
    lib1_cmakelists
    DEPENDS ${CMAKE_CURRENT_LIST_DIR}/lib1/CMakeLists.txt
    )

add_subdirectory(lib1)
add_dependencies(lib1 lib1_cmakelists)

And even though it's just a crude example, for completeness here's
*make_cmakelists.sh*:

#!/usr/bin/env bash

cmakelistsfile=lib1/CMakeLists.txt

mkdir lib1 2> /dev/null
echo 'set(SRCS' > $cmakelistsfile
while read line; do
    echo '    ${PRJ_DIR}/'$line
done < ../prj/lib1_files.txt  >> $cmakelistsfile
echo '    )'  >> $cmakelistsfile

echo 'add_library(lib1 SHARED ${SRCS})' >> $cmakelistsfile

The whole boot strapping thing via execute_process() feels a little funny
but the whole thing seems to update appropriately when files are added or
removed from the example project.


On Thu, May 28, 2015 at 1:11 PM, Alan W. Irwin <irwin at beluga.phys.uvic.ca>
wrote:

> Hi Kevin:
>
> I believe this discussion continues to belong on the cmake list so I have
> CC'd
> there.
>
>
>  On Wed, May 27, 2015 at 2:17 PM, Alan W. Irwin <irwin at beluga.phys.uvic.ca
>> >
>> wrote:
>>
>>  On 2015-05-27 13:48-0400 Kevin Houlihan wrote:
>>>
>>>  Hello,
>>>
>>>>
>>>> I want to migrate from a build system that has its own lists of source
>>>> files that must be maintained for the time being. I have scripts to
>>>> translate those list files into CMakeLists.txt files but I don't know
>>>> of a
>>>> good way to integrate those into a CMake generated build system and keep
>>>> the generated CMakeLists.txt files up to date with the files they were
>>>> generated from.
>>>>
>>>> My current solution is to use a Makefile to check to see if the
>>>> CMakeLists.txt files need to be updated as part of the build. This is a
>>>> bit
>>>> clumsy.
>>>>
>>>> The issue seems similar to the problem of using file globbing in
>>>> CMakeLIsts.txt files and as far as I know, the answer there is "don't do
>>>> that". Still I thought I'd try my luck.
>>>>
>>>> Any suggestions?
>>>>
>>>>
>>> Use a CMake list of files, and maintain that, e.g.,
>>>
>>> set(lib_SRC_FILE_LIST
>>> a.c
>>> b.c
>>> c.c
>>> [...]
>>> )
>>>
>>> add_library(lib ${lib_SRC_FILE_LIST})
>>>
>>> or if there are thousands of files in the list and you don't want
>>> to disrupt the logic of your principal CMakeLists.txt files with
>>> lists scattered all over within the file, then look at
>>> the include(...) command which will include CMake source code
>>> from a file (say completely devoted to the above list creation command).
>>>
>>>
> On 2015-05-28 08:31-0400 Kevin Houlihan wrote:
>
>  Sorry, I wasn't clear. The list of source files from the existing
>> non-CMake
>> build system is the authoritative list and whenever it changes
>> (potentially
>> by people who aren't me) I want the CMakeLists.txt files to automatically
>> update. Generating the CMakeLists.txt files isn't the issue, it's
>> automating that process.
>>
>
> Just for reference the actual quote you were referring to is likely
> from <http://www.cmake.org/cmake/help/v3.2/command/file.html> which
> says:
>
> "Note We do not recommend using GLOB to collect a list of source files
> from your source tree. If no CMakeLists.txt file changes when a source
> is added or removed then the generated build system cannot know when
> to ask CMake to regenerate."
>
> Does this mean that a summary of your need is that you want an
> automated method such that if a source file was added or deleted for
> an already configured build of a library, then the next attempt to
> build that library would regenerate the list of source files for that
> library?
>
> If so, that is an intriguing problem.  I have never tried anything
> like that, but to replace your current Makefile approach it seems to
> me the following approach would work:
>
> 1. Implement a custom command that file depended on the authorative
> list of source files for a particular library and whose OUTPUT was the
> generated CMakeLists.txt file that built that library.
>
> 2. Implement a custom target which file depended on that OUTPUT file.
>
> 3. Use add_dependencies to make the library target depend on the
> custom target (so the custom target will always be built first).
>
> Of course, 1. through 3. could all be implemented as part of the generated
> CMakeLists.txt file.
>
>
> Alan
> __________________________
> Alan W. Irwin
>
> Astronomical research affiliation with Department of Physics and Astronomy,
> University of Victoria (astrowww.phys.uvic.ca).
>
> Programming affiliations with the FreeEOS equation-of-state
> implementation for stellar interiors (freeeos.sf.net); the Time
> Ephemerides project (timeephem.sf.net); PLplot scientific plotting
> software package (plplot.sf.net); the libLASi project
> (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
> and the Linux Brochure Project (lbproject.sf.net).
> __________________________
>
> Linux-powered Science
> __________________________
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20150609/50c98cf4/attachment-0001.html>


More information about the CMake mailing list