summaryrefslogtreecommitdiffstats
path: root/cmake_modules/UnityBuild.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake_modules/UnityBuild.cmake')
-rw-r--r--cmake_modules/UnityBuild.cmake158
1 files changed, 158 insertions, 0 deletions
diff --git a/cmake_modules/UnityBuild.cmake b/cmake_modules/UnityBuild.cmake
new file mode 100644
index 0000000..7c133f1
--- /dev/null
+++ b/cmake_modules/UnityBuild.cmake
@@ -0,0 +1,158 @@
+#
+# Copyright (c) 2009-2012 Christoph Heindl
+# Copyright (c) 2015 Csaba Kertész (csaba.kertesz@gmail.com)
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the <organization> nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+MACRO (COMMIT_UNITY_FILE UNITY_FILE FILE_CONTENT)
+ SET(DIRTY FALSE)
+ # Check if the build file exists
+ SET(OLD_FILE_CONTENT "")
+ IF (NOT EXISTS ${${UNITY_FILE}} AND NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${${UNITY_FILE}})
+ SET(DIRTY TRUE)
+ ELSE ()
+ # Check the file content
+ FILE(STRINGS ${${UNITY_FILE}} OLD_FILE_CONTENT)
+ STRING(REPLACE ";" "" OLD_FILE_CONTENT "${OLD_FILE_CONTENT}")
+ STRING(REPLACE "\n" "" NEW_CONTENT "${${FILE_CONTENT}}")
+ STRING(COMPARE EQUAL "${OLD_FILE_CONTENT}" "${NEW_CONTENT}" EQUAL_CHECK)
+ IF (NOT EQUAL_CHECK EQUAL 1)
+ SET(DIRTY TRUE)
+ ENDIF ()
+ ENDIF ()
+ IF (DIRTY MATCHES TRUE)
+ MESSAGE(STATUS "Write Unity Build file: " ${${UNITY_FILE}})
+ FILE(WRITE ${${UNITY_FILE}} "${${FILE_CONTENT}}")
+ ENDIF ()
+ # Create a dummy copy of the unity file to trigger CMake reconfigure if it is deleted.
+ SET(UNITY_FILE_PATH "")
+ SET(UNITY_FILE_NAME "")
+ GET_FILENAME_COMPONENT(UNITY_FILE_PATH ${${UNITY_FILE}} PATH)
+ GET_FILENAME_COMPONENT(UNITY_FILE_NAME ${${UNITY_FILE}} NAME)
+ CONFIGURE_FILE(${${UNITY_FILE}} ${UNITY_FILE_PATH}/CMakeFiles/${UNITY_FILE_NAME}.dummy)
+ENDMACRO ()
+
+MACRO (ENABLE_UNITY_BUILD TARGET_NAME SOURCE_VARIABLE_NAME UNIT_SIZE EXTENSION)
+ # Limit is zero based conversion of unit_size
+ MATH(EXPR LIMIT ${UNIT_SIZE}-1)
+ SET(FILES ${SOURCE_VARIABLE_NAME})
+ # Effectivly ignore the source files from the build, but keep track them for changes.
+ SET_SOURCE_FILES_PROPERTIES(${${FILES}} PROPERTIES HEADER_FILE_ONLY true)
+ # Counts the number of source files up to the threshold
+ SET(COUNTER ${LIMIT})
+ # Have one or more unity build files
+ SET(FILE_NUMBER 0)
+ SET(BUILD_FILE "")
+ SET(BUILD_FILE_CONTENT "")
+ SET(UNITY_BUILD_FILES "")
+ SET(_DEPS "")
+
+ FOREACH (SOURCE_FILE ${${FILES}})
+ IF (COUNTER EQUAL LIMIT)
+ SET(_DEPS "")
+ # Write the actual Unity Build file
+ IF (NOT ${BUILD_FILE} STREQUAL "" AND NOT ${BUILD_FILE_CONTENT} STREQUAL "")
+ COMMIT_UNITY_FILE(BUILD_FILE BUILD_FILE_CONTENT)
+ ENDIF ()
+ SET(UNITY_BUILD_FILES ${UNITY_BUILD_FILES} ${BUILD_FILE})
+ # Set the variables for the current Unity Build file
+ SET(BUILD_FILE ${CMAKE_CURRENT_BINARY_DIR}/unitybuild_${FILE_NUMBER}_${TARGET_NAME}.${EXTENSION})
+ SET(BUILD_FILE_CONTENT "// Unity Build file generated by CMake\n")
+ MATH(EXPR FILE_NUMBER ${FILE_NUMBER}+1)
+ SET(COUNTER 0)
+ ENDIF ()
+ # Add source path to the file name if it is not there yet.
+ SET(FINAL_SOURCE_FILE "")
+ SET(SOURCE_PATH "")
+ GET_FILENAME_COMPONENT(SOURCE_PATH ${SOURCE_FILE} PATH)
+ IF (SOURCE_PATH STREQUAL "" OR NOT EXISTS ${SOURCE_FILE})
+ SET(FINAL_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE})
+ ELSE ()
+ SET(FINAL_SOURCE_FILE ${SOURCE_FILE})
+ ENDIF ()
+ # Treat only the existing files or moc_*.cpp files
+ STRING(FIND ${SOURCE_FILE} "moc_" MOC_POS)
+ IF (EXISTS ${FINAL_SOURCE_FILE} OR MOC_POS GREATER -1)
+ # Add md5 hash of the source file (except moc files) to the build file content
+ IF (MOC_POS LESS 0)
+ SET(MD5_HASH "")
+ FILE(MD5 ${FINAL_SOURCE_FILE} MD5_HASH)
+ SET(BUILD_FILE_CONTENT "${BUILD_FILE_CONTENT}// md5: ${MD5_HASH}\n")
+ ENDIF ()
+ # Add the source file to the build file content
+ IF (MOC_POS GREATER -1)
+ SET(BUILD_FILE_CONTENT "${BUILD_FILE_CONTENT}#include <${SOURCE_FILE}>\n")
+ ELSE ()
+ SET(BUILD_FILE_CONTENT "${BUILD_FILE_CONTENT}#include <${FINAL_SOURCE_FILE}>\n")
+ ENDIF ()
+ # Add the source dependencies to the Unity Build file
+ GET_SOURCE_FILE_PROPERTY(_FILE_DEPS ${SOURCE_FILE} OBJECT_DEPENDS)
+
+ IF (_FILE_DEPS)
+ SET(_DEPS ${_DEPS} ${_FILE_DEPS})
+ SET_SOURCE_FILES_PROPERTIES(${BUILD_FILE} PROPERTIES OBJECT_DEPENDS "${_DEPS}")
+ ENDIF()
+ # Keep counting up to the threshold. Increment counter.
+ MATH(EXPR COUNTER ${COUNTER}+1)
+ ENDIF ()
+ ENDFOREACH ()
+ # Write out the last Unity Build file
+ IF (NOT ${BUILD_FILE} STREQUAL "" AND NOT ${BUILD_FILE_CONTENT} STREQUAL "")
+ COMMIT_UNITY_FILE(BUILD_FILE BUILD_FILE_CONTENT)
+ ENDIF ()
+ SET(UNITY_BUILD_FILES ${UNITY_BUILD_FILES} ${BUILD_FILE})
+ SET(${SOURCE_VARIABLE_NAME} ${${SOURCE_VARIABLE_NAME}} ${UNITY_BUILD_FILES})
+ENDMACRO ()
+
+MACRO (UNITY_GENERATE_MOC TARGET_NAME SOURCES HEADERS)
+ SET(NEW_SOURCES "")
+ FOREACH (HEADER_FILE ${${HEADERS}})
+ IF (NOT EXISTS ${HEADER_FILE})
+ MESSAGE(FATAL_ERROR "Header file does not exist (mocing): ${HEADER_FILE}")
+ ENDIF ()
+ FILE(READ ${HEADER_FILE} FILE_CONTENT)
+ STRING(FIND "${FILE_CONTENT}" "Q_OBJECT" QOBJECT_POS)
+ STRING(FIND "${FILE_CONTENT}" "Q_SLOTS" QSLOTS_POS)
+ STRING(FIND "${FILE_CONTENT}" "Q_SIGNALS" QSIGNALS_POS)
+ STRING(FIND "${FILE_CONTENT}" "QObject" OBJECT_POS)
+ STRING(FIND "${FILE_CONTENT}" "slots" SLOTS_POS)
+ STRING(FIND "${FILE_CONTENT}" "signals" SIGNALS_POS)
+ IF (QOBJECT_POS GREATER 0 OR OBJECT_POS GREATER 0 OR QSLOTS_POS GREATER 0 OR Q_SIGNALS GREATER 0 OR
+ SLOTS_POS GREATER 0 OR SIGNALS GREATER 0)
+ # Generate the moc filename
+ GET_FILENAME_COMPONENT(HEADER_BASENAME ${HEADER_FILE} NAME_WE)
+ SET(MOC_FILENAME "moc_${HEADER_BASENAME}.cpp")
+ SET(NEW_SOURCES ${NEW_SOURCES} ; "${CMAKE_CURRENT_BINARY_DIR}/${MOC_FILENAME}")
+ ADD_CUSTOM_COMMAND(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${MOC_FILENAME}"
+ DEPENDS ${HEADER_FILE}
+ COMMAND ${QT_MOC_EXECUTABLE} ${HEADER_FILE} -o "${CMAKE_CURRENT_BINARY_DIR}/${MOC_FILENAME}")
+ ENDIF ()
+ ENDFOREACH ()
+ IF (NEW_SOURCES)
+ SET_SOURCE_FILES_PROPERTIES(${NEW_SOURCES} PROPERTIES GENERATED TRUE)
+ SET(${SOURCES} ${${SOURCES}} ; ${NEW_SOURCES})
+ ENDIF ()
+ENDMACRO ()