[CMake] Precompiled headers
Anders Backman
andersb at cs.umu.se
Tue May 6 15:11:53 EDT 2008
Hi and thanks for the tip...
However, when I try this (Im using VS2008, CMake 2.4-patch 8) I get
some problems.
I have nailed this down to the following command:
#usual add_executable etc... works just fine!
add_executable(rendering file1.cpp ...)
.
.
.
get_target_property(OBJECT_FILES rendering SOURCES)
message("Msg: ${OBJECT_FILES}")
Output is:
Msg: NOTFOUND
Now I have tried quite a few various properties, and it seems to not
give me much output what so ever...
There are a few properties that actually works:
DEBUG_LOCATION
TYPE
That is, the one documented at: http://www.cmake.org/HTML/CMake-2.4.html
So, what version of cmake are you using?
Or are the SOURCES property a platform dependent property?
/Anders
On Tue, May 6, 2008 at 4:06 PM, Rodolfo Lima <rodolfo at rodsoft.org> wrote:
> Anders Backman escreveu:
>
>
>
> > So is there are portable way of handling this in cmake?
> >
>
> I've been using the attached script and it has been working nicely for my
> needs.
>
> The usage is:
>
>
> include(PCHSupport)
> add_executable(test test.cpp pch.h)
> ADD_PRECOMPILED_HEADER(test pch.h)
>
> I'm using it with gcc, but it should work with MS Visual Studio too.
>
> Regards,
> rod
>
> # - Try to find precompiled headers support for GCC 3.4 and 4.x
> # Once done this will define:
> #
> # Variable:
> # PCHSupport_FOUND
> #
> # Macro:
> # ADD_PRECOMPILED_HEADER _targetName _input _dowarn
>
> set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
>
> IF(CMAKE_COMPILER_IS_GNUCXX)
> # Verifies if GCC supports precompiled header
> # Its version should be >= 3.4.0
> EXEC_PROGRAM(
> ${CMAKE_CXX_COMPILER}
> ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
> OUTPUT_VARIABLE gcc_compiler_version)
> #MESSAGE("GCC Version: ${gcc_compiler_version}")
> IF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]")
> SET(PCHSupport_FOUND TRUE)
> ELSE()
> IF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]")
> SET(PCHSupport_FOUND TRUE)
> ENDIF()
> ENDIF()
>
> SET(_PCH_include_prefix -I)
> ELSE()
> IF(WIN32)
> SET(PCHSupport_FOUND TRUE) # for experimental msvc support
> SET(_PCH_include_prefix /I)
> ELSE()
> SET(PCHSupport_FOUND FALSE)
> ENDIF()
> ENDIF()
>
>
> MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags)
> SET(${_out_compile_flags} ${CMAKE_CXX_FLAGS} )
>
> STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name)
> if(${_flags_var_name})
> list(APPEND ${_out_compile_flags} ${${_flags_var_name}} )
> endif(${_flags_var_name})
>
> # If the compiler is g++ and the target type is shared library, we have
> # to add -fPIC to its compile flags.
> IF(CMAKE_COMPILER_IS_GNUCXX)
> GET_TARGET_PROPERTY(_targetType ${_PCH_current_target} TYPE)
> IF(${_targetType} STREQUAL SHARED_LIBRARY)
> LIST(APPEND ${_out_compile_flags} -fPIC)
> ENDIF()
> ELSE(MSVC)
> LIST(APPEND ${_out_compile_flags}
> /Fd${CMAKE_CURRENT_BINARY_DIR}/${_PCH_current_target}.pdb)
> ENDIF()
>
> # Add all include directives...
> GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES )
> FOREACH(item ${DIRINC})
> LIST(APPEND ${_out_compile_flags} ${_PCH_include_prefix}${item})
> ENDFOREACH(item)
>
> # Add all definitions...
> GET_TARGET_PROPERTY(_compiler_flags ${_PCH_current_target}
> COMPILE_FLAGS)
> if(_compiler_flags)
> LIST(APPEND ${_out_compile_flags} ${_compiler_flags})
> endif()
>
> GET_DIRECTORY_PROPERTY(_directory_flags COMPILE_DEFINITIONS)
> if(_directory_flags)
> foreach(flag ${_directory_flags})
> LIST(APPEND ${_out_compile_flags} -D${flag})
> endforeach(flag)
> endif(_directory_flags)
>
> STRING(TOUPPER "COMPILE_DEFINITIONS_${CMAKE_BUILD_TYPE}"
> _defs_prop_name)
> GET_DIRECTORY_PROPERTY(_directory_flags ${_defs_prop_name})
> if(_directory_flags)
> foreach(flag ${_directory_flags})
> LIST(APPEND ${_out_compile_flags} -D${flag})
> endforeach(flag)
> endif(_directory_flags)
>
> get_target_property(_target_flags ${_PCH_current_target}
> COMPILE_DEFINITIONS)
> if(_target_flags)
> foreach(flag ${_target_flags})
> LIST(APPEND ${_out_compile_flags} -D${flag})
> endforeach(flag)
> endif(_target_flags)
>
> get_target_property(_target_flags ${_PCH_current_target}
> ${_defs_prop_name})
> if(_target_flags)
> foreach(flag ${_target_flags})
> LIST(APPEND ${_out_compile_flags} -D${flag})
> endforeach(flag)
> endif(_target_flags)
>
> SEPARATE_ARGUMENTS(${_out_compile_flags})
> ENDMACRO(_PCH_GET_COMPILE_FLAGS)
>
>
> MACRO(_PCH_GET_COMPILE_COMMAND out_command _input _output)
> FILE(TO_NATIVE_PATH ${_input} _native_input)
> FILE(TO_NATIVE_PATH ${_output} _native_output)
>
> IF(CMAKE_COMPILER_IS_GNUCXX)
> IF(CMAKE_CXX_COMPILER_ARG1)
> # remove leading space in compiler argument
> STRING(REGEX REPLACE "^ +" "" pchsupport_compiler_cxx_arg1
> ${CMAKE_CXX_COMPILER_ARG1})
> ELSE()
> SET(pchsupport_compiler_cxx_arg1 "")
> ENDIF()
> SET(${out_command}
> ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1}
> ${_compile_FLAGS} -x c++-header -o ${_output} ${_input})
> ELSE()
> set(_tempdir
> ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_PCH_current_target}.dir)
> GET_FILENAME_COMPONENT(_namewe ${_input} NAME_WE)
> SET(_pchsource ${_tempdir}/${_namewe}.cpp)
> FILE(TO_NATIVE_PATH ${_pchsource} _native_pchsource)
>
> SET(_dummy_str "#include \"${_input}\"")
> FILE(WRITE ${_pchsource} ${_dummy_str})
>
> SET(${out_command}
> ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} /c
> /Fp${_native_output} /Yc${_native_input} /Fo${_tempdir}/
> ${_native_pchsource} /nologo)
> ENDIF()
> ENDMACRO(_PCH_GET_COMPILE_COMMAND )
>
> MACRO(_PCH_GET_TARGET_COMPILE_FLAGS _cflags _header_name _pch_path _dowarn
> )
> FILE(TO_NATIVE_PATH ${_pch_path} _native_pch_path)
> #message(${_native_pch_path})
>
> IF(CMAKE_COMPILER_IS_GNUCXX)
> # for use with distcc and gcc>4.0.1 if preprocessed files are
> accessible
> # on all remote machines set
> # PCH_ADDITIONAL_COMPILER_FLAGS to -fpch-preprocess
> # if you want warnings for invalid header files (which is very
> # inconvenient if you have different versions of the headers for
> # different build types you may set _pch_dowarn
> LIST(APPEND ${_cflags} ${PCH_ADDITIONAL_COMPILER_FLAGS})
> IF (_dowarn)
> LIST(APPEND ${_cflags} -Winvalid-pch)
> ENDIF ()
> ELSE()
> set(${_cflags} "/Fp${_native_pch_path}" "/Yu${_header_name}" )
> ENDIF()
>
> get_target_property(_old_target_cflags ${_PCH_current_target}
> COMPILE_FLAGS)
> if(_old_target_cflags)
> list(APPEND ${_cflags} ${_old_target_cflags})
> endif()
>
> STRING(REPLACE ";" " " ${_cflags} "${${_cflags}}")
> ENDMACRO(_PCH_GET_TARGET_COMPILE_FLAGS )
>
> MACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input _output)
> GET_FILENAME_COMPONENT(_name ${_input} NAME)
> if(CMAKE_COMPILER_IS_GNUCXX)
> set(_build "")
> IF(CMAKE_BUILD_TYPE)
> set(_build _${CMAKE_BUILD_TYPE})
> endif()
> file(MAKE_DIRECTORY
> ${CMAKE_CURRENT_BINARY_DIR}/${_name}.gch)
> SET(_output
> "${CMAKE_CURRENT_BINARY_DIR}/${_name}.gch/${_targetName}${_build}.h++")
> else()
> SET(_output
> "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${_name}.pch")
> endif()
> ENDMACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input)
>
> MACRO(ADD_PRECOMPILED_HEADER _targetName _input)
> SET(_PCH_current_target ${_targetName})
>
> if(${ARGN})
> set(_dowarn 1)
> else()
> set(_dowarn 0)
> endif()
>
> GET_FILENAME_COMPONENT(_name ${_input} NAME)
> GET_FILENAME_COMPONENT(_path ${_input} PATH)
> GET_PRECOMPILED_HEADER_OUTPUT( ${_targetName} ${_input} _output)
> GET_FILENAME_COMPONENT(_outdir ${_output} PATH )
>
> FILE(MAKE_DIRECTORY ${_outdir})
>
> _PCH_GET_COMPILE_FLAGS(_compile_FLAGS)
>
> # Ensure same directory! Required by gcc
> IF(NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
> SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${_name}
> PROPERTIES GENERATED 1)
> ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}
> COMMAND ${CMAKE_COMMAND} -E copy
> ${CMAKE_CURRENT_SOURCE_DIR}/${_input} ${CMAKE_CURRENT_BINARY_DIR}/${_name}
> DEPENDS ${_input})
> ENDIF()
>
> #message("_command ${_input} ${_output}")
> _PCH_GET_COMPILE_COMMAND(_command ${CMAKE_CURRENT_BINARY_DIR}/${_name}
> ${_output} )
>
> ADD_CUSTOM_COMMAND(OUTPUT ${_output}
> COMMAND ${_command}
> IMPLICIT_DEPENDS CXX
> ${CMAKE_CURRENT_BINARY_DIR}/${_name})
>
> GET_TARGET_PROPERTY(_sources ${_targetName} SOURCES)
> FOREACH(_src ${_sources})
> SET_SOURCE_FILES_PROPERTIES(${_src} PROPERTIES OBJECT_DEPENDS
> ${_output})
> ENDFOREACH()
> endif()
>
> _PCH_GET_TARGET_COMPILE_FLAGS(_target_cflags ${_name} ${_output}
> ${_dowarn})
>
> if(_target_c_flags)
> SET_TARGET_PROPERTIES(${_targetName}
> PROPERTIES
> COMPILE_FLAGS
> ${_target_cflags} )
> endif(_target_c_flags)
> ENDMACRO(ADD_PRECOMPILED_HEADER)
>
> _______________________________________________
> CMake mailing list
> CMake at cmake.org
> http://www.cmake.org/mailman/listinfo/cmake
>
--
________________________________________________________________
Anders Backman Email: andersb at cs.umu.se
HPC2N/VRlab Phone: +46 (0)90-786 9936
Umea university Cellular: +46 (0)70-392 64 67
S-901 87 UMEA SWEDEN Fax: +46 90-786 6126
http://www.cs.umu.se/~andersb
More information about the CMake
mailing list