include (CheckCXXSourceRuns) # ================================================================================ # == Macros, mostly for special targets ========================================== MACRO(COPY_IF_DIFFERENT FROM_DIR TO_DIR FILES TARGETS TAGS) # Macro to implement copy_if_different for a list of files # Arguments - # FROM_DIR - this is the source directory # TO_DIR - this is the destination directory # FILES - names of the files to copy # TODO: add globing. # TARGETS - List of targets # TAGS - Since only the file name is used # to generate rules, pre-pend a user # supplied tag to prevent duplicate rule errors. SET(AddTargets) FOREACH(SRC ${FILES}) GET_FILENAME_COMPONENT(SRCFILE ${SRC} NAME) # Command to copy the files to ${STEP1}/src, if changed. SET(TARGET "${TAGS}/${SRCFILE}") IF("${FROM_DIR}" STREQUAL "") SET(FROM ${SRC}) ELSE("${FROM_DIR}" STREQUAL "") SET(FROM ${FROM_DIR}/${SRC}) ENDIF("${FROM_DIR}" STREQUAL "") IF("${TO_DIR}" STREQUAL "") SET(TO ${SRCFILE}) ELSE("${TO_DIR}" STREQUAL "") SET(TO ${TO_DIR}/${SRCFILE}) ENDIF("${TO_DIR}" STREQUAL "") ADD_CUSTOM_COMMAND( OUTPUT ${TARGET} COMMAND "${CMAKE_COMMAND}" ARGS -E copy_if_different "${FROM}" "${TO}" COMMENT "Copying ${SRCFILE} ${TO_DIR}" ) list(APPEND AddTargets ${TARGET}) ENDFOREACH(SRC ${FILES}) SET(${TARGETS} ${AddTargets}) ENDMACRO(COPY_IF_DIFFERENT FROM_DIR TO_DIR FILES TARGETS TAGS) MACRO (fc_copy_sources target_name outpath) if(BUILD_VERBOSE_GENERATION) set(fc_details " (fc_copy_sources called from ${CMAKE_CURRENT_SOURCE_DIR})") else() set(fc_details "") endif() foreach(it ${ARGN}) get_filename_component(infile ${it} ABSOLUTE) get_filename_component(outfile "${outpath}/${it}" ABSOLUTE) add_file_dependencies("${infile}" "${outfile}") ADD_CUSTOM_COMMAND( SOURCE "${infile}" COMMAND "${CMAKE_COMMAND}" -E copy "${infile}" "${outfile}" TARGET ${target_name} OUTPUTS "${outfile}" COMMENT "Copying ${infile} to ${outfile}${fc_details}" ) endforeach(it) ADD_CUSTOM_COMMAND( SOURCE ${target_name} TARGET ${target_name} DEPENDS ${ARGN} ) ENDMACRO(fc_copy_sources) MACRO (fc_target_copy_resource target_name inpath outpath) if(BUILD_VERBOSE_GENERATION) set(fc_details " (fc_target_copy_resource called from ${CMAKE_CURRENT_SOURCE_DIR})") else() set(fc_details "") endif() foreach(it ${ARGN}) get_filename_component(infile "${inpath}/${it}" ABSOLUTE) get_filename_component(outfile "${outpath}/${it}" ABSOLUTE) add_file_dependencies("${infile}" "${outfile}") ADD_CUSTOM_COMMAND( SOURCE "${infile}" COMMAND "${CMAKE_COMMAND}" -E copy "${infile}" "${outfile}" TARGET ${target_name} OUTPUTS "${outfile}" COMMENT "Copying ${infile} to ${outfile}${fc_details}" ) endforeach(it) ADD_CUSTOM_COMMAND( SOURCE ${target_name} TARGET ${target_name} DEPENDS ${ARGN} ) ENDMACRO(fc_target_copy_resource) macro(copy_to_local_output_paths SOURCE_PATHS) if(CMAKE_CFG_INTDIR STREQUAL .) # No Debug/Release output paths set(DEBUG_LOCAL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) set(RELEASE_LOCAL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) else(CMAKE_CFG_INTDIR STREQUAL .) #set(DEBUG_LOCAL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/Debug) #set(RELEASE_LOCAL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/Release) set(DEBUG_LOCAL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) set(RELEASE_LOCAL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) endif(CMAKE_CFG_INTDIR STREQUAL .) file(TO_NATIVE_PATH ${SOURCE_PATHS} NATIVE_SOURCE) file(TO_NATIVE_PATH ${DEBUG_LOCAL_OUTPUT_PATH}/ NATIVE_DEBUG_DESTINATION) file(TO_NATIVE_PATH ${RELEASE_LOCAL_OUTPUT_PATH}/ NATIVE_RELEASE_DESTINATION) message(STATUS "${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEBUG_DESTINATION}") execute_process( COMMAND ${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEBUG_DESTINATION} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) if(NOT ${DEBUG_LOCAL_OUTPUT_PATH} STREQUAL ${RELEASE_LOCAL_OUTPUT_PATH}) message(STATUS "${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_RELEASE_DESTINATION}") execute_process( COMMAND ${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_RELEASE_DESTINATION} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif(NOT ${DEBUG_LOCAL_OUTPUT_PATH} STREQUAL ${RELEASE_LOCAL_OUTPUT_PATH}) endmacro(copy_to_local_output_paths) macro(copy_to_main_output_paths SOURCE_PATHS) file(TO_NATIVE_PATH ${SOURCE_PATHS} NATIVE_SOURCE) file(TO_NATIVE_PATH ${DEBUG_MAIN_OUTPUT_PATH}/ NATIVE_DEBUG_DESTINATION) file(TO_NATIVE_PATH ${RELEASE_MAIN_OUTPUT_PATH}/ NATIVE_RELEASE_DESTINATION) message(STATUS "${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEBUG_DESTINATION}") execute_process( COMMAND ${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_DEBUG_DESTINATION} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) if(NOT ${DEBUG_MAIN_OUTPUT_PATH} STREQUAL ${RELEASE_MAIN_OUTPUT_PATH}) message(STATUS "${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_RELEASE_DESTINATION}") execute_process( COMMAND ${PLATFORM_CP} ${NATIVE_SOURCE} ${NATIVE_RELEASE_DESTINATION} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif(NOT ${DEBUG_MAIN_OUTPUT_PATH} STREQUAL ${RELEASE_MAIN_OUTPUT_PATH}) endmacro(copy_to_main_output_paths) # It would be a bit cleaner to generate these files in ${CMAKE_CURRENT_BINARY_DIR} macro(generate_from_xml BASE_NAME) set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/generate.py") file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH) file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.xml" SOURCE_NATIVE_PATH) set(SOURCE_CPP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.cpp" ) # BASE_NAME may include also a path name GET_FILENAME_COMPONENT(OUTPUT_PATH "${SOURCE_CPP_PATH}" PATH) file(TO_NATIVE_PATH "${OUTPUT_PATH}" OUTPUT_NATIVE_PATH) if(NOT EXISTS "${SOURCE_CPP_PATH}") # assures the source files are generated at least once execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) endif() add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.h" "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.cpp" COMMAND ${PYTHON_EXECUTABLE} "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" ${BASE_NAME}.xml MAIN_DEPENDENCY "${SOURCE_PATH}" DEPENDS "${CMAKE_SOURCE_DIR}/src/Tools/generateTemplates/templateClassPyExport.py" "${TOOL_PATH}" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Building ${BASE_NAME}.h/.cpp out of ${BASE_NAME}.xml" ) endmacro(generate_from_xml) macro(generate_from_py BASE_NAME OUTPUT_FILE) set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/PythonToCPP.py") file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH) file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.py" SOURCE_NATIVE_PATH) add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILE}" COMMAND "${PYTHON_EXECUTABLE}" "${TOOL_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}" "${OUTPUT_FILE}" MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.py" DEPENDS "${TOOL_PATH}" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMENT "Building files out of ${BASE_NAME}.py") endmacro(generate_from_py) # generates the ui -> cpp h files #macro(qt4_wrap_ui infiles ) # #endmacro(qt4_wrap_ui) MACRO(ADD_MSVC_PRECOMPILED_HEADER TargetName PrecompiledHeader PrecompiledSource SourcesVar) IF(MSVC) GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE) IF(MSVC_IDE) SET(PrecompiledBinary "$(IntDir)\\$(TargetName).pch") ELSE(MSVC_IDE) SET(PrecompiledBinary ${CMAKE_CURRENT_BINARY_DIR}/${TargetName}.pch) ENDIF(MSVC_IDE) SET(Sources ${${SourcesVar}}) SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\"" OBJECT_OUTPUTS "${PrecompiledBinary}") SET_SOURCE_FILES_PROPERTIES(${Sources} PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\"" OBJECT_DEPENDS "${PrecompiledBinary}") # Add precompiled header to SourcesVar LIST(APPEND ${SourcesVar} ${PrecompiledSource}) ENDIF(MSVC) ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER) MACRO(GET_MSVC_PRECOMPILED_SOURCE PrecompiledSource SourcesVar) IF(MSVC) FOREACH (it ${ARGN}) GET_FILENAME_COMPONENT(file_ext ${it} EXT) GET_FILENAME_COMPONENT(file_name ${it} NAME) STRING(COMPARE EQUAL ${it} ${PrecompiledSource} pch) IF (NOT pch) # get c++ source files STRING(REGEX MATCH "^(.cpp|.cc|.cxx)$" cpp_file ${file_ext}) # ignore any generated source files from Qt STRING(REGEX MATCH "^(moc_|qrc_|ui_)" gen_file ${file_name}) IF(cpp_file AND NOT gen_file) LIST(APPEND ${SourcesVar} ${it}) ENDIF(cpp_file AND NOT gen_file) ENDIF(NOT pch) ENDFOREACH (it) ENDIF(MSVC) ENDMACRO(GET_MSVC_PRECOMPILED_SOURCE) # Macro to replace all the binary output locations. Takes 2 optional parameters. # ${ARGVN} is zero based so the 3rd element is ${ARGV2}. When the 3rd element is missing, # Runtime and Lib directories default to /bin and /lib. When present, the 3rd element # specifies both Runtime and Lib directories. 4th specifies linux install path. MACRO(SET_BIN_DIR ProjectName OutputName) set_target_properties(${ProjectName} PROPERTIES OUTPUT_NAME ${OutputName}) if(${ARGC} GREATER 2) # VS_IDE (and perhaps others) make Release and Debug subfolders. This removes them. set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}${ARGV2}) set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}${ARGV2}) set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}${ARGV2}) set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}${ARGV2}) set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}${ARGV2}) set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}${ARGV2}) else(${ARGC} GREATER 2) set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin) set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin) set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib) set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib) endif(${ARGC} GREATER 2) if(WIN32) set_target_properties(${ProjectName} PROPERTIES DEBUG_OUTPUT_NAME ${OutputName}_d) else(WIN32) # FreeCADBase, SMDS, Driver, MEFISTO2 and area-native libs don't depend on parts from CMAKE_INSTALL_LIBDIR if(NOT ${ProjectName} MATCHES "^(FreeCADBase|SMDS|Driver|MEFISTO2|area-native)$") if(${ARGC} STREQUAL 4) set_property(TARGET ${ProjectName} APPEND PROPERTY INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}${ARGV3}) else(${ARGC} STREQUAL 4) set_property(TARGET ${ProjectName} APPEND PROPERTY INSTALL_RPATH ${CMAKE_INSTALL_LIBDIR}) endif() endif() endif(WIN32) ENDMACRO(SET_BIN_DIR) # Set python prefix & suffix together MACRO(SET_PYTHON_PREFIX_SUFFIX ProjectName) if(NOT MSVC) set_target_properties(${ProjectName} PROPERTIES PREFIX "") endif(NOT MSVC) if(WIN32) set_target_properties(${ProjectName} PROPERTIES SUFFIX ".pyd") # 0000661: cmake build on Mac OS: dealing with dylib versus so elseif(APPLE) set_target_properties(${ProjectName} PROPERTIES SUFFIX ".so") endif(WIN32) ENDMACRO(SET_PYTHON_PREFIX_SUFFIX)