Skip to content

Commit

Permalink
feat: add asynchronous cc -dumpmachine for libc detection
Browse files Browse the repository at this point in the history
  • Loading branch information
Saghen committed Feb 4, 2025
1 parent beffa19 commit 4ac2c27
Showing 1 changed file with 44 additions and 34 deletions.
78 changes: 44 additions & 34 deletions lua/blink/cmp/fuzzy/download/system.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,47 +26,56 @@ function system.get_info()
return os, arch
end

--- Synchronously gets the system target triple from `cc -dumpmachine`
--- I.e. { 'x86_64', 'pc', 'linux', 'gnu' }
--- @return string[] | nil
function system.get_target_triple()
local success, process = pcall(function()
return vim.system({'cc', '-dumpmachine'}, { text = true }):wait()
end)
if not success or process.code ~= 0 then
vim.notify(
"Failed to determine system target triple using `cc -dumpmachine`. " ..
"Try setting `fuzzy.prebuilt_binaries.force_system_triple`",
vim.log.levels.ERROR,
{ title = 'blink.cmp' }
)
return nil
end
--- Gets the system target triple from `cc -dumpmachine`
--- I.e. 'gnu' | 'musl'
--- @return blink.cmp.Task
function system.get_linux_libc()
return async
.task
-- Check for system libc via `cc -dumpmachine` by default
-- NOTE: adds 1ms to startup time
.new(function(resolve) vim.system({ 'cc', '-dumpmachine' }, { text = true }, resolve) end)
:schedule()
:map(function(process)
--- @cast process vim.SystemCompleted
if process.code ~= 0 then return nil end

-- strip whitespace
local stdout = process.stdout:gsub('%s+', '')
return vim.fn.split(stdout, '-')
-- strip whitespace
local stdout = process.stdout:gsub('%s+', '')
return vim.fn.split(stdout, '-')[4]
end)
-- Fall back to checking for alpine
:map(function(libc)
if libc ~= nil then return libc end

return async.task.new(function(resolve, reject)
vim.uv.fs_stat('/etc/alpine-release', function(err, is_alpine)
if err then return reject(err) end
resolve(is_alpine ~= nil and 'musl' or 'gnu')
end)
end)
end)
end

--- Synchronously determine the system's libc target (on linux)
--- I.e. `'musl'`, `'gnu'`
--- @return string
function system.get_linux_libc()
local target_triple = system.get_target_triple()
if target_triple and target_triple[3] then
return target_triple[3]
function system.get_linux_libc_sync()
local _, process = pcall(function() return vim.system({ 'cc', '-dumpmachine' }, { text = true }):wait() end)
if process and process.code == 0 then
-- strip whitespace
local stdout = process.stdout:gsub('%s+', '')
local triple_parts = vim.fn.split(stdout, '-')
if triple_parts[4] ~= nil then return triple_parts[4] end
end

-- Fall back to checking for alpine
local success, is_alpine = pcall(vim.uv.fs_stat, '/etc/alpine-release')
return (success and is_alpine) and 'musl' or 'gnu'
local _, is_alpine = pcall(function() return vim.uv.fs_stat('/etc/alpine-release') end)
if is_alpine then return 'musl' end
return 'gnu'
end

--- Gets the system triple for the current system
--- I.e. `x86_64-unknown-linux-gnu` or `aarch64-apple-darwin`
--- @return blink.cmp.Task
function system.get_triple()
return async.task.new(function(resolve)
return async.task.new(function(resolve, reject)
if download_config.force_system_triple then return resolve(download_config.force_system_triple) end

local os, arch = system.get_info()
Expand All @@ -75,9 +84,10 @@ function system.get_triple()
if os == 'linux' then
if vim.fn.has('android') == 1 then return resolve(triples.android) end

local libc = system.get_linux_libc()
local triple = triples[arch]
return resolve(triple and type(triple) == 'function' and triple(libc) or triple)
if type(triple) ~= 'function' then return resolve(triple) end

system.get_linux_libc():map(function(libc) return triple(libc) end):map(resolve):catch(reject)
else
return resolve(triples[arch])
end
Expand All @@ -96,9 +106,9 @@ function system.get_triple_sync()
if os == 'linux' then
if vim.fn.has('android') == 1 then return triples.android end

local libc = system.get_linux_libc()
local triple = triples[arch]
return triple and type(triple) == 'function' and triple(libc) or triple
if type(triple) ~= 'function' then return triple end
return triple(system.get_linux_libc_sync())
else
return triples[arch]
end
Expand Down

0 comments on commit 4ac2c27

Please sign in to comment.