1 pontos por GN⁺ 5 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Em alinhamento com o fluxo em que o build.zig e o sistema de build do Zig são separados em processos distintos, a lógica de gerenciamento de pacotes foi movida para o processo maker, fora do executável do compilador
  • Com zig build, zig fetch, zig init e zig libc migrando para o lado do maker, o código de tratamento de HTTP, TLS, Git, compressão e build.zig.zon passa a ser distribuído em forma de código-fonte
  • Nessa estrutura, é possível corrigir funções de gerenciamento de pacotes sem recompilar o compilador, e o maker é compilado em ReleaseSafe, ativando também as verificações de segurança em operações de rede
  • O objetivo original é expor o build server protocol para resolver o problema da mudança em --build-runner que bloqueava o ZLS; na nova árvore de processos, o maker permanece como pai do configurer e consegue lidar de forma mais estável com reexecuções de configuração
  • O impacto para usuários não é grande, mas o executável do Zig diminui 4%, de 14,1 MiB para 13,5 MiB, e --maker-opt e --zig-lib-dir são substituídos, respectivamente, pelas variáveis de ambiente ZIG_DEBUG_MAKER e ZIG_LIB_DIR

Migração da lógica de gerenciamento de pacotes

  • Depois que o script build.zig do usuário e o próprio sistema de build foram separados em processos distintos, o Zig mudou para uma estrutura em que a lógica de gerenciamento de pacotes também fica do lado do sistema de build
  • Os subcomandos movidos para o processo maker são os seguintes
    • zig build
    • zig fetch
    • zig init
    • zig libc

Código removido do executável do compilador

  • Grandes áreas de código que antes ficavam dentro do executável do compilador agora são distribuídas em forma de código-fonte
    • Lógica de obtenção de pacotes
    • Cliente HTTP e networking
    • TLS e criptografia relacionada
    • Protocolo Git
    • xz, gzip, zstd, flate, zip
    • Parsing, validação e outros tratamentos de arquivos build.zig.zon
  • Esses recursos podem ser corrigidos sem recompilar o compilador, facilitando experimentos para usuários e contribuidores
  • O executável maker é compilado no modo ReleaseSafe, então as verificações de segurança ficam ativadas nas operações de rede do gerenciamento de pacotes
  • O código criptográfico usado em networking e hashing de arquivos pode aproveitar instruções especiais de CPU disponíveis no host

Estrutura de processos e build server

  • A motivação original era expor o build server protocol para resolver o problema que bloqueava o ZLS
  • Na estrutura anterior, zig build cuidava ao mesmo tempo do compilador e do gerenciador de pacotes, enquanto o builder abaixo dele continha a lógica do build.zig do usuário e a implementação do sistema de build
  • Após a separação entre maker/configurer, a estrutura ficou assim
    • zig build: compilador + gerenciador de pacotes
    • configurer: lógica do build.zig do usuário
    • maker: sistema de build
  • Nessa estrutura, um zig build --watch de longa duração precisava reexecutar o configurer quando detectava alterações no build.zig ou em arquivos relacionados; para isso, o maker precisava encerrar para dar ao zig build a chance de repetir a lógica de gerenciamento de pacotes
  • Na nova estrutura, zig build cuida apenas do compilador, enquanto o maker abaixo dele fica responsável pelo sistema de build e pelo gerenciador de pacotes, e o configurer passa a ser um processo filho do maker
  • Mesmo quando for necessário reexecutar a configuração, o maker pode continuar vivo como processo pai
  • No build server planejado, em vez de o cliente se reconectar após o servidor encerrar, passa a ser possível uma estrutura que notifica o cliente sobre mudanças de configuração

Mudanças observáveis

  • A maior parte não é incompatível, mas há diferenças visíveis para usuários
    • Tamanho do binário executável do Zig: em ReleaseSmall sem LLVM, reduz de 14,1 MiB para 13,5 MiB, uma redução de 4%
    • A flag --maker-opt é substituída pela variável de ambiente ZIG_DEBUG_MAKER
    • A flag --zig-lib-dir é substituída pela variável de ambiente ZIG_LIB_DIR

