[xc7] Install torc in Docker image
diff --git a/.cirrus.yml b/.cirrus.yml
index 38e1451..40b335d 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -5,8 +5,9 @@
     memory: 16
     dockerfile: .cirrus/Dockerfile.ubuntu16.04
 
-  build_script: mkdir build && cd build && cmake .. -DARCH=all -DTRELLIS_ROOT=/usr/local/src/prjtrellis -DBUILD_TESTS=on && make -j $(nproc)
+  build_script: mkdir build && cd build && cmake .. -DARCH=all -DTRELLIS_ROOT=/usr/local/src/prjtrellis -DTORC_ROOT=/usr/local/src/torc -DBUILD_TESTS=on && make -j $(nproc)
   test_generic_script: cd build && ./nextpnr-generic-test
   test_ice40_script: cd build && ./nextpnr-ice40-test
   smoketest_ice40_script: export NEXTPNR=$(pwd)/build/nextpnr-ice40 && cd ice40/smoketest/attosoc && ./smoketest.sh
-  test_ecp5_script: cd build && ./nextpnr-ecp5-test
\ No newline at end of file
+  test_ecp5_script: cd build && ./nextpnr-ecp5-test
+  test_xc7_script: cd build && ./nextpnr-xc7-test
diff --git a/.cirrus/Dockerfile.ubuntu16.04 b/.cirrus/Dockerfile.ubuntu16.04
index 71a634b..673fb54 100644
--- a/.cirrus/Dockerfile.ubuntu16.04
+++ b/.cirrus/Dockerfile.ubuntu16.04
@@ -52,4 +52,11 @@
     make -j $(nproc) ;\
     make install
 
-
+RUN set -e -x ;\
+    mkdir -p /usr/local/src ;\
+    cd /usr/local/src ;\
+    git clone --recursive https://github.com/eddiehung/torc.git ;\
+    cd torc ;\
+    git reset --hard 90874d1293fbeba77bae41b5c38168cd91e1bf00 ;\
+    make -j $(nproc) -C src/torc ;\
+    make install
diff --git a/xc7/family.cmake b/xc7/family.cmake
index 12bb3cf..c1c7dcb 100644
--- a/xc7/family.cmake
+++ b/xc7/family.cmake
@@ -1,99 +1,103 @@
-# Adapted https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html
-find_package(Git QUIET)
-if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules")
-# Update submodules as needed
-    option(GIT_SUBMODULE "Check submodules during build" ON)
-    if(GIT_SUBMODULE)
-        message(STATUS "Submodule update")
-        execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
-                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-                        RESULT_VARIABLE GIT_SUBMOD_RESULT)
-        if(NOT GIT_SUBMOD_RESULT EQUAL "0")
-            message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
+if (NOT DEFINED TORC_ROOT)
+    # Adapted from https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html
+    find_package(Git QUIET)
+    if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules")
+    # Update submodules as needed
+        option(GIT_SUBMODULE "Check submodules during build" ON)
+        if(GIT_SUBMODULE)
+            message(STATUS "Submodule update")
+            execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
+                            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                            RESULT_VARIABLE GIT_SUBMOD_RESULT)
+            if(NOT GIT_SUBMOD_RESULT EQUAL "0")
+                message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
+            endif()
         endif()
     endif()
