diff --git a/lib/file_system/backends/fs_mac.ex b/lib/file_system/backends/fs_mac.ex
index 68a8476a0edbb724f5feb20948eeb348853b6409..ff0fc6beefd2885f4aa45d39a1f5704355be0a78 100644
--- a/lib/file_system/backends/fs_mac.ex
+++ b/lib/file_system/backends/fs_mac.ex
@@ -40,32 +40,12 @@ defmodule FileSystem.Backends.FSMac do
 
   def bootstrap do
     exec_file = executable_path()
-    cond do
-      is_nil(exec_file) -> {:error, :fs_mac_bootstrap_error}
-      File.exists?(exec_file) -> :ok
-      true -> compile_executable_file(exec_file)
-    end
-  end
-
-  defp compile_executable_file(exec_file) do
-    Logger.info "Compiling executable file..."
-    src_dir =
-      case Mix.Project.config[:app] do
-        :file_system -> "."
-        _ -> Mix.Project.deps_paths[:file_system]
-      end
-    cmd = "clang -framework CoreFoundation -framework CoreServices -Wno-deprecated-declarations #{src_dir}/c_src/mac/*.c -o #{exec_file}"
-    if Mix.shell.cmd(cmd) > 0 do
-      Logger.error ~s|Compile executable file error, try to run "#{cmd}" manually.|
-      {:error, :fs_mac_bootstrap_error}
-    else
-      Logger.info "Compile executable file, Done."
+    if not is_nil(exec_file) and File.exists?(exec_file) do
       :ok
-    end
-  rescue
-    _ ->
-      Logger.error ~s|Automatic compile executable file failed, run "mix file_system.fs_mac init" to compile it manually.|
+    else
+      Logger.error "Can't find executable `mac_listener`"
       {:error, :fs_mac_bootstrap_error}
+    end
   end
 
   def supported_systems do
@@ -84,13 +64,7 @@ defmodule FileSystem.Backends.FSMac do
   end
 
   defp executable_path(:config) do
-    with config when is_list(config) <- Application.get_env(:file_system, :fs_mac),
-         executable_file when not is_nil(executable_file) <- Keyword.get(config, :executable_file)
-    do
-      executable_file |> to_string
-    else
-      _ -> nil
-    end
+    Application.get_env(:file_system, :fs_mac)[:executable_file]
   end
 
   defp executable_path(:system_env) do
diff --git a/lib/file_system/backends/fs_windows.ex b/lib/file_system/backends/fs_windows.ex
index fbfcadbd1acaa3723cc4eeff159481576827b566..3fbe04aa6a4d235e273d513ec32f3fa9d1e803f0 100644
--- a/lib/file_system/backends/fs_windows.ex
+++ b/lib/file_system/backends/fs_windows.ex
@@ -51,13 +51,7 @@ defmodule FileSystem.Backends.FSWindows do
   end
 
   defp executable_path(:config) do
-    with config when is_list(config) <- Application.get_env(:file_system, :fs_windows),
-         executable_file when not is_nil(executable_file) <- Keyword.get(config, :executable_file)
-    do
-      executable_file |> to_string
-    else
-      _ -> nil
-    end
+    Application.get_env(:file_system, :fs_windows)[:executable_file]
   end
 
   defp executable_path(:system_env) do
diff --git a/lib/mix/tasks/fs_mac.ex b/lib/mix/tasks/fs_mac.ex
deleted file mode 100644
index 7d966f942d36d3de22741ff8036f635cac6e1b36..0000000000000000000000000000000000000000
--- a/lib/mix/tasks/fs_mac.ex
+++ /dev/null
@@ -1,17 +0,0 @@
-defmodule Mix.Tasks.FileSystem.FsMac do
-  use Mix.Task
-
-  @doc false
-  def run(["init"]) do
-    case FileSystem.Backends.FSMac.bootstrap do
-      :ok ->
-        IO.puts "Initialize fs_mac backend successfully."
-      {:error, reason} ->
-        IO.puts :stderr, "Initialize fs_mac backend error, reason: #{reason}."
-    end
-  end
-
-  def run(args) do
-    IO.puts :stderr, "unknown command `#{args}`"
-  end
-end
diff --git a/mix.exs b/mix.exs
index 74d5f2c3bd25386eff89a1f670cef0ee2e6bf811..d57ba9d1e52fe1e413b5d3b786d1d89cf87c5d09 100644
--- a/mix.exs
+++ b/mix.exs
@@ -9,6 +9,8 @@ defmodule FileSystem.Mixfile do
       description: "A file system change watcher wrapper based on [fs](https://github.com/synrc/fs)",
       source_url: "https://github.com/falood/file_system",
       package: package(),
+      compilers: [:file_system | Mix.compilers],
+      aliases: ["compile.file_system": &file_system/1],
       docs: [
         extras: ["README.md"],
         main: "readme",
@@ -28,6 +30,32 @@ defmodule FileSystem.Mixfile do
     ]
   end
 
+  defp file_system(_args) do
+    case :os.type do
+      {:unix, :darwin} -> compile_mac()
+      _ -> :ok
+    end
+  end
+
+  defp compile_mac do
+    require Logger
+    source = "c_src/mac/*.c"
+    target = "priv/mac_listener"
+
+    if Mix.Utils.stale?(Path.wildcard(source), [target]) do
+      Logger.info "Compiling file system watcher for Mac..."
+      cmd = "clang -framework CoreFoundation -framework CoreServices -Wno-deprecated-declarations #{source} -o #{target}"
+      if Mix.shell.cmd(cmd) > 0 do
+        Logger.error "Could not compile file system watcher for Mac, try to run #{inspect cmd} manually inside the dependnecy."
+      else
+        Logger.info "Done."
+      end
+      :ok
+    else
+      :noop
+    end
+  end
+
   defp package do
     %{ maintainers: ["Xiangrong Hao", "Max Veytsman"],
        files: [