Issues bloqueadoras restantes antes do Zig 0.17.0

1 comentários

 
GN⁺ 5 시간 전
Comentários do Hacker News
  • Desenvolvedores de Zig, Go e Python às vezes anunciam que removeram o líquido de arrefecimento do tanque de combustível, e os apoiadores comemoram dizendo que isso será bom para a linguagem e que o desempenho vai melhorar muito
    Mas fico ainda mais curioso sobre por que o líquido de arrefecimento foi parar no tanque de combustível em primeiro lugar

    • No início de projetos assim, é fácil a conveniência de desenvolvedores individuais ter prioridade sobre uma reflexão profunda sobre as consequências do design
      Colocar o gerenciamento de pacotes dentro do compilador era conveniente, mas, quando a linguagem e as ferramentas começam a ser amplamente usadas, um recurso que era vantajoso para uma pessoa vira uma dívida que impede a adoção
      Em muitos projetos, os desenvolvedores escolhem o caminho conveniente para evitar “o trabalho difícil necessário para fazer direito”, e, como os outros também não querem fazer esse trabalho difícil, aquilo acaba virando prática comum
    • Também há uma lógica defensável aqui
      Se você quer implementar um gerenciador de pacotes dentro do sistema de build e também mantê-lo no compilador, primeiro precisa decidir que abstração colocar entre o compilador e o sistema de build
      Isso também afeta o sistema de import e partes fundamentais da linguagem; essas partes precisam ser bem projetadas e também são difíceis de mudar depois
      No começo, pode ter menos impacto para os usuários acoplar fortemente o gerenciamento de pacotes ao compilador, projetar de trás para frente a partir da experiência de programador desejada e só depois mudar a implementação
      Em especial, acho que o sistema de import do Python ficou muito complexo e cheio de falhas por ter precisado acomodar várias formas de gerenciamento de pacotes
      Já Go foi projetada desde o início levando o gerenciamento de pacotes em conta, então a sintaxe relacionada a imports é relativamente pequena e limpa. Claro, isso não quer dizer que eu concorde com todas as decisões de design
    • Parece que isso soa assim porque você nunca construiu nada
      Mesmo em um produto pequeno, é difícil prever como cada componente vai interagir, então é preciso corrigir as coisas o tempo todo
      Agora imagine fazer uma linguagem alternativa a C que seja self-hosting
    • Tenho exatamente a mesma sensação em relação a desempenho. Não tem a ver com uma linguagem de programação específica nem com as minhas otimizações
      Quanto maior o ganho de velocidade, mais comemoração há, mas a maior parte das otimizações não é uma técnica brilhante; é usar o profiler para descobrir “opa, o líquido de arrefecimento não deveria estar no tanque de combustível”
      A maioria dos gargalos de desempenho não é um limite essencial do hardware nem do próprio problema
      Existe uma quantidade mínima de trabalho necessária para obter o resultado, mas o motivo de uma aplicação ser lenta quase sempre é a tralha acrescentada por cima disso
    • Não conheço Zig nem Python bem o suficiente para julgar, mas em Go nunca tive essa impressão. Não sei quando isso teria acontecido
  • O desenvolvimento do Zig realmente parece ter uma atmosfera saudável

    • Olhar para Zig hoje em dia prova que o craft do desenvolvimento de software não morreu nem foi substituído por LLMs
      Eu uso LLMs todos os dias e reconheço que elas são surpreendentemente boas em vários tipos de problema, mas não quero uma linguagem de programação criada por LLM
      Cada linha de código, decisão e trade-off em uma linguagem de programação importa
      Uma linguagem projetada e codificada só no “feeling” seria um desastre
      Nenhum modelo jamais me mostrou código que me convencesse do contrário. Mesmo o Fable, embora claramente melhor que os melhores modelos anteriores, continua igual nesse ponto
      O modelo não quer nada, não tem opiniões significativas e não sabe o que é conforto ou desconforto em uma linguagem. O mesmo vale para interfaces GUI ou CLI suficientemente complexas
      Uma linguagem como Zig não poderia sair de uma LLM a menos que ela simplesmente copiasse Zig; e, mesmo copiando, seria uma cópia pior
      Aqui, copiar com LLM não significa fazer literalmente cp da árvore de código-fonte, mas sim a LLM escrever a especificação e outra LLM implementar a linguagem conforme essa especificação
    • Também é bem divertido construir coisas com Zig
      Fiz um bootloader e trabalhei com UEFI, e pessoalmente achei muito mais fácil do que em C
      Dito isso, também há o viés de estar aprendendo algo novo e brilhante, o que aumenta bastante a empolgação
  • Fico me perguntando se esta é a mudança que fez o Zig remover @cImport e movê-lo para o sistema de build
    É puramente uma questão de experiência do usuário, e entendo que separar o sistema de build do compilador é importante para os mantenedores, mas ainda assim é um pouco decepcionante que a estabilidade de desenvolvimento venha antes da experiência do usuário
    É a decisão correta, mas triste; considero @cImport um poderoso killer feature da linguagem

    • Não necessariamente
      Esta mudança diz respeito ao código que baixa e descompacta pacotes de terceiros
      A mudança em @cImport fazia parte do trabalho para tornar a dependência de LLVM/libclang do Zig opcional algum dia e, mais tarde, possibilitar movê-la para um pacote de terceiros, mas não parece diretamente relacionada
  • Li em algum lugar que o objetivo de longo prazo é mover o sistema de build para dentro de uma VM WebAssembly
    Se for isso mesmo, é algo impressionante

    • Fico curioso sobre qual seria a vantagem disso no build
  • É uma boa mudança para Zig
    Tenho bastante vontade de migrar de Go para Zig, mas, por enquanto, também estou gostando de acompanhar de fora

    • Dependendo do caso de uso, você pode usar as duas, e talvez até deva
  • Toda vez que uma linguagem cria seu próprio sistema de pacotes, só consigo pensar que perdemos alguma grande oportunidade
    A única exceção é C/C++, em que, para o bem ou para o mal, nada se consolidou o suficiente
    Esse tipo de escolha pode criar processos muito complexos quando, mais tarde, for preciso misturar várias linguagens
    Sistemas de empacotamento tornam as coisas mais fáceis, mas, no momento em que você precisa usar outra linguagem, tornam o restante do processo mais complexo

    • Fico curioso sobre o que você acha que perdemos
      Você quer um único sistema de build para todas as linguagens? Existem sistemas como Bazel, e eles são usados com frequência em projetos multilíngues, mas, na prática, parece ter ficado provado que sistemas de build com conhecimento específico da linguagem são muito mais fáceis de lidar
    • Acho que é até bom C++ não ter um sistema de empacotamento padronizado
      Porque isso faz pensar com cuidado antes de adicionar uma dependência
      Dependências desse tipo muitas vezes têm custos ocultos, como vulnerabilidades de segurança
      Como uma quantidade considerável de sistemas importantes é escrita em C++, depender de dezenas de pacotes de terceiros facilmente acessíveis sem auditar direito cada um deles é arriscado demais
    • C deveria ter corrigido vários problemas e adicionado um gerenciador de pacotes, ou reconhecido oficialmente algum
      Zig está preenchendo esse vazio
    • O mundo ainda não conseguiu padronizar um bom sistema de build multiplataforma e multilíngue
      Na prática, os únicos sistemas desse tipo são Buck e Bazel, mas ambos trazem bagagem demais das grandes organizações por trás deles
      É uma pena
    • Conan e vcpkg estão suficientemente consolidados
  • A separação de responsabilidades foi feita de um jeito muito convincente