[CMake] Disallowing in-source builds

aaron.meadows at thomsonreuters.com aaron.meadows at thomsonreuters.com
Fri Oct 8 15:05:29 EDT 2010


Here's what I ended up with:

 

function(AssureOutOfSourceBuilds)

  # make sure the user doesn't play dirty with symlinks

  get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)

  get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)

 

  # disallow in-source builds

  if(${srcdir} STREQUAL ${bindir})

    message("######################################################")

    message("You are attempting to build in your Source Directory.")

    message("You must run cmake from a build directory.")

    message("######################################################")

 

    # attempt to remove cache and cache files... this actually fails to
work,

    # but no hurt trying incase it starts working..

    file(REMOVE_RECURSE "${CMAKE_SOURCE_DIR}/CMakeCache.txt"
"${CMAKE_SOURCE_DIR}/CMakeFiles")

 

    message(FATAL_ERROR "In-source builds are forbidden!")

  endif()

 

  # check for polluted source tree

  if(EXISTS ${CMAKE_SOURCE_DIR}/CMakeCache.txt OR EXISTS
${CMAKE_SOURCE_DIR}/CMakeFiles)

 
message("###############################################################
#")

    message( "Found results from an in-source build in your source
directory.")

 
message("###############################################################
#")

 

    # attempt to remove cache and cache files...

    file(REMOVE_RECURSE "${CMAKE_SOURCE_DIR}/CMakeCache.txt"
"${CMAKE_SOURCE_DIR}/CMakeFiles")

 

    message(FATAL_ERROR "Source Directory Cleaned, please rerun CMake.")

  endif()

endfunction()

 

It's basically exactly what you mentioned.  I changed the order of the
checks to allow it to check for an in-source build before dealing with
the consequences of such.  I added more logging and actual cleanup.

 

Thanks for all the help. If you have any suggestions on improving this,
please let me know.  Incidentally, removing the CMakeCache.txt and
CMakeFiles directory does not work during the in-source build, but does
during the check to insure there isn't anything left over from an in
source build.  I went ahead and removed the files there and then
fatal_error'd out to allow the right CMakeCache.txt to be loaded in the
build tree when cmake is next run.

 

Aaron C. Meadows 

 

-----Original Message-----
From: Michael Wild [mailto:themiwi at gmail.com] 
Sent: Thursday, October 07, 2010 2:20 AM
To: Meadows, Aaron C.; Meadows, Aaron C.
Cc: cmake at cmake.org
Subject: Re: [CMake] Disallowing in-source builds

 

 

On 6. Oct, 2010, at 20:10 , <aaron.meadows at thomsonreuters.com>
<aaron.meadows at thomsonreuters.com> wrote:

 

> Hi all.

> 

> 

> 

> Is there a good way to disallow in-source builds?  Ideally, I'd like
to

> prevent it before any cruft is written into the source tree.  I

> experimented with writing a function into my CMakelists file and
calling

> it.  The function checked if CMAKE_BINARY_DIR was equal to

> CMAKE_SOURCE_DIR and messaged a FATAL_ERROR if that was the case.
This

> works ok, but still generates a CMakeFiles directory and a

> CMakeCache.txt file.

 

I don't think there's a way to prevent that from happening. The bad
thing about this is that if the user doesn't clean away the in-source
CMakeCache.txt file, subsequent out-of-source builds will fail. Perhaps
you can do something like this:

 

# check for polluted source tree

if(EXISTS ${CMAKE_SOURCE_DIR}/CMakeCache.txt OR

    EXISTS ${CMAKE_SOURCE_DIR}/CMakeFiles)

  message(FATAL_ERROR

    "CMakeCache.txt or CMakeFiles exists in source directory!")

endif()

# make sure the user doesn't play dirty with symlinks

get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)

get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)

# disallow in-source builds

if(${srcdir} STREQUAL ${bindir})

  message(FATAL_ERROR "In-source builds are forbidden!")

endif()

 

> 

> The second half of the question is of course, is there an easy way to

> clean out a source tree if an in-source build was accidentally kicked

> off?  (short of dividing the files by their timestamp and removing the

> newer ones, etc..)

 

No, simply because CMake cannot. Your build system might have something
like the following:

 

execute_process(COMMAND echo "BOOM" > ${CMAKE_BINARY_DIR}/boom.txt
VERBATIM)

 

CMake never knows that the file boom.txt is written, and therefor can't
clean it away. The only reasonable way I know of is using git
(http://git-scm.com):

 

git clean -df

 

will remove all the files and directories that are not part of the
repository. With tar-ball builds it's easier. Just wipe the source tree
and unpack again.

 

 

Michael



This email was sent to you by Thomson Reuters, the global news and information company.
Any views expressed in this message are those of the individual sender, except where the sender specifically states them to be the views of Thomson Reuters.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20101008/d20f7ccf/attachment-0001.htm>


More information about the CMake mailing list