diff --git a/reactos/cmake/gcc.cmake b/reactos/cmake/gcc.cmake index fff1911c578..27a3a730cf3 100644 --- a/reactos/cmake/gcc.cmake +++ b/reactos/cmake/gcc.cmake @@ -297,67 +297,36 @@ set(PSEH_LIB "pseh") # Macros if(PCH) - macro(_PCH_GET_COMPILE_FLAGS _target_name _out_compile_flags _header_filename) - # Add the precompiled header to the build - get_filename_component(_FILE ${_header_filename} NAME) - set(_gch_filename "${_FILE}.gch") - list(APPEND ${_out_compile_flags} -c ${_header_filename} -o ${_gch_filename}) - - # This gets us our includes - get_directory_property(DIRINC INCLUDE_DIRECTORIES) - foreach(item ${DIRINC}) - list(APPEND ${_out_compile_flags} -I${item}) - endforeach() - - # This our definitions - get_directory_property(_compiler_flags DEFINITIONS) - list(APPEND ${_out_compile_flags} ${_compiler_flags}) - - # This gets any specific definitions that were added with set-target-property - get_target_property(_target_defs ${_target_name} COMPILE_DEFINITIONS) - if(_target_defs) - foreach(item ${_target_defs}) - list(APPEND ${_out_compile_flags} -D${item}) - endforeach() - endif() + macro(add_pch _target _pch _sources) + # When including x.h GCC looks for x.h.gch first + set(_pch_final_name "${_target}_pch.h") + set(_gch ${CMAKE_CURRENT_BINARY_DIR}/${_pch_final_name}.gch) if(IS_CPP) - list(APPEND ${_out_compile_flags} ${CMAKE_CXX_FLAGS}) + set(_pch_language CXX) else() - list(APPEND ${_out_compile_flags} ${CMAKE_C_FLAGS}) + set(_pch_language C) endif() - separate_arguments(${_out_compile_flags}) - endmacro() + # Build the precompiled header + # HEADER_FILE_ONLY FALSE: force compiling the header + # EXTERNAL_SOURCE TRUE: don't use the .gch file when linking + set_source_files_properties(${_pch} PROPERTIES + HEADER_FILE_ONLY FALSE + LANGUAGE ${_pch_language} + EXTERNAL_SOURCE TRUE + OBJECT_LOCATION ${_gch}) - macro(add_pch _target_name _FILE) - set(_header_filename ${CMAKE_CURRENT_SOURCE_DIR}/${_FILE}) - get_filename_component(_basename ${_FILE} NAME) - set(_gch_filename ${_basename}.gch) - _PCH_GET_COMPILE_FLAGS(${_target_name} _args ${_header_filename}) - - if(IS_CPP) - set(__lang CXX) - set(__compiler ${CCACHE} ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}) - else() - set(__lang C) - set(__compiler ${CCACHE} ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}) + if(ENABLE_CCACHE) + set(_ccache_flag "-fpch-preprocess") endif() - add_custom_command(OUTPUT ${_gch_filename} - COMMAND ${__compiler} ${_args} - IMPLICIT_DEPENDS ${__lang} ${_header_filename} - DEPENDS ${_header_filename} ${ARGN}) - get_target_property(_src_files ${_target_name} SOURCES) - add_target_compile_flags(${_target_name} "-fpch-preprocess -Winvalid-pch -Wno-error=invalid-pch") - foreach(_item in ${_src_files}) - get_source_file_property(__src_lang ${_item} LANGUAGE) - if(__src_lang STREQUAL __lang) - set_source_files_properties(${_item} PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_gch_filename}) - endif() + # Include the gch in the specified source files, skipping the pch file itself + list(REMOVE_ITEM ${_sources} ${_pch}) + foreach(_src ${${_sources}}) + set_property(SOURCE ${_src} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_ccache_flag} -Winvalid-pch -Werror=invalid-pch -include ${_pch_final_name}") + set_property(SOURCE ${_src} APPEND PROPERTY OBJECT_DEPENDS ${_gch}) endforeach() - #set dependency checking : depends on precompiled header only which already depends on deeper header - set_target_properties(${_target_name} PROPERTIES IMPLICIT_DEPENDS_INCLUDE_TRANSFORM "\"${_basename}\"=;<${_basename}>=") endmacro() else() macro(add_pch _target_name _FILE) diff --git a/reactos/cmake/msvc.cmake b/reactos/cmake/msvc.cmake index 9374f93f242..b157c8561e6 100644 --- a/reactos/cmake/msvc.cmake +++ b/reactos/cmake/msvc.cmake @@ -54,7 +54,8 @@ add_compile_flags("/wd4290") # - TODO: C4133: incompatible types # - C4229: modifiers on data are ignored # - C4700: uninitialized variable usage -add_compile_flags("/we4013 /we4022 /we4047 /we4098 /we4113 /we4129 /we4229 /we4700") +# - C4603: macro is not defined or definition is different after precompiled header use +add_compile_flags("/we4013 /we4022 /we4047 /we4098 /we4113 /we4129 /we4229 /we4700 /we4603") # Enable warnings above the default level, but don't treat them as errors: # - C4115: named type definition in parentheses @@ -118,8 +119,47 @@ set(CMAKE_RC_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY}) set(CMAKE_ASM_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY}) set(CMAKE_ASM_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY}) -macro(add_pch _target_name _FILE) -endmacro() +if(PCH) + macro(add_pch _target _pch _sources) + set(_gch ${CMAKE_CURRENT_BINARY_DIR}/${_target}.pch) + + if(IS_CPP) + set(_pch_language CXX) + set(_cl_lang_flag "/TP") + else() + set(_pch_language C) + set(_cl_lang_flag "/TC") + endif() + + if(MSVC_IDE) + set(_pch_path_name_flag "/Fp${_gch}") + endif() + + # Build the precompiled header + # HEADER_FILE_ONLY FALSE: force compiling the header + set_source_files_properties(${_pch} PROPERTIES + HEADER_FILE_ONLY FALSE + LANGUAGE ${_pch_language} + COMPILE_FLAGS "${_cl_lang_flag} /Yc /Fp${_gch}" + OBJECT_OUTPUTS ${_gch}) + + # Prevent a race condition related to writing to the PDB files between the PCH and the excluded list of source files + get_target_property(_target_sources ${_target} SOURCES) + list(REMOVE_ITEM _target_sources ${_pch}) + foreach(_target_src ${_target_sources}) + set_property(SOURCE ${_target_src} APPEND PROPERTY OBJECT_DEPENDS ${_gch}) + endforeach() + + # Use the precompiled header with the specified source files, skipping the pch itself + list(REMOVE_ITEM ${_sources} ${_pch}) + foreach(_src ${${_sources}}) + set_property(SOURCE ${_src} APPEND_STRING PROPERTY COMPILE_FLAGS " /FI${_gch} /Yu${_gch} ${_pch_path_name_flag}") + endforeach() + endmacro() +else() + macro(add_pch _target_name _FILE) + endmacro() +endif() function(set_entrypoint _module _entrypoint) if(${_entrypoint} STREQUAL "0")