| function(PARSE_INSTALL_LISTS) |
| # ~~~ |
| # PARSE_INSTALL_LISTS |
| # |
| # Parses lists of architectures and devices to be installed as given by a |
| # user. Converts them to CMake lists and sets them in the global scope. |
| # |
| # There are INSTALL_* and NO_INSTALL_* global variables. Each of them holds |
| # a comma-separated list of entities to install and not to install. |
| # |
| # When none of these two is set then all entities are considered for installation |
| # If INSTALL_* is set then only entities present there are to be installed. |
| # The NO_INSTALL_* list contains entities that should NOT be installed. |
| # |
| # For example: If one wants to install only the Xilinx 7-series familly one |
| # would run the CMake with -DINSTALL_FAMILIES=xc7. If one wants to install |
| # all supported families BUT Xilinx 7-series one would do -DNO_INSTALL_FAMILIES=xc7 |
| # The same principle applies to the architecture and the device lists. |
| |
| # Device lists |
| if (NOT "${INSTALL_DEVICES}" STREQUAL "") |
| string(REPLACE "," ";" DEVICE_INSTALL_LIST ${INSTALL_DEVICES}) |
| else () |
| set(DEVICE_INSTALL_LIST "") |
| endif () |
| set(SYMBIFLOW_DEVICE_INSTALL_LIST ${DEVICE_INSTALL_LIST} CACHE INTERNAL "List of devices to install" FORCE) |
| |
| if (NOT "${NO_INSTALL_DEVICES}" STREQUAL "") |
| string(REPLACE "," ";" DEVICE_NO_INSTALL_LIST ${NO_INSTALL_DEVICES}) |
| else () |
| set(DEVICE_NO_INSTALL_LIST "") |
| endif () |
| set(SYMBIFLOW_DEVICE_NO_INSTALL_LIST ${DEVICE_NO_INSTALL_LIST} CACHE INTERNAL "List of devices not to install" FORCE) |
| |
| # Architecture lists |
| if (NOT "${INSTALL_ARCHS}" STREQUAL "") |
| string(REPLACE "," ";" ARCH_INSTALL_LIST ${INSTALL_ARCHS}) |
| else () |
| set(ARCH_INSTALL_LIST "") |
| endif () |
| set(SYMBIFLOW_ARCH_INSTALL_LIST ${ARCH_INSTALL_LIST} CACHE INTERNAL "List of architectures to install" FORCE) |
| |
| if (NOT "${NO_INSTALL_ARCHS}" STREQUAL "") |
| string(REPLACE "," ";" ARCH_NO_INSTALL_LIST ${NO_INSTALL_ARCHS}) |
| else () |
| set(ARCH_NO_INSTALL_LIST "") |
| endif () |
| set(SYMBIFLOW_ARCH_NO_INSTALL_LIST ${ARCH_NO_INSTALL_LIST} CACHE INTERNAL "List of acritectures not to install" FORCE) |
| |
| # Family lists |
| if (NOT "${INSTALL_FAMILIES}" STREQUAL "") |
| string(REPLACE "," ";" FAMILY_INSTALL_LIST ${INSTALL_FAMILIES}) |
| else () |
| set(FAMILY_INSTALL_LIST "") |
| endif () |
| set(SYMBIFLOW_FAMILY_INSTALL_LIST ${FAMILY_INSTALL_LIST} CACHE INTERNAL "List of device families to install" FORCE) |
| |
| if (NOT "${NO_INSTALL_FAMILIES}" STREQUAL "") |
| string(REPLACE "," ";" FAMILY_NO_INSTALL_LIST ${NO_INSTALL_FAMILIES}) |
| else () |
| set(FAMILY_NO_INSTALL_LIST "") |
| endif () |
| set(SYMBIFLOW_FAMILY_NO_INSTALL_LIST ${FAMILY_NO_INSTALL_LIST} CACHE INTERNAL "List of families not to install" FORCE) |
| |
| endfunction() |
| |
| |
| function(CHECK_INSTALL_LIST) |
| # ~~~ |
| # CHECK_INSTALL_LIST |
| # <entity> |
| # <variable> |
| # <install list> |
| # <no-install list> |
| # |
| # Checks if the given device is to be installed by examining it through |
| # installation lists. Sets the given variable to TRUE or FALSE |
| # ~~~ |
| |
| set(options) |
| set(oneValueArgs ENTITY VAR) |
| set(multiValueArgs INSTALL_LIST NO_INSTALL_LIST) |
| cmake_parse_arguments( |
| CHECK_INSTALL_LIST |
| "${options}" |
| "${oneValueArgs}" |
| "${multiValueArgs}" |
| ${ARGN} |
| ) |
| |
| set(ENTITY ${CHECK_INSTALL_LIST_ENTITY}) |
| set(INSTALL_LIST ${CHECK_INSTALL_LIST_INSTALL_LIST}) |
| set(NO_INSTALL_LIST ${CHECK_INSTALL_LIST_NO_INSTALL_LIST}) |
| set(VAR ${CHECK_INSTALL_LIST_VAR}) |
| |
| # Initially accept |
| set(RET TRUE) |
| |
| # The install list provided, check against it. No install list means accept all |
| if (INSTALL_LIST) |
| if (NOT "${ENTITY}" IN_LIST INSTALL_LIST) |
| message(DEBUG "INSTALL: Skipping entity '${ENTITY}' as not on the install list") |
| set(RET FALSE) |
| endif () |
| endif () |
| |
| # The no-install list provided, check against it |
| if (NO_INSTALL_LIST) |
| if ("${ENTITY}" IN_LIST NO_INSTALL_LIST) |
| message(DEBUG "INSTALL: Skipping entity '${ENTITY}' as on the no-install list") |
| set(RET FALSE) |
| endif () |
| endif () |
| |
| # Return |
| set(${VAR} ${RET} PARENT_SCOPE) |
| |
| endfunction() |
| |
| # ============================================================================= |
| |
| function(CHECK_ARCH_INSTALL ARCH VAR) |
| # ~~~ |
| # CHECK_ARCH_INSTALL |
| # <arch> |
| # <variable> |
| # |
| # Checks if the given architecture is to be installed. |
| # ~~~ |
| |
| get_target_property_required(FAMILY ${ARCH} FAMILY) |
| |
| # Initially accept |
| set(RET TRUE) |
| |
| # Check the arch against the list |
| check_install_list( |
| ENTITY ${ARCH} |
| INSTALL_LIST ${SYMBIFLOW_ARCH_INSTALL_LIST} |
| NO_INSTALL_LIST ${SYMBIFLOW_ARCH_NO_INSTALL_LIST} |
| VAR RET |
| ) |
| |
| if(NOT ${RET}) |
| message(STATUS "INSTALL: Skipping architecture '${ARCH}' due to installation list") |
| set(${VAR} FALSE PARENT_SCOPE) |
| return() |
| endif() |
| |
| # Check the individual property of the arch |
| get_target_property_required(NO_INSTALL ${ARCH} NO_INSTALL) |
| if(${NO_INSTALL}) |
| message(STATUS "INSTALL: Skipping architecture '${ARCH}' as marked as NO_INSTALL") |
| set(RET FALSE) |
| endif() |
| |
| # Check the family against the list |
| check_install_list( |
| ENTITY ${FAMILY} |
| INSTALL_LIST ${SYMBIFLOW_FAMILY_INSTALL_LIST} |
| NO_INSTALL_LIST ${SYMBIFLOW_FAMILY_NO_INSTALL_LIST} |
| VAR RET |
| ) |
| |
| if(NOT ${RET}) |
| message(STATUS "INSTALL: Skipping architecture '${ARCH}' due to its family '${FAMILY}' (not) on an installation list") |
| set(${VAR} FALSE PARENT_SCOPE) |
| return() |
| endif() |
| |
| # Get list of devices of the given architecture |
| get_target_property_required(DEVICES ${ARCH} DEVICES) |
| |
| # No devices, don't install this arch |
| if (NOT DEVICES) |
| message(STATUS "INSTALL: Skipping architecture '${ARCH}' as there are no devices") |
| set(${VAR} FALSE PARENT_SCOPE) |
| return() |
| endif () |
| |
| # Examine each device |
| set(RET FALSE) |
| foreach(DEVICE ${DEVICES}) |
| |
| # Check the device against the list |
| check_install_list( |
| ENTITY ${DEVICE} |
| INSTALL_LIST ${SYMBIFLOW_DEVICE_INSTALL_LIST} |
| NO_INSTALL_LIST ${SYMBIFLOW_DEVICE_NO_INSTALL_LIST} |
| VAR RET |
| ) |
| |
| # Check the individual property of the device |
| if(${RET}) |
| get_target_property_required(NO_INSTALL ${DEVICE} NO_INSTALL) |
| if(NOT ${NO_INSTALL}) |
| break() |
| endif() |
| endif() |
| |
| endforeach() |
| |
| if(NOT RET) |
| message(STATUS "INSTALL: Skipping architecture '${ARCH}' as none of its devices it to be installed") |
| endif() |
| |
| # Return |
| set(${VAR} ${RET} PARENT_SCOPE) |
| |
| endfunction() |
| |
| |
| function(CHECK_DEVICE_INSTALL DEVICE VAR) |
| # ~~~ |
| # CHECK_DEVICE_INSTALL |
| # <device> |
| # <variable> |
| # |
| # Checks if the given device is to be installed by examining it and its |
| # architecture + family through the installation lists. Also checks individual |
| # NO_INSTALL properties of the device and its architecture |
| # ~~~ |
| |
| get_target_property_required(ARCH ${DEVICE} ARCH) |
| get_target_property_required(FAMILY ${ARCH} FAMILY) |
| |
| # Initially accept |
| set(RET TRUE) |
| |
| # Check the device against the list |
| check_install_list( |
| ENTITY ${DEVICE} |
| INSTALL_LIST ${SYMBIFLOW_DEVICE_INSTALL_LIST} |
| NO_INSTALL_LIST ${SYMBIFLOW_DEVICE_NO_INSTALL_LIST} |
| VAR RET |
| ) |
| |
| if(NOT ${RET}) |
| message(STATUS "INSTALL: Skipping device '${DEVICE}' due to installation list") |
| set(${VAR} FALSE PARENT_SCOPE) |
| return() |
| endif() |
| |
| # Check the individual property of the device |
| get_target_property_required(NO_INSTALL ${DEVICE} NO_INSTALL) |
| if(${NO_INSTALL}) |
| message(STATUS "INSTALL: Skipping device '${DEVICE}' as marked as NO_INSTALL") |
| set(RET FALSE) |
| endif() |
| |
| # Check the architecture against the list |
| check_install_list( |
| ENTITY ${ARCH} |
| INSTALL_LIST ${SYMBIFLOW_ARCH_INSTALL_LIST} |
| NO_INSTALL_LIST ${SYMBIFLOW_ARCH_NO_INSTALL_LIST} |
| VAR RET |
| ) |
| |
| if(NOT ${RET}) |
| message(STATUS "INSTALL: Skipping device '${DEVICE}' due to its architecture '${ARCH}' (not) on an installation list") |
| set(${VAR} FALSE PARENT_SCOPE) |
| return() |
| endif() |
| |
| # Check the individual property of the architecture |
| get_target_property_required(NO_INSTALL ${ARCH} NO_INSTALL) |
| if(${NO_INSTALL}) |
| message(STATUS "INSTALL: Skipping device '${DEVICE}' as its architecture '${ARCH}' is marked as NO_INSTALL") |
| set(RET FALSE) |
| endif() |
| |
| # Check the family against the list |
| check_install_list( |
| ENTITY ${FAMILY} |
| INSTALL_LIST ${SYMBIFLOW_FAMILY_INSTALL_LIST} |
| NO_INSTALL_LIST ${SYMBIFLOW_FAMILY_NO_INSTALL_LIST} |
| VAR RET |
| ) |
| |
| if(NOT ${RET}) |
| message(STATUS "INSTALL: Skipping device '${DEVICE}' due to its family '${FAMILY}' (not) on an installation list") |
| set(${VAR} FALSE PARENT_SCOPE) |
| return() |
| endif() |
| |
| # Return |
| set(${VAR} ${RET} PARENT_SCOPE) |
| |
| endfunction() |
| |
| # ============================================================================= |
| |
| function(INSTALL_DEVICE_FILES) |
| # ~~~ |
| # INSTALL_DEVICE_FILES( |
| # DEVICE <device> |
| # PACKAGE <package> |
| # DEVICE_TYPE <device_type> |
| # ) |
| # ~~~ |
| # |
| set(options) |
| set(oneValueArgs DEVICE PACKAGE DEVICE_TYPE) |
| set(multiValueArgs) |
| cmake_parse_arguments( |
| INSTALL_DEVICE_FILES |
| "${options}" |
| "${oneValueArgs}" |
| "${multiValueArgs}" |
| ${ARGN} |
| ) |
| |
| set(DEVICE ${INSTALL_DEVICE_FILES_DEVICE}) |
| set(DEVICE_TYPE ${INSTALL_DEVICE_FILES_DEVICE_TYPE}) |
| set(PACKAGE ${INSTALL_DEVICE_FILES_PACKAGE}) |
| |
| get_target_property(USE_ROI ${DEVICE_TYPE} USE_ROI) |
| if(USE_ROI OR USE_ROI STREQUAL "USE_ROI-NOTFOUND") |
| message(STATUS "Skipping device files installation for ${DEVICE}-${PACKAGE} type: ${DEVICE_TYPE}") |
| return() |
| endif() |
| |
| get_target_property(LIMIT_GRAPH_TO_DEVICE ${DEVICE_TYPE} LIMIT_GRAPH_TO_DEVICE) |
| if(LIMIT_GRAPH_TO_DEVICE OR LIMIT_GRAPH_TO_DEVICE STREQUAL "LIMIT_GRAPH_TO_DEVICE-NOTFOUND") |
| message(STATUS "Graph limited to a sub-area of the device. Skipping files installation for ${DEVICE}-${PACKAGE} type: ${DEVICE_TYPE}") |
| return() |
| endif() |
| |
| # Check if the device should be installed |
| check_device_install(${DEVICE} DO_INSTALL) |
| if (NOT DO_INSTALL) |
| return() |
| endif () |
| |
| set(INSTALL_FILES) |
| |
| # Get files to be installed |
| get_target_property_required(HAS_LOOKAHEAD ${DEVICE} "${PACKAGE}_HAS_LOOKAHEAD_CACHE") |
| get_target_property_required(HAS_PLACE_DELAY ${DEVICE} "${PACKAGE}_HAS_PLACE_DELAY_CACHE") |
| if(${HAS_LOOKAHEAD}) |
| get_target_property(LOOKAHEAD_FILE ${DEVICE} ${PACKAGE}_LOOKAHEAD_FILE) |
| list(APPEND INSTALL_FILES ${LOOKAHEAD_FILE}) |
| endif() |
| if(${HAS_PLACE_DELAY}) |
| get_target_property(PLACE_DELAY_FILE ${DEVICE} ${PACKAGE}_PLACE_DELAY_FILE) |
| list(APPEND INSTALL_FILES ${PLACE_DELAY_FILE}) |
| endif() |
| get_target_property_required(RR_GRAPH_FILE ${DEVICE} ${PACKAGE}_OUT_RRBIN_REAL) |
| list(APPEND INSTALL_FILES ${RR_GRAPH_FILE}) |
| |
| get_target_property_required(ARCH_FILE ${DEVICE_TYPE} DEVICE_MERGED_FILE) |
| list(APPEND INSTALL_FILES ${ARCH_FILE}) |
| |
| get_target_property(VPR_GRID_MAP_FILE ${DEVICE_TYPE} VPR_GRID_MAP) |
| if(NOT ${VPR_GRID_MAP_FILE} STREQUAL "VPR_GRID_MAP_FILE-NOTFOUND") |
| list(APPEND INSTALL_FILES ${VPR_GRID_MAP_FILE}) |
| endif() |
| |
| # Extra files for the device (common to all packages) |
| get_target_property(EXTRA_FILES ${DEVICE} EXTRA_INSTALL_FILES) |
| if(NOT ${EXTRA_FILES} MATCHES ".*-NOTFOUND" AND NOT ${EXTRA_FILES} STREQUAL "") |
| list(APPEND INSTALL_FILES ${EXTRA_FILES}) |
| endif() |
| |
| # Generate installation target for the files |
| foreach(FILE ${INSTALL_FILES}) |
| get_file_location(SRC_FILE ${FILE}) |
| get_filename_component(SRC_FILE_REAL ${SRC_FILE} REALPATH) |
| get_filename_component(FILE_NAME ${SRC_FILE} NAME) |
| append_file_dependency(DEPS ${FILE}) |
| # Create a custom target and add it to ALL target. |
| # We do this because install targets depend only on |
| # all. |
| add_custom_target( |
| "INSTALL_${DEVICE}_${PACKAGE}_${FILE_NAME}" |
| ALL |
| DEPENDS ${DEPS}) |
| install(FILES ${SRC_FILE_REAL} |
| DESTINATION "share/f4pga/arch/${DEVICE}_${PACKAGE}" |
| RENAME ${FILE_NAME} |
| ) |
| endforeach() |
| |
| endfunction() |
| |