Am Mittwoch, den 20.12.2006, 17:53 +0100 schrieb frederic heem: > Hi, > Is there a nice way to find out if a target is using -fPIC ? > Indeed, this information is needed for generating compiled header. > At the moment, a kludge is to use the following code: > > #If the target is a shared library, add -fPIC to compile > GET_TARGET_PROPERTY(_targetType ${_targetName} TYPE) > IF(${_targetType} STREQUAL SHARED_LIBRARY) > SET(_compile_FLAGS "${_compile_FLAGS} -fPIC") > ENDIF(${_targetType} STREQUAL SHARED_LIBRARY) > > This works but is not a proper solution, one shall not know in which > case -fPIC is used or not. > Thanks, > Frederic Heem
I ran into this problem and your solutions works like a charm. I also worked on msvc support(see attached file), but it only work if CMAKE_BUILD_TYPE equals "Release", since /Fd wants to add debugging informations and fails due to inconsitent pdb files. If someone know's more about this issue, please give me a hint. merry Christmas, Maik
# - 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 IF(CMAKE_COMPILER_IS_GNUCXX) EXEC_PROGRAM( ${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _compiler_output) STRING(REGEX REPLACE ".* ([0-9]\\.[0-9]\\.[0-9]) .*" "\\1" gcc_compiler_version ${_compiler_output}) #MESSAGE("GCC Version: ${gcc_compiler_version}") IF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") SET(PCHSupport_FOUND TRUE) ELSE(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") IF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") SET(PCHSupport_FOUND TRUE) ENDIF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") ENDIF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") SET(_PCH_include_prefix "-I") ELSE(CMAKE_COMPILER_IS_GNUCXX) SET(PCHSupport_FOUND TRUE) # for experimental msvc support SET(_PCH_include_prefix "/I") ENDIF(CMAKE_COMPILER_IS_GNUCXX) MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags) STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name) SET(_compile_FLAGS ${${_flags_var_name}} ) IF(CMAKE_COMPILER_IS_GNUCXX) GET_TARGET_PROPERTY(_targetType ${_PCH_current_target} TYPE) IF(${_targetType} STREQUAL SHARED_LIBRARY) LIST(APPEND _compile_FLAGS "${_compile_FLAGS} -fPIC") ENDIF(${_targetType} STREQUAL SHARED_LIBRARY) ELSE(CMAKE_COMPILER_IS_GNUCXX) ## TODO ... ? or does it work out of the box ENDIF(CMAKE_COMPILER_IS_GNUCXX) FOREACH(item ${_directory_flags}) LIST(APPEND _compile_FLAGS "${_PCH_include_prefix}${item}") ENDFOREACH(item) GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) LIST(APPEND _compile_FLAGS ${_directory_flags}) LIST(APPEND _compile_FLAGS ${CMAKE_CXX_FLAGS} ) SEPARATE_ARGUMENTS(_compile_FLAGS) ENDMACRO(_PCH_GET_COMPILE_FLAGS) MACRO(_PCH_TEST_PATH _path ) GET_DIRECTORY_PROPERTY(_directory_flags INCLUDE_DIRECTORIES) SET(_CMAKE_CURRENT_BINARY_DIR_included_before_path FALSE) FOREACH(item ${_directory_flags}) IF(${item} STREQUAL ${_path} AND NOT _CMAKE_CURRENT_BINARY_DIR_included_before_path ) MESSAGE(FATAL_ERROR "This is the ADD_PRECOMPILED_HEADER macro. " "CMAKE_CURREN_BINARY_DIR has to mentioned at INCLUDE_DIRECTORIES's argument list before :${_path}:, where ${_name} is located" ) ENDIF(${item} STREQUAL ${_path} AND NOT _CMAKE_CURRENT_BINARY_DIR_included_before_path ) IF(${item} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) SET(_CMAKE_CURRENT_BINARY_DIR_included_before_path TRUE) ENDIF(${item} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) ENDFOREACH(item) ENDMACRO(_PCH_TEST_PATH) 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) SET(${out_command} ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input} ) ELSE(CMAKE_COMPILER_IS_GNUCXX) SET(_dummy_str "#include <${_input}>") FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pch_dummy.cpp ${_dummy_str}) SET(${out_command} ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} /c /Fp${_native_output} /Yc${_native_input} pch_dummy.cpp ) #/out:${_output} ENDIF(CMAKE_COMPILER_IS_GNUCXX) ENDMACRO(_PCH_GET_COMPILE_COMMAND ) MACRO(_PCH_GET_TARGET_COMPILE_FLAGS _cflags _header_name _pch_path ) FILE(TO_NATIVE_PATH ${_pch_path} _native_pch_path) message(${_native_pch_path}) IF(CMAKE_COMPILER_IS_GNUCXX) set(${_cflags} "-include ${_header_name} -Winvalid-pch" ) ELSE(CMAKE_COMPILER_IS_GNUCXX) set(${_cflags} "/Fp${_native_pch_path} /Yu${_header_name}" ) ENDIF(CMAKE_COMPILER_IS_GNUCXX) ENDMACRO(_PCH_GET_TARGET_COMPILE_FLAGS ) MACRO(ADD_PRECOMPILED_HEADER _targetName _input ) SET(_PCH_current_target ${_targetName}) IF(NOT CMAKE_BUILD_TYPE) MESSAGE(FATAL_ERROR "This is the ADD_PRECOMPILED_HEADER macro. " "You must set CMAKE_BUILD_TYPE!" ) ENDIF(NOT CMAKE_BUILD_TYPE) GET_FILENAME_COMPONENT(_name ${_input} NAME) GET_FILENAME_COMPONENT(_path ${_input} PATH) SET(_outdir "${CMAKE_CURRENT_BINARY_DIR}/${_name}.gch") SET(_output "${_outdir}/${CMAKE_BUILD_TYPE}.c++") ADD_CUSTOM_COMMAND( OUTPUT ${_outdir} COMMAND mkdir ${_outdir} # TODO: {CMAKE_COMMAND} -E ... !doesn't work in win32 ) _PCH_TEST_PATH(_path) _PCH_GET_COMPILE_FLAGS(_compile_FLAGS) #MESSAGE("_compiler_FLAGS: ${_compiler_FLAGS}") message(${_compile_FLAGS} ) #message("COMMAND ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input}") ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name} COMMAND ${CMAKE_COMMAND} -E copy ${_input} ${CMAKE_CURRENT_BINARY_DIR}/${_name} # ensure same directory! Required by gcc ) #message("_command ${_input} ${_output}") _PCH_GET_COMPILE_COMMAND(_command ${_input} ${_output} ) #message(${_input} ) message("${_command}") ADD_CUSTOM_COMMAND( OUTPUT ${_output} COMMAND ${_command} DEPENDS ${_input} ${_outdir} ${CMAKE_CURRENT_BINARY_DIR}/${_name} ) ADD_CUSTOM_TARGET(${_targetName}_gch DEPENDS ${_output} ) ADD_DEPENDENCIES(${_targetName} ${_targetName}_gch ) _PCH_GET_TARGET_COMPILE_FLAGS(_target_cflags ${_name} ${_output}) #message("${_target_cflags}") SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS ${_target_cflags} ) ENDMACRO(ADD_PRECOMPILED_HEADER)
_______________________________________________ CMake mailing list CMake@cmake.org http://www.cmake.org/mailman/listinfo/cmake