diff --git a/hpvm/CMakeLists.txt b/hpvm/CMakeLists.txt
index 53cd456ad96108226c5aec0bad3aed70f0555f1f..b6985d0a100f38a7712580a30d3ba91e59dd248c 100644
--- a/hpvm/CMakeLists.txt
+++ b/hpvm/CMakeLists.txt
@@ -1,6 +1,14 @@
-include_directories(./include/)
+cmake_minimum_required(VERSION 3.17)
+project(hpvm CUDA CXX)
+get_filename_component(
+  CUDA_TOOLKIT_ROOT_DIR "${CMAKE_CUDA_COMPILER}/../.." ABSOLUTE
+)  # Set CUDA_TOOLKIT_ROOT_DIR by our own, to the parent folder of cuda nvcc
+
 # find_package will use the auxillary cmake/Find*.cmake we provide
 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+find_package(CUDNN 7 EXACT REQUIRED)  # CUDNN_INCLUDE_PATH, CUDNN_LIBRARY_PATH
+
+include_directories(./include/)
 
 # Generate TENSOR_RT_PREFIX into config.h
 set(TENSOR_RT_PREFIX ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
diff --git a/hpvm/lib/Transforms/DFG2LLVM_CPU/CMakeLists.txt b/hpvm/lib/Transforms/DFG2LLVM_CPU/CMakeLists.txt
index b4e129ba01837cf328912f7787b861f843f4f581..83ec877b0675f0b2a841e24d15126932c812bbd9 100644
--- a/hpvm/lib/Transforms/DFG2LLVM_CPU/CMakeLists.txt
+++ b/hpvm/lib/Transforms/DFG2LLVM_CPU/CMakeLists.txt
@@ -2,7 +2,7 @@ if(WIN32 OR CYGWIN)
   set(LLVM_LINK_COMPONENTS Core Support)
 endif()
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_BUILD_DIR=${PROJECT_BINARY_DIR}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_BUILD_DIR=${CMAKE_BINARY_DIR}")
 
 add_llvm_library( LLVMDFG2LLVM_CPU
   MODULE
diff --git a/hpvm/lib/Transforms/DFG2LLVM_OpenCL/CMakeLists.txt b/hpvm/lib/Transforms/DFG2LLVM_OpenCL/CMakeLists.txt
index 00c651eaa250fc114f229f30e0cb7c121154ff96..4041df11ce8d79e39d6f72bdf0a1068eae449300 100644
--- a/hpvm/lib/Transforms/DFG2LLVM_OpenCL/CMakeLists.txt
+++ b/hpvm/lib/Transforms/DFG2LLVM_OpenCL/CMakeLists.txt
@@ -2,7 +2,7 @@ if(WIN32 OR CYGWIN)
   set(LLVM_LINK_COMPONENTS Core Support)
 endif()
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_BUILD_DIR=${PROJECT_BINARY_DIR}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_BUILD_DIR=${CMAKE_BINARY_DIR}")
 
 add_llvm_library( LLVMDFG2LLVM_OpenCL
   MODULE
diff --git a/hpvm/lib/Transforms/GenHPVM/CMakeLists.txt b/hpvm/lib/Transforms/GenHPVM/CMakeLists.txt
index fc4c9fc5a98007dd700973c598b6731edcd61e14..fbf5881480ce11745b0d4de00b90c0812a6db356 100644
--- a/hpvm/lib/Transforms/GenHPVM/CMakeLists.txt
+++ b/hpvm/lib/Transforms/GenHPVM/CMakeLists.txt
@@ -2,7 +2,7 @@ if(WIN32 OR CYGWIN)
   set(LLVM_LINK_COMPONENTS Core Support)
 endif()
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_BUILD_DIR=${PROJECT_BINARY_DIR}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_BUILD_DIR=${CMAKE_BINARY_DIR}")
 
 add_llvm_library( LLVMGenHPVM
   MODULE
diff --git a/hpvm/projects/CMakeLists.txt b/hpvm/projects/CMakeLists.txt
index b46164b8d07de77ba9feb570b976e19ae9fdf4b2..2a51c0b09e672e8508a8a13d189d05eb3ccc2e48 100644
--- a/hpvm/projects/CMakeLists.txt
+++ b/hpvm/projects/CMakeLists.txt
@@ -10,7 +10,6 @@ foreach(entry ${entries})
        (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/parallel-libs) AND
        (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/openmp) AND
        (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/debuginfo-tests))
-      set(LLVM_BUILD_DIR ${PROJECT_BINARY_DIR})
       get_filename_component(entry_name "${entry}" NAME)
       add_llvm_external_project(${entry_name})
     endif()
diff --git a/hpvm/projects/hpvm-rt/CMakeLists.txt b/hpvm/projects/hpvm-rt/CMakeLists.txt
index 02ab62fca57f66155ffafff0686634b3efe4f861..6efd8d3d0a9d86236adc87657fb68b782f3daaa0 100644
--- a/hpvm/projects/hpvm-rt/CMakeLists.txt
+++ b/hpvm/projects/hpvm-rt/CMakeLists.txt
@@ -1,7 +1,7 @@
 add_definitions(-DNUM_CORES=8)
 
-SET(CMAKE_C_COMPILER ${CMAKE_BINARY_DIR}/bin/clang)
-SET(CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/bin/clang++)
+SET(CMAKE_C_COMPILER ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clang)
+SET(CMAKE_CXX_COMPILER ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clang++)
 SET(CMAKE_CXX_STANDARD 11)
 # Defines ${OpenCL_INCLUDE_DIRS} and ${OpenCL_LIBRARY} if found
 find_package(OpenCL REQUIRED)
diff --git a/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt b/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt
index f863158ff2a6fdecce38fe42bd7510ab8187d809..5c04604406eb81571c0a87539fb0568aad3c4e4d 100644
--- a/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt
+++ b/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt
@@ -1,7 +1,14 @@
-cmake_minimum_required(VERSION 3.17)
 project(hpvm-tensor-rt CUDA CXX)
 set(CMAKE_CXX_STANDARD 14)
 
+if(CMAKE_CURRENT_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)  # This means we're NOT compiling in HPVM
+  set(INDEP_BUILD True)
+  message(STATUS "Compiling hpvm-tensor-rt independently")
+else()
+  set(INDEP_BUILD False)
+  message(STATUS "Compiling hpvm-tensor-rt inside HPVM")
+endif()
+
 # -- Configure path configuration file
 if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/global_knobs.txt)
   message(FATAL_ERROR "global_knobs.txt not found")
@@ -15,7 +22,6 @@ configure_file(
 )
 
 # -- Default include directories
-find_package(CUDNN 7 EXACT REQUIRED)  # Include CUDNN_INCLUDE_PATH, then link CUDNN_LIBRARY_PATH
 set(
   INCLUDES
   ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
@@ -30,8 +36,7 @@ find_package(OpenMP REQUIRED)  # Provides ${OpenMP_CXX_FLAGS}
 # Configure gpu_profiler and soc_simulator, and setup all libs to link to
 # Conditionally add gpu_profiler project if we're building independently
 # (not building the whole hpvm)
-if(NOT LLVM_BUILD_DIR)  # Defined in ../CMakeLists.txt. This means we're compiling in LLVM
-  message(STATUS "Compiling hpvm-tensor-rt independently")
+if(INDEP_BUILD)
   message(STATUS "Also compiling gpu_profiler and soc_simulator")
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../gpu_profiler ${CMAKE_CURRENT_BINARY_DIR}/gpu_profiler)
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../soc_simulator ${CMAKE_CURRENT_BINARY_DIR}/soc_simulator)
@@ -102,33 +107,33 @@ add_executable(unit_tests dnn_sources/src/unit_tests.cc)
 target_link_libraries(unit_tests  tensor_runtime_online ${GPU_PROFILER_LIB} ${SOC_SIMULATOR_LIB})
 
 # -- Compile tensor_runtime.ll if possible
-if(LLVM_BUILD_DIR)  # Defined in ../CMakeLists.txt. This means we're compiling in LLVM
-  get_filename_component(LLVM_CLANG_XX ${LLVM_BUILD_DIR}/bin/clang++ REALPATH)
-  # It's important that tensor_runtime.ll goes here if we're compiling with LLVM
-  # Some HPVM passes look for tensor_runtime.ll in this folder (which is usually build/lib)
-  set(TENSOR_RT_LL_PREFIX ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
-  add_dependencies(tensor_runtime clang)
-else()
-  # Surely if we're compiling outside of hpvm, then we need the system-wide clang.
-  # Use it but check version 9 first
-  execute_process(COMMAND clang++ --version OUTPUT_VARIABLE clang_full_version_string ERROR_QUIET)
-  string(REGEX REPLACE ".*clang version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION_STRING ${clang_full_version_string})
-  if(CLANG_VERSION_STRING VERSION_EQUAL 9)
-    set(LLVM_CLANG_XX clang++)
+if(INDEP_BUILD)
+  # Surely if we're compiling outside of hpvm, then we need the system-wide clang -- a clang 9.
+  execute_process(COMMAND clang-9 --version OUTPUT_VARIABLE clang_stdout ERROR_QUIET)
+  if(clang_stdout)
     set(TENSOR_RT_LL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/lib)
   else()
     message(WARNING "System clang++ of version 9 not found; skipping tensor_runtime.ll generation")
   endif()
+  set(CLANG_NAME clang-9)
+else()
+  # It's important that tensor_runtime.ll goes here if we're compiling with LLVM
+  # Some HPVM passes look for tensor_runtime.ll in this folder (which is usually build/lib)
+  set(TENSOR_RT_LL_PREFIX ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+  # Per cmake documentation, if we're building in LLVM, then in add_custom_command
+  # the command "clang" will be auto resolved to the path to clang we're building
+  set(CLANG_NAME clang)
+  add_dependencies(tensor_runtime clang)
 endif()
 # If some clang-9 is found, create a tensor_runtime.ll from tensor_signatures.cc
-if(LLVM_CLANG_XX)
+if(CLANG_NAME)
   message(STATUS "Creating tensor_runtime.ll in ${TENSOR_RT_LL_PREFIX}")
   foreach(dir ${INCLUDES})
     list(APPEND INCLUDE_COMPILER_STRINGS "-I${dir}")
   endforeach()
   add_custom_command(
     TARGET tensor_runtime POST_BUILD
-    COMMAND ${LLVM_CLANG_XX} ${INCLUDE_COMPILER_STRINGS} -S -emit-llvm
+    COMMAND ${CLANG_NAME} -x c++ ${INCLUDE_COMPILER_STRINGS} -S -emit-llvm
     ${CMAKE_CURRENT_SOURCE_DIR}/tensor_runtime/include/tensor_signatures.cc
     -o ${TENSOR_RT_LL_PREFIX}/tensor_runtime.ll
   )
diff --git a/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt b/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt
index 76d6910d2d43d641f5a2dfff1d48b39fe25686a4..37a856123d1ea9ee074a5ac2844b223a78c56e16 100644
--- a/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt
+++ b/hpvm/test/dnn_benchmarks/hpvm-c/CMakeLists.txt
@@ -1,5 +1,5 @@
 # First get approxhpvm.py which we then use to compile benchmarks.
-get_filename_component(APPROXHPVM_PY ${PROJECT_BINARY_DIR}/bin/approxhpvm.py REALPATH)
+get_filename_component(APPROXHPVM_PY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/approxhpvm.py REALPATH)
 
 # Configure config.h which tells the benchmarks where's the model parameter directory.
 # We can also use the one in tensor_runtime, but we're avoiding that so as to 
diff --git a/hpvm/tools/py-approxhpvm/CMakeLists.txt b/hpvm/tools/py-approxhpvm/CMakeLists.txt
index d35ae6ac24b6b1f59bc06d1365d0dda7903ba017..60fbc66aadd362e6aceb507dec5f1bec1223c418 100644
--- a/hpvm/tools/py-approxhpvm/CMakeLists.txt
+++ b/hpvm/tools/py-approxhpvm/CMakeLists.txt
@@ -1,9 +1,9 @@
 # This file is very tightly coupled with main.py.in.
 # Watch out and keep them in sync.
 
-set(LLVM_PROJECT_DIR ${PROJECT_SOURCE_DIR})
-set(LLVM_BUILD_DIR ${PROJECT_BINARY_DIR})
-set(LIB_DIR ${PROJECT_BINARY_DIR}/lib)
+set(LLVM_PROJECT_DIR ${CMAKE_SOURCE_DIR})
+set(LLVM_BUILD_DIR ${CMAKE_BINARY_DIR})
+set(LIB_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
 # The hpvm-rt runtime
 # This has to be explicitly set as hpvm-rt.bc is created in a custom_target
 # and does not export its file location.
@@ -26,8 +26,7 @@ set(
     LLVMClearDFG
     LLVMGenHPVM
 )
-find_package(CUDA REQUIRED)  # Defines CUDA_TOOLKIT_ROOT_DIR
-find_package(CUDNN 7 REQUIRED)  # Defines CUDNN_LIBRARY_PATH
+# CUDA_TOOLKIT_ROOT_DIR and CUDNN_LIBRARY_PATH has been defined globally
 set(CUDNN_DIR ${CUDNN_LIBRARY_PATH})
 # First resolve all `@symbol@` by configuring the file
 configure_file(main.py.in ${CMAKE_CURRENT_BINARY_DIR}/main.py.conf)
@@ -53,9 +52,9 @@ set(
     clang opt llvm-link
 )
 add_custom_command(
-    OUTPUT ${PROJECT_BINARY_DIR}/bin/approxhpvm.py
-    COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/main.py ${PROJECT_BINARY_DIR}/bin/approxhpvm.py
-    COMMAND chmod +x ${PROJECT_BINARY_DIR}/bin/approxhpvm.py
+    OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/approxhpvm.py
+    COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/main.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/approxhpvm.py
+    COMMAND chmod +x ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/approxhpvm.py
     DEPENDS ${DEPS} ${CMAKE_CURRENT_BINARY_DIR}/main.py
 )
-add_custom_target(approxhpvm.py ALL DEPENDS ${PROJECT_BINARY_DIR}/bin/approxhpvm.py)
+add_custom_target(approxhpvm.py ALL DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/approxhpvm.py)