+
+    add_dependencies(nextpnr-${family} torc)
+    if (BUILD_TESTS)
+        add_dependencies(nextpnr-${family}-test torc)
+    endif()
+    add_custom_target(torc ALL
+                      COMMAND $(MAKE) > /dev/null 2> /dev/null
+                      COMMENT "Building torc (may take some time...)"
+                      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/torc/src)
+    find_package(Boost REQUIRED COMPONENTS serialization iostreams ${boost_libs} ${boost_python_lib})
+
+    set(TORC_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
 endif()
 
-add_dependencies(nextpnr-${family} torc)
+target_include_directories(nextpnr-${family} PUBLIC ${TORC_ROOT}/torc/src)
 if (BUILD_TESTS)
-    add_dependencies(nextpnr-${family}-test torc)
-endif()
-add_custom_target(torc ALL
-                  COMMAND $(MAKE) > /dev/null 2> /dev/null
-                  COMMENT "Building torc (may take some time...)"
-                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/torc/src)
-find_package(Boost REQUIRED COMPONENTS serialization iostreams ${boost_libs} ${boost_python_lib})
-
-target_include_directories(nextpnr-${family} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/torc/src)
-if (BUILD_TESTS)
-    target_include_directories(nextpnr-${family}-test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/torc/src)
+    target_include_directories(nextpnr-${family}-test PUBLIC ${TORC_ROOT}/torc/src)
 endif()
 if (BUILD_GUI)
-    target_include_directories(gui_${family} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/torc/src)
+    target_include_directories(gui_${family} PUBLIC ${TORC_ROOT}/torc/src)
 endif()
 
 set(TORC_OBJS
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Arc.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/ArcUsage.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Array.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/DDB.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/DDBConsoleStreams.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/DDBStreamHelper.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/DigestStream.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/ExtendedWireInfo.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/InstancePin.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/OutputStreamHelpers.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Package.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Pad.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/PrimitiveConn.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/PrimitiveDef.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/PrimitiveElement.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/PrimitiveElementPin.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/PrimitivePin.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Segments.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Site.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Sites.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Tiles.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/TileInfo.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Tilewire.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/Versions.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/VprExporter.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/WireInfo.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/WireUsage.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/XdlImporter.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/architecture/XilinxDatabaseTypes.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Arc.o
+    ${TORC_ROOT}/torc/src/torc/architecture/ArcUsage.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Array.o
+    ${TORC_ROOT}/torc/src/torc/architecture/DDB.o
+    ${TORC_ROOT}/torc/src/torc/architecture/DDBConsoleStreams.o
+    ${TORC_ROOT}/torc/src/torc/architecture/DDBStreamHelper.o
+    ${TORC_ROOT}/torc/src/torc/architecture/DigestStream.o
+    ${TORC_ROOT}/torc/src/torc/architecture/ExtendedWireInfo.o
+    ${TORC_ROOT}/torc/src/torc/architecture/InstancePin.o
+    ${TORC_ROOT}/torc/src/torc/architecture/OutputStreamHelpers.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Package.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Pad.o
+    ${TORC_ROOT}/torc/src/torc/architecture/PrimitiveConn.o
+    ${TORC_ROOT}/torc/src/torc/architecture/PrimitiveDef.o
+    ${TORC_ROOT}/torc/src/torc/architecture/PrimitiveElement.o
+    ${TORC_ROOT}/torc/src/torc/architecture/PrimitiveElementPin.o
+    ${TORC_ROOT}/torc/src/torc/architecture/PrimitivePin.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Segments.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Site.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Sites.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Tiles.o
+    ${TORC_ROOT}/torc/src/torc/architecture/TileInfo.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Tilewire.o
+    ${TORC_ROOT}/torc/src/torc/architecture/Versions.o
+    ${TORC_ROOT}/torc/src/torc/architecture/VprExporter.o
+    ${TORC_ROOT}/torc/src/torc/architecture/WireInfo.o
+    ${TORC_ROOT}/torc/src/torc/architecture/WireUsage.o
+    ${TORC_ROOT}/torc/src/torc/architecture/XdlImporter.o
+    ${TORC_ROOT}/torc/src/torc/architecture/XilinxDatabaseTypes.o
 
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/common/Annotated.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/common/DeviceDesignator.o
-	${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/common/Devices.o
-	${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/common/DirectoryTree.o
-	${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/common/DottedVersion.o
-	${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/common/NullOutputStream.o
+    ${TORC_ROOT}/torc/src/torc/common/Annotated.o
+    ${TORC_ROOT}/torc/src/torc/common/DeviceDesignator.o
+	${TORC_ROOT}/torc/src/torc/common/Devices.o
+	${TORC_ROOT}/torc/src/torc/common/DirectoryTree.o
+	${TORC_ROOT}/torc/src/torc/common/DottedVersion.o
+	${TORC_ROOT}/torc/src/torc/common/NullOutputStream.o
 
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/externals/zlib/zfstream.o
+    ${TORC_ROOT}/torc/src/torc/externals/zlib/zfstream.o
     z
 
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Circuit.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/ConfigMap.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Config.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Design.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Factory.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Instance.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/InstancePin.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/InstanceReference.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Module.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/ModuleTransformer.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Named.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Net.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/OutputStreamHelpers.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Pip.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Port.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Progenitor.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Progeny.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Renamable.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/Routethrough.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/TilewirePlaceholder.o
-    ${CMAKE_CURRENT_SOURCE_DIR}/torc/src/torc/physical/XdlExporter.o
+    ${TORC_ROOT}/torc/src/torc/physical/Circuit.o
+    ${TORC_ROOT}/torc/src/torc/physical/ConfigMap.o
+    ${TORC_ROOT}/torc/src/torc/physical/Config.o
+    ${TORC_ROOT}/torc/src/torc/physical/Design.o
+    ${TORC_ROOT}/torc/src/torc/physical/Factory.o
+    ${TORC_ROOT}/torc/src/torc/physical/Instance.o
+    ${TORC_ROOT}/torc/src/torc/physical/InstancePin.o
+    ${TORC_ROOT}/torc/src/torc/physical/InstanceReference.o
+    ${TORC_ROOT}/torc/src/torc/physical/Module.o
+    ${TORC_ROOT}/torc/src/torc/physical/ModuleTransformer.o
+    ${TORC_ROOT}/torc/src/torc/physical/Named.o
+    ${TORC_ROOT}/torc/src/torc/physical/Net.o
+    ${TORC_ROOT}/torc/src/torc/physical/OutputStreamHelpers.o
+    ${TORC_ROOT}/torc/src/torc/physical/Pip.o
+    ${TORC_ROOT}/torc/src/torc/physical/Port.o
+    ${TORC_ROOT}/torc/src/torc/physical/Progenitor.o
+    ${TORC_ROOT}/torc/src/torc/physical/Progeny.o
+    ${TORC_ROOT}/torc/src/torc/physical/Renamable.o
+    ${TORC_ROOT}/torc/src/torc/physical/Routethrough.o
+    ${TORC_ROOT}/torc/src/torc/physical/TilewirePlaceholder.o
+    ${TORC_ROOT}/torc/src/torc/physical/XdlExporter.o
 )
 
 target_link_libraries(nextpnr-${family} PRIVATE ${TORC_OBJS})