has_lib.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. const query = process.argv[2]
  2. const fs = require('fs')
  3. const childProcess = require('child_process')
  4. const SYSTEM_PATHS = [
  5. '/lib',
  6. '/usr/lib',
  7. '/usr/lib64',
  8. '/usr/local/lib',
  9. '/opt/local/lib',
  10. '/opt/homebrew/lib',
  11. '/usr/lib/x86_64-linux-gnu',
  12. '/usr/lib/i386-linux-gnu',
  13. '/usr/lib/arm-linux-gnueabihf',
  14. '/usr/lib/arm-linux-gnueabi',
  15. '/usr/lib/aarch64-linux-gnu'
  16. ]
  17. /**
  18. * Checks for lib using ldconfig if present, or searching SYSTEM_PATHS
  19. * otherwise.
  20. * @param {string} lib - library name, e.g. 'jpeg' in 'libjpeg64.so' (see first line)
  21. * @return {boolean} exists
  22. */
  23. function hasSystemLib (lib) {
  24. const libName = 'lib' + lib + '.+(so|dylib)'
  25. const libNameRegex = new RegExp(libName)
  26. // Try using ldconfig on linux systems
  27. if (hasLdconfig()) {
  28. try {
  29. if (childProcess.execSync('ldconfig -p 2>/dev/null | grep -E "' + libName + '"').length) {
  30. return true
  31. }
  32. } catch (err) {
  33. // noop -- proceed to other search methods
  34. }
  35. }
  36. // Try checking common library locations
  37. return SYSTEM_PATHS.some(function (systemPath) {
  38. try {
  39. const dirListing = fs.readdirSync(systemPath)
  40. return dirListing.some(function (file) {
  41. return libNameRegex.test(file)
  42. })
  43. } catch (err) {
  44. return false
  45. }
  46. })
  47. }
  48. /**
  49. * Checks for ldconfig on the path and /sbin
  50. * @return {boolean} exists
  51. */
  52. function hasLdconfig () {
  53. try {
  54. // Add /sbin to path as ldconfig is located there on some systems -- e.g.
  55. // Debian (and it can still be used by unprivileged users):
  56. childProcess.execSync('export PATH="$PATH:/sbin"')
  57. process.env.PATH = '...'
  58. // execSync throws on nonzero exit
  59. childProcess.execSync('hash ldconfig 2>/dev/null')
  60. return true
  61. } catch (err) {
  62. return false
  63. }
  64. }
  65. /**
  66. * Checks for freetype2 with --cflags-only-I
  67. * @return Boolean exists
  68. */
  69. function hasFreetype () {
  70. try {
  71. if (childProcess.execSync('pkg-config cairo --cflags-only-I 2>/dev/null | grep freetype2').length) {
  72. return true
  73. }
  74. } catch (err) {
  75. // noop
  76. }
  77. return false
  78. }
  79. /**
  80. * Checks for lib using pkg-config.
  81. * @param {string} lib - library name
  82. * @return {boolean} exists
  83. */
  84. function hasPkgconfigLib (lib) {
  85. try {
  86. // execSync throws on nonzero exit
  87. childProcess.execSync('pkg-config --exists "' + lib + '" 2>/dev/null')
  88. return true
  89. } catch (err) {
  90. return false
  91. }
  92. }
  93. function main (query) {
  94. switch (query) {
  95. case 'gif':
  96. case 'cairo':
  97. return hasSystemLib(query)
  98. case 'pango':
  99. return hasPkgconfigLib(query)
  100. case 'freetype':
  101. return hasFreetype()
  102. case 'jpeg':
  103. return hasPkgconfigLib('libjpeg')
  104. case 'rsvg':
  105. return hasPkgconfigLib('librsvg-2.0')
  106. default:
  107. throw new Error('Unknown library: ' + query)
  108. }
  109. }
  110. process.stdout.write(main(query).toString())