Merge "Refactor utility functions"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c41392..cb26763 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,9 @@
 )
 
 set(BUILD_RV64_LINUX OFF CACHE BOOL "Build RISC-V 64-bit Linux target (default: OFF)")
-set(BUILD_INTERNAL_MODELS OFF CACHE BOOL "Build applications from internal models (default: OFF")
+set(BUILD_INTERNAL_MODELS OFF CACHE BOOL "Build applications from internal models (default: OFF)")
+set(IREE_SOURCE_DIR "$ENV{ROOTDIR}/toolchain/iree" CACHE PATH
+    "IREE source code path. (default: $ENV{ROOTDIR}/toolchain/iree)")
 
 # Use nano spec header and libraries.
 if(NOT ${BUILD_RV64_LINUX})
@@ -32,7 +34,6 @@
 add_link_options("LINKER:--defsym=__stack_size__=${STACK_SIZE}")
 set(SPRINGBOK_LINKER_SCRIPT "$ENV{ROOTDIR}/sw/vec/springbok/matcha.ld" CACHE PATH "Springbok linker script path (default: matcha.ld)")
 set(BUILD_WITH_SPRINGBOK ON CACHE BOOL "Build the target with springbok BSP (default: ON)")
-add_subdirectory($ENV{ROOTDIR}/sw/vec/springbok springbok)
 
 #-------------------------------------------------------------------------------
 # IREE-specific settings
@@ -57,21 +58,32 @@
   add_definitions(-DIREE_USER_CONFIG_H="${SPRINGBOK_CONFIG_HEADER}")
 endif()
 
-# Springbok BSP-related setting
+# The project does a cmake hack here -- at the executable linkage stage, we
+# append the logging library (and springbok BSP). Any logging library update
+# (libspringbok.a or libnative_log.a) only gets rebuilt during executable
+# linkage, but not during library compilation.
+#
+# However, an explicit include path gets added here across all targets so the
+# header files can be found during compilation.
 if(${BUILD_WITH_SPRINGBOK})
+  # Springbok BSP-related setting
+  add_subdirectory($ENV{ROOTDIR}/sw/vec/springbok springbok)
   include(riscv_springbok)
   include_directories($ENV{ROOTDIR}/sw/vec/springbok/include)
 else()
-  # Add the LOG_X springbok macros with fprintf.
-  include_directories(native_log_include)
+  # Add the springbok printout support.
+  add_subdirectory(native_log)
+  include(riscv_native_log)
+  include_directories(native_log)
 endif()
 
+message(STATUS "Include IREE source at ${IREE_SOURCE_DIR}")
 # Build IREE runtime libraries.
-add_subdirectory($ENV{ROOTDIR}/toolchain/iree iree)
+add_subdirectory(${IREE_SOURCE_DIR} iree)
 
 # Apply IREE's CMake variables and build options so we can use IREE build
 # functions properly in this project.
-include($ENV{ROOTDIR}/toolchain/iree/build_tools/cmake/iree_copts.cmake)
+include(${IREE_SOURCE_DIR}/build_tools/cmake/iree_copts.cmake)
 
 include(springbok_bytecode_module)
 include(iree_model_input)
diff --git a/cmake/riscv_native_log.cmake b/cmake/riscv_native_log.cmake
new file mode 100644
index 0000000..5e6fd1a
--- /dev/null
+++ b/cmake/riscv_native_log.cmake
@@ -0,0 +1,17 @@
+# A native log support to be compatible with springbok simprint
+#
+# Connect the logging library with the executables
+
+if(NOT TARGET native_log)
+  message(FATAL_ERROR "Please include native_log target first")
+endif()
+
+function(add_executable executable)
+  cmake_parse_arguments(AE "ALIAS;IMPORTED" "" "" ${ARGN})
+  if(AE_ALIAS OR AE_IMPORTED)
+    _add_executable(${executable} ${ARGN})
+  else()
+    _add_executable(${executable} ${ARGN})
+    target_link_libraries(${executable} PRIVATE native_log)
+  endif()
+endfunction()
diff --git a/native_log/CMakeLists.txt b/native_log/CMakeLists.txt
new file mode 100644
index 0000000..0c6cbb8
--- /dev/null
+++ b/native_log/CMakeLists.txt
@@ -0,0 +1,23 @@
+add_library(native_log STATIC)
+
+target_sources(native_log
+  PRIVATE
+    springbok.h
+    "$ENV{ROOTDIR}/sw/vec/springbok/springbok.cpp"
+)
+
+target_include_directories(native_log
+ PUBLIC
+   "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+target_compile_options(native_log
+  PRIVATE
+    "-Wall"
+)
+
+set_target_properties(
+  native_log
+  PROPERTIES
+  LINKER_LANGUAGE C
+)
diff --git a/native_log/springbok.h b/native_log/springbok.h
new file mode 100644
index 0000000..6872908
--- /dev/null
+++ b/native_log/springbok.h
@@ -0,0 +1,21 @@
+// Stub out the LOG implmentations with fprintf
+#ifndef SPRINGBOK_H
+#define SPRINGBOK_H
+
+#include <stdio.h>
+
+#define LOG_NOISY(msg, args...) fprintf(stdout, "[NOISY] " msg "\n", ##args)
+#define LOG_DEBUG(msg, args...) fprintf(stdout, "[DEBUG] " msg "\n", ##args)
+#define LOG_INFO(msg, args...) fprintf(stdout, "[INFO] " msg "\n", ##args)
+#define LOG_WARN(msg, args...) fprintf(stdout, "[WARN] " msg "\n", ##args)
+#define LOG_ERROR(msg, args...) fprintf(stderr, "[ERROR] " msg "\n", ##args)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int float_to_str(const int len, char *buffer, const float value);
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // SPRINGBOK_H
diff --git a/native_log_include/springbok.h b/native_log_include/springbok.h
deleted file mode 100644
index d56c2f4..0000000
--- a/native_log_include/springbok.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Stub out the LOG implmentations with fprintf
-#ifndef SPRINGBOK_H
-#define SPRINGBOK_H
-
-#include <stdio.h>
-
-#define LOG_NOISY(msg,args...) fprintf(stdout, msg"\n", ##args)
-#define LOG_DEBUG(msg,args...) fprintf(stdout, msg"\n", ##args)
-#define LOG_INFO(msg,args...) fprintf(stdout, msg"\n", ##args)
-#define LOG_WARN(msg,args...) fprintf(stdout, msg"\n", ##args)
-#define LOG_ERROR(msg, args...) fprintf(stderr, msg"\n", ##args)
-
-#endif  // SPRINGBOK_H