Skip to content

Commit

Permalink
automatically detect musl, allow overriding target
Browse files Browse the repository at this point in the history
Tailwind v4 includes binaries for linux-x64-musl and linux-arm64-musl.
This commit adds support for automatically selecting those based on the
system architecture. It also adds a config option to override the target,
if necessary.
  • Loading branch information
SteffenDE committed Feb 3, 2025
1 parent e3cfa8d commit 27ad86f
Showing 1 changed file with 60 additions and 17 deletions.
77 changes: 60 additions & 17 deletions lib/tailwind.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule Tailwind do
## Tailwind configuration
There are two global configurations for the tailwind application:
There are four global configurations for the tailwind application:
* `:version` - the expected tailwind version
Expand All @@ -36,6 +36,10 @@ defmodule Tailwind do
default, it is automatically downloaded and placed inside
the `_build` directory of your current app
* `:target` - the target architecture for the tailwind executable.
For example `"linux-x64-musl"`. By default, it is automatically detected
based on system information.
Overriding the `:path` is not recommended, as we will automatically
download and manage `tailwind` for you. But in case you can't download
it (for example, GitHub behind a proxy), you may want to
Expand Down Expand Up @@ -109,6 +113,13 @@ defmodule Tailwind do
Application.get_env(:tailwind, :version, latest_version())
end

@doc """
Returns the configured tailwind target. By default, it is automatically detected.
"""
def configured_target do
Application.get_env(:tailwind, :target, target())
end

@doc """
Returns the configuration for the given profile.
Expand Down Expand Up @@ -138,7 +149,7 @@ defmodule Tailwind do
The executable may not be available if it was not yet installed.
"""
def bin_path do
name = "tailwind-#{target()}"
name = "tailwind-#{configured_target()}"

Application.get_env(:tailwind, :path) ||
if Code.ensure_loaded?(Mix.Project) do
Expand Down Expand Up @@ -248,19 +259,51 @@ defmodule Tailwind do
# tailwindcss-windows-x64.exe
defp target do
arch_str = :erlang.system_info(:system_architecture)
[arch | _] = arch_str |> List.to_string() |> String.split("-")

case {:os.type(), arch, :erlang.system_info(:wordsize) * 8} do
{{:win32, _}, _arch, 64} -> "windows-x64.exe"
{{:unix, :darwin}, arch, 64} when arch in ~w(arm aarch64) -> "macos-arm64"
{{:unix, :darwin}, "x86_64", 64} -> "macos-x64"
{{:unix, :freebsd}, "aarch64", 64} -> "freebsd-arm64"
{{:unix, :freebsd}, arch, 64} when arch in ~w(x86_64 amd64) -> "freebsd-x64"
{{:unix, :linux}, "aarch64", 64} -> "linux-arm64"
{{:unix, :linux}, "arm", 32} -> "linux-armv7"
{{:unix, :linux}, "armv7" <> _, 32} -> "linux-armv7"
{{:unix, _osname}, arch, 64} when arch in ~w(x86_64 amd64) -> "linux-x64"
{_os, _arch, _wordsize} -> raise "tailwind is not available for architecture: #{arch_str}"
target_triple = arch_str |> List.to_string() |> String.split("-")

{arch, abi} =
case target_triple do
[arch, _vendor, _system, abi] -> {arch, abi}
[arch, _vendor, abi] -> {arch, abi}
[arch | _] -> {arch, nil}
end

case {:os.type(), arch, abi, :erlang.system_info(:wordsize) * 8} do
{{:win32, _}, _arch, _abi, 64} ->
"windows-x64.exe"

{{:unix, :darwin}, arch, _abi, 64} when arch in ~w(arm aarch64) ->
"macos-arm64"

{{:unix, :darwin}, "x86_64", _abi, 64} ->
"macos-x64"

{{:unix, :freebsd}, "aarch64", _abi, 64} ->
"freebsd-arm64"

{{:unix, :freebsd}, arch, _abi, 64} when arch in ~w(x86_64 amd64) ->
"freebsd-x64"

{{:unix, :linux}, "aarch64", "musl", 64} ->
"linux-arm64-musl"

{{:unix, :linux}, "aarch64", _abi, 64} ->
"linux-arm64"

{{:unix, :linux}, "arm", _abi, 32} ->
"linux-armv7"

{{:unix, :linux}, "armv7" <> _, _abi, 32} ->
"linux-armv7"

{{:unix, _osname}, arch, "musl", 64} when arch in ~w(x86_64 amd64) ->
"linux-x64-musl"

{{:unix, _osname}, arch, _abi, 64} when arch in ~w(x86_64 amd64) ->
"linux-x64"

{_os, _arch, _abi, _wordsize} ->
raise "tailwind is not available for architecture: #{arch_str}"
end
end

Expand Down Expand Up @@ -316,7 +359,7 @@ defmodule Tailwind do
your certificates are set via OTP ca certfile overide via SSL configuration.
2. Manually download the executable from the URL above and
place it inside "_build/tailwind-#{target()}"
place it inside "_build/tailwind-#{configured_target()}"
3. Install and use Tailwind from npmJS. See our module documentation
to learn more: https://hexdocs.pm/tailwind
Expand Down Expand Up @@ -363,6 +406,6 @@ defmodule Tailwind do
defp get_url(base_url) do
base_url
|> String.replace("$version", configured_version())
|> String.replace("$target", target())
|> String.replace("$target", configured_target())
end
end

0 comments on commit 27ad86f

Please sign in to comment.