aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014-2017, 2019-2021, 2023-2024 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2023 Janneke Nieuwenhuizen <jannek@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu system locale)
  #:use-module (guix gexp)
  #:use-module (guix store)
  #:use-module (guix modules)
  #:use-module (guix records)
  #:use-module (guix packages)
  #:use-module (guix utils)
  #:use-module (gnu packages base)
  #:use-module (gnu packages compression)
  #:use-module (srfi srfi-26)
  #:use-module (ice-9 match)
  #:export (locale-definition
            locale-definition?
            locale-definition-name
            locale-definition-source
            locale-definition-charset

            locale-name->definition
            locale-directory

            %default-locale-libcs
            %default-locale-definitions

            glibc-supported-locales))

;;; Commentary:
;;;
;;; Locale definitions, and compilation thereof.
;;;
;;; Code:

(define-record-type* <locale-definition> locale-definition
  make-locale-definition
  locale-definition?
  (name    locale-definition-name)                ;string--e.g., "fr_FR.utf8"
  (source  locale-definition-source)              ;string--e.g., "fr_FR"
  (charset locale-definition-charset              ;string--e.g., "UTF-8"
           (default "UTF-8")))

(define %not-dot
  (char-set-complement (char-set #\.)))

(define (denormalize-codeset codeset)
  "Attempt to guess the \"real\" name of CODESET, a normalized codeset as
defined in (info \"(libc) Using gettextized software\")."
  (cond ((string=? codeset "utf8")
         "UTF-8")
        ((string-prefix? "iso8859" codeset)
         (string-append "ISO-8859-" (string-drop codeset 7)))
        ((string=? codeset "eucjp")
         "EUC-JP")
        (else                                ;cross fingers, hope for the best
         codeset)))

(define (locale-name->definition name)
  "Return a <locale-definition> corresponding to NAME, guessing the charset,
or #f on failure."
  (match (string-tokenize name %not-dot)
    ((source charset)
     ;; XXX: NAME is supposed to use the "normalized codeset", such as "utf8",
     ;; whereas the actual name used is different.  Add a special case to make
     ;; the right guess for UTF-8.
     (locale-definition (name name)
                        (source source)
                        (charset (denormalize-codeset charset))))
    (_
     #f)))

(define* (single-locale-directory locales
                                  #:key (libc glibc))
  "Return a directory containing all of LOCALES for LIBC compiled.

Because locale data formats are incompatible when switching from one libc to
another, locale data is put in a sub-directory named after the 'version' field
of LIBC."
  (define version
    (version-major+minor (package-version libc)))

  (define build
    (with-imported-modules (source-module-closure
                            '((gnu build locale)))
     #~(begin
         (use-modules (gnu build locale))

         (mkdir #$output)
         (mkdir (string-append #$output "/" #$version))

         ;; 'localedef' executes 'gzip' to access compressed locale sources.
         (setenv "PATH"
                 (string-append #+gzip "/bin:" #+libc "/bin"))

         (setvbuf (current-output-port) 'line)
         (setvbuf (current-error-port) 'line)
         (for-each (lambda (locale codeset name)
                     (build-locale locale
                                   #:codeset codeset
                                   #:name name
                                   #:directory
                                   (string-append #$output "/" #$version)))
                   '#$(map locale-definition-source locales)
                   '#$(map locale-definition-charset locales)
                   '#$(map locale-definition-name locales)))))

  (computed-file (string-append "locale-" version) build))

(define* (locale-directory locales
                           #:key (libcs %default-locale-libcs))
  "Return a locale directory containing all of LOCALES for each libc package
listed in LIBCS.

It is useful to list more than one libc when willing to support
already-installed packages built against a different libc since the locale
data format changes between libc versions."
  (match libcs
    ((libc)
     (single-locale-directory locales #:libc libc))
    ((libcs ..1)
     (let ((dirs (map (lambda (libc)
                        (single-locale-directory locales #:libc libc))
                      libcs)))
       (computed-file "locale-multiple-versions"
                      (with-imported-modules '((guix build union))
                        #~(begin
                            (use-modules (guix build union))
                            (union-build #$output (list #$@dirs))))
                      #:options '(#:local-build? #t
                                  #:substitutable? #f))))))

(define %default-locale-libcs
  ;; The libcs for which we build locales by default.
  (list glibc glibc-2.35))

(define %default-locale-definitions
  ;; Arbitrary set of locales that are built by default.  They come as a
  ;; "bonus" in addition to that specified in the 'locale' field of the
  ;; operating system, for the user's convenience, so they shouldn't take too
  ;; much space.
  (letrec-syntax ((utf8-locale (syntax-rules ()
                                 ((_ name*)
                                  (locale-definition
                                   ;; Note: We choose "utf8", which is the
                                   ;; "normalized codeset".
                                   (name (string-append name* ".utf8"))
                                   (source name*)
                                   (charset "UTF-8")))))
                  (utf8-locales (syntax-rules ()
                                  ((_ name ...)
                                   (list (utf8-locale name) ...)))))
    ;; The six UN official languages plus Portuguese, with at most two
    ;; variants per language.
    (utf8-locales "ar_DZ"
                  "en_GB"
                  "en_US"
                  "es_AR"
                  "es_ES"
                  "fr_FR"
                  "pt_BR"
                  "pt_PT"
                  "ru_RU"
                  "zh_CN")))


;;;
;;; Locales supported by glibc.
;;;

(define* (glibc-supported-locales #:optional (glibc glibc))
  "Return a file-like object that contains a list of locale name/encoding
pairs such as (\"oc_FR.UTF-8\" . \"UTF-8\").  Each pair corresponds to a
locale supported by GLIBC."
  (define build
    (with-imported-modules (source-module-closure
                            '((guix build gnu-build-system)
                              (gnu build locale)))
      #~(begin
          (use-modules (guix build gnu-build-system)
                       (gnu build locale)
                       (ice-9 pretty-print))

          (define unpack
            (assq-ref %standard-phases 'unpack))


          (setenv "PATH"
                  (string-append #+(file-append tar "/bin") ":"
                                 #+(file-append zstd "/bin") ":"
                                 #+(file-append gzip "/bin")))
          (unpack #:source #+(package-source glibc))

          (let ((locales (call-with-input-file "localedata/SUPPORTED"
                           read-supported-locales)))
            (call-with-output-file #$output
              (lambda (port)
                (pretty-print locales port)))))))

  (computed-file "glibc-supported-locales.scm" build))

;;; locale.scm ends here
k?id=ea0a06cee2ba05451f94714a4f913db02efbe92c'>Remove 'guix-register' and its traces....* Makefile.am (SH_TESTS): Remove tests/guix-register.sh. * build-aux/pre-inst-env.in (GUIX_REGISTER): Remove. * gnu/build/install.scm (directives): Remove outdated comment. * gnu/build/vm.scm (root-partition-initializer): Update comment. * gnu/packages/package-management.scm (guix-register): Remove. * guix/config.scm.in (%sbindir, %guix-register-program): Remove. * guix/scripts/system.scm (install): Adjust docstring. * guix/self.scm (make-config.scm): Remove #:guix. Do not generate %sbindir and %guix-register-program. (specification->package): Remove "guix". * nix/guix-register/guix-register.cc: Remove. * nix/libstore/store-api.cc (decodeValidPathInfo): Remove. * nix/libstore/store-api.hh (decodeValidPathInfo): Remove declaration. * nix/local.mk (sbin_PROGRAMS, guix_register_SOURCES) (guix_register_CPPFLAGS, guix_register_LDFLAGS): Remove. * tests/guix-register.sh: Remove. Ludovic Courtès 2018-06-14database: 'with-database' can now initialize new databases....* nix/libstore/schema.sql: Rename to... * guix/store/schema.sql: ... this. * Makefile.am (nobase_dist_guilemodule_DATA): Add it. * nix/local.mk (%D%/libstore/schema.sql.hh): Adjust accordingly. * guix/store/database.scm (sql-schema): New variable. (sqlite-exec, initialize-database, call-with-database): New procedures. (with-database): Rewrite in terms of 'call-with-database'. * tests/store-database.scm ("new database"): New test. * guix/self.scm (compiled-guix)[*core-modules*]: Add 'schema.sql' to #:extra-files. Ludovic Courtès 2018-06-08build: Do not add all of $(BUILT_SOURCES) to $(CLEANFILES)....Reported by Gábor Boskovits <boskovits@gmail.com>. Fixes <https://bugs.gnu.org/31700>. * nix/local.mk (CLEANFILES): Add nothing but schema.sql.hh. Ludovic Courtès 2018-01-07daemon: Make libbz2 an optional dependency....* config-daemon.ac: Don't bail out when libbz2 is missing. Define 'HAVE_LIBBZ2' Automake conditional. * nix/libstore/build.cc: Wrap relevant bits in '#if HAVE_BZLIB_H'. * nix/libstore/globals.cc (Settings::Settings): 'logCompression' defaults to COMPRESSION_GZIP when HAVE_BZLIB_H is false. * nix/libstore/globals.hh (CompressionType): Make 'COMPRESSION_BZIP2' conditional on HAVE_BZLIB_H. * nix/local.mk (guix_register_LDADD, guix_daemon_LDADD): Add -lbz2 only when HAVE_LIBBZ2. * nix/nix-daemon/guix-daemon.cc (parse_opt): Ignore "bzip2" when not HAVE_BZLIB_H. Ludovic Courtès 2018-01-07daemon: Add gzip log compression....* nix/nix-daemon/guix-daemon.cc (GUIX_OPT_LOG_COMPRESSION): New macro. (options): Mark "disable-log-compression" as hidden and add "log-compression". (parse_opt): Handle GUIX_OPT_LOG_COMPRESSION. * nix/libstore/build.cc (DerivationGoal): Add 'gzLogFile'. (openLogFile): Initialize it when 'logCompression' is COMPRESSION_GZIP. (closeLogFile, handleChildOutput): Honor 'gzLogFile'. * nix/libstore/globals.hh (Settings)[compressLog]: Remove. [logCompression]: New field. (CompressionType): New enum. * nix/libstore/globals.cc (Settings::Settings): Initialize it. (update): Remove '_get' call for 'compressLog'. * nix/local.mk (guix_daemon_LDADD, guix_register_LDADD): Add -lz. * guix/store.scm (log-file): Handle '.gz' log files. * tests/guix-daemon.sh: Add test with '--log-compression=gzip'. * doc/guix.texi (Invoking guix-daemon): Adjust accordingly. * config-daemon.ac: Check for libz and zlib.h. Ludovic Courtès 2017-03-06build: Don't embed absolute paths in .service and .conf service files....Otherwise, users will be stuck running an old copy of guix and the guix-daemon if they copy the service files instead of symlinking them. * etc/guix-daemon.conf.in, etc/guix-daemon.service.in, etc/guix-publish.conf.in, etc/guix-publish.service.in: Expand @localstatedir@ instead of @bindir@. * nix/local.mk (etc/guix-%.service, etc/guix-%.conf): Use @localstatedir@ instead of @bindir@. Leo Famulari 2016-12-20build: Delete all the .service and .conf files upon 'make clean'....* nix/local.mk (CLEANFILES): Define to add $(nodist_systemdservice_DATA) and $(nodist_upstartjob_DATA). Ludovic Courtès 2016-12-18build: Fix .service and .conf targets for VPATH builds....* nix/local.mk (etc/guix-%.service, etc/guix-%.conf): Use "$<", not "$(srcdir)/$<". Ludovic Courtès 2016-12-18build: Add 'guix-publish.*.in' to the distribution....This is a followup to 332d7903f52c2bf3741b04ac2d01cd9018b70800. * nix/local.mk (EXTRA_DIST): Add 'guix-service.publish.in' and 'guix-publish.conf.in'. Ludovic Courtès 2016-11-24Add system start-up files for "guix publish"....* .gitignore: add etc/guix-publish.conf and /etc/guix-publish.service. * etc/guix-publish.conf.in: New file. * etc/guix-publish.service.in: New file. * nix/local.mk (etc/guix-%.service, etc/guix-%.conf): Generalized former build-rules for by using patterns. (nodist_systemdservice_DATA): Add etc/guix-publish.service, update comment. (nodist_upstartjob_DATA): Add etc/guix-publish.conf, update comment. * doc/guix.texi (Invoking guix publish): Add description for enabling "guix publish" on host distros using the new files. Hartmut Goebel 2016-11-16daemon: Add "builtin:download" derivation builder....This ensures that 1) the derivation doesn't change when Guix changes; 2) the derivation closure doesn't contain Guix and its dependencies; 3) we don't have to rely on ugly chroot hacks. Adapted from Nix commit 0a2bee307b20411f5b0dda0c662b1f9bb9e0e131. * nix/libstore/build.cc (DerivationGoal::runChild): Add special case for 'isBuiltin(drv)'. Disable chroot when 'isBuiltin(drv)'. * nix/libstore/builtins.cc, nix/libstore/builtins.hh, nix/scripts/download.in, guix/scripts/perform-download.scm: New files. * guix/ui.scm (show-guix-help)[internal?]: Add 'perform-download'. * nix/local.mk (libstore_a_SOURCES): Add builtins.cc. (libstore_headers): Add builtins.hh. (nodist_pkglibexec_SCRIPTS): Add 'scripts/download'. * config-daemon.ac: Emit 'scripts/download'. * Makefile.am (MODULES): Add 'guix/scripts/perform-download.scm'. * tests/derivations.scm ("unknown built-in builder") ("'download' built-in builder") ("'download' built-in builder, invalid hash") ("'download' built-in builder, not found") ("'download' built-in builder, not fixed-output"): New tests. Co-authored-by: Eelco Dolstra <eelco.dolstra@logicblox.com> Ludovic Courtès 2016-10-28daemon: Factor out SQLite handling....* nix/libstore/local-store.cc: Move SQLite code to... * nix/libstore/sqlite.cc, nix/libstore/sqlite.hh: ... here. New files. * nix/local.mk (libstore_a_SOURCES): Add sqlite.cc. (libstore_headers): Add sqlite.hh. Co-authored-by: Ludovic Courtès <ludo@gnu.org> Eelco Dolstra