From 11ccbe317ea7fae1deedc9747baf36b6ba67863d Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Tue, 18 Dec 2012 14:50:53 +0200 Subject: [PATCH] Added precompiled header support and enabled it for UnityCore. (bzr r2998.2.1) --- CMakeLists.txt | 3 +- UnityCore/CMakeLists.txt | 1 + UnityCore/pch/unitycore_pch.hh | 33 ++++++++++++++ cmake/isclang.cc | 26 ++++++++++++ cmake/pch.cmake | 78 ++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 UnityCore/pch/unitycore_pch.hh create mode 100644 cmake/isclang.cc create mode 100644 cmake/pch.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 2310f4770..ee0f09012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ project (unity) -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.9) include (cmake/Documentation.cmake) +include (cmake/pch.cmake) # # Base bits diff --git a/UnityCore/CMakeLists.txt b/UnityCore/CMakeLists.txt index c000adf6c..b3d270677 100644 --- a/UnityCore/CMakeLists.txt +++ b/UnityCore/CMakeLists.txt @@ -131,6 +131,7 @@ set_target_properties(${CORE_LIB_NAME} PROPERTIES VERSION ${CORE_LIB_LT_CURRENT}.${CORE_LIB_LT_REV}.${CORE_LIB_LT_AGE} SOVERSION ${CORE_LIB_LT_CURRENT} INSTALL_RPATH "${PRIVATE_CORE_DEPS_LIBRARY_DIRS}") +add_pch(pch/unitycore_pch.hh ${CORE_LIB_NAME}) install (TARGETS ${CORE_LIB_NAME} RUNTIME DESTINATION bin diff --git a/UnityCore/pch/unitycore_pch.hh b/UnityCore/pch/unitycore_pch.hh new file mode 100644 index 000000000..87cb9ecc4 --- /dev/null +++ b/UnityCore/pch/unitycore_pch.hh @@ -0,0 +1,33 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Jussi Pakkanen + */ + +/* + * These are the precompiled header includes for UnityCore. + * Only system header files can be listed here. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include diff --git a/cmake/isclang.cc b/cmake/isclang.cc new file mode 100644 index 000000000..35cbb3295 --- /dev/null +++ b/cmake/isclang.cc @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2012 Canonical, Ltd. + * + * Authors: + * Jussi Pakkanen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +int main(int argc, char **argv) { +#ifdef __clang__ + return 1; // This gets assigned to a CMake variable so "1" means "true". +#else + return 0; +#endif +} diff --git a/cmake/pch.cmake b/cmake/pch.cmake new file mode 100644 index 000000000..83e94255b --- /dev/null +++ b/cmake/pch.cmake @@ -0,0 +1,78 @@ +function(get_gcc_flags target_name) + # CMake does not provide an easy way to get all compiler switches, + # so this function is a fishing expedition to get them. + # http://public.kitware.com/Bug/view.php?id=1260 + set(compile_args ${CMAKE_CXX_FLAGS}) + string(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype_name) + if(CMAKE_CXX_FLAGS_${buildtype_name}) + list(APPEND compile_args ${CMAKE_CXX_FLAGS_${buildtype_name}}) + endif() + get_directory_property(dir_inc INCLUDE_DIRECTORIES) + foreach(item ${dir_inc}) + LIST(APPEND compile_args "-I" ${item}) + endforeach() + get_directory_property(dir_defs COMPILE_DEFINITIONS) + foreach(item ${dir_defs}) + list(APPEND compile_args -D${item}) + endforeach() + get_directory_property(buildtype_defs COMPILE_DEFINITIONS_${buildtype_name}) + foreach(item ${buildtype_defs}) + list(APPEND compile_args -D${item}) + endforeach() + get_target_property(target_type ${target_name} TYPE) + if(${target_type} STREQUAL SHARED_LIBRARY) + list(APPEND compile_args ${CMAKE_CXX_COMPILE_OPTIONS_PIC}) + endif() + set(compile_args ${compile_args} PARENT_SCOPE) + #message(STATUS ${compile_args}) +endfunction() + +function(add_pch_linux header_filename target_name pch_suffix) + set(gch_target_name "${target_name}_pch") + get_filename_component(header_basename ${header_filename} NAME) + set(gch_filename "${CMAKE_CURRENT_BINARY_DIR}/${header_basename}.${pch_suffix}") + get_gcc_flags(${target_name}) # Sets compile_args in this scope. It's even better than Intercal's COME FROM! + #message(STATUS ${compile_args}) + list(APPEND compile_args -c ${CMAKE_CURRENT_SOURCE_DIR}/${header_filename} -o ${gch_filename}) + separate_arguments(compile_args) + add_custom_command(OUTPUT ${gch_filename} + COMMAND ${CMAKE_CXX_COMPILER} ${compile_args} + DEPENDS ${header_filename}) + add_custom_target(${gch_target_name} DEPENDS ${gch_filename}) + add_dependencies(${target_name} ${gch_target_name}) + + # Add the PCH to every source file's include list. + # This is the only way that is supported by both GCC and Clang. + set_property(TARGET ${target_name} APPEND_STRING PROPERTY COMPILE_FLAGS "-include ${header_basename}") + + # Each directory should have only one precompiled header + # for simplicity. If there are several, the current dir + # gets added to the search path several times. + # It should not be an issue, though. + include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) +endfunction() + +try_run(IS_CLANG did_build ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/cmake/isclang.cc) + +if(UNIX) + if(NOT APPLE) + option(use_pch "Use precompiled headers." TRUE) + endif() +endif() + +if(use_pch) + message(STATUS "Using precompiled headers.") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Winvalid-pch") + if(IS_CLANG) + set(precompiled_header_extension pch) + else() + set(precompiled_header_extension gch) + endif() + macro(add_pch _header_filename _target_name) + add_pch_linux(${_header_filename} ${_target_name} ${precompiled_header_extension}) + endmacro() +else() + message(STATUS "Not using precompiled headers.") + macro(add_pch _header_filename _target_name) + endmacro() +endif()