Ninja: Toneladas de avisos de inclusão de arquivo ao compilar com a versão chinesa do Visual Studio 2010

Criado em 5 jul. 2013  ·  32Comentários  ·  Fonte: ninja-build/ninja

Ao construir o chromium com ninja com a versão chinesa do Visual Studio 2010, a janela do console gera toneladas de avisos de arquivo de inclusão e, portanto, retarda muito o processo de construção. O aviso é como:

注意 : 包含 文件 : incluir o caminho do arquivo

O equivalente em inglês é:
Nota: incluindo arquivo: .....

Talvez o ninja esteja removendo os avisos de inclusão baseados apenas nas palavras em inglês.

bug windows

Comentários muito úteis

Com um local francês, ninja 1.8.2 e CMake 3.10.2, isso ainda acontece ...

Todos 32 comentários

Em uma instalação em inglês, "Observação: incluindo arquivo:% s% s \ n" aparece como recurso na tabela de strings em VC \ bin \ 1033 \ clui.dll.

1033 é o identificador de localidade para "Inglês (Estados Unidos)".

Não estou ciente de nenhuma opção de linha de comando para forçar cl no local 1033, infelizmente. Presumo que, se vários locais estiverem instalados, ele usará as configurações do sistema para determinar qual usar.

Portanto, acho que teríamos que adicionar vários idiomas à pesquisa de prefixo no analisador / showIncludes. : /

Acho que cmcldeps (o analisador CMake desta saída) usa um regex, algo como "[^:] +: [^:] +: (. *)", Para capturar todas as linhas de saída que se parecem com a saída showincludes. Eu não olhei muito para o código porque eventualmente gostaria de implementar algo assim e não quero violar nenhum direito autoral. :)

A parte complicada é não confundir a saída showincludes com avisos. sfcheng, você poderia colar a saída em chinês do Visual Studio cl.exe ao mostrar um aviso ou mensagem de erro?

Parece que: não é ascii 58, então isso pode adicionar uma ruga. Talvez o número da linha "(\ d +)" que estará com erros possa ser um sinal útil.

Não estou ciente de nenhuma opção de linha de comando para forçar cl no local 1033, infelizmente.

Infelizmente, não existe uma maneira (limpa) de fazer isso. Versões em idioma estrangeiro do VS teriam outros recursos de localidade em número diferente (por exemplo, 1041 para JA).
O que aprendemos: sempre instale a versão EN do VS e, em seguida, instale o pacote de idiomas, se necessário :(

Mas, felizmente, "error Cnnnn" e "warning Cnnnn" nunca são localizados. Portanto, podemos usá-los como chave. Mas, como disse @sgraham , os números das linhas parecem mais promissores porque também permitiriam filtrar a saída 'note:'.

Não tenho certeza se: não são ascii 58. Na versão japonesa, certamente são ascii 58.

FWIW, a saída em japonês seria assim:

C:\cygwin\home\oku>type main.c
#include <stdio.h>
int nah(void){}; /* Trigger "function must return a value */
main(){return nah();}

C:\cygwin\home\oku>cl /showIncludes main.c
Microsoft(R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.c
メモ: インクルード ファイル:  C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h
メモ: インクルード ファイル:   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\crtdefs.h
メモ: インクルード ファイル:    C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\sal.h
メモ: インクルード ファイル:     c:\program files (x86)\microsoft visual studio10.0\vc\include\codeanalysis\sourceannotations.h
メモ: インクルード ファイル:    C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\vadefs.h
メモ: インクルード ファイル:   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\swprintf.inl
c:\cygwin\home\oku\main.c(2) : warning C4716: 'nah' : 値を返さなければいけません

Arte relacionada: https://bugzilla.mozilla.org/show_bug.cgi?id=587372 (abordagem lá: leia o prefixo de um env var, tenha uma verificação de autoconf para verificar / showInclui trabalhos de análise. Não ótimo.)

Ideia semelhante ao bug do mozilla: pode haver um var msvs_includes_prefix , e os geradores podem escrever isso compilando um arquivo fictício #include "knownheader.h" com / showIncludes e escrevendo o que estiver na frente de "knownheader.h "na saída cl.exe para essa var de nível superior. O Ninja então usaria msvs_includes_prefix como o prefixo / showIncludes.

Enquanto o CMake configura, o prefixo include é lido a partir de uma construção fictícia
https://github.com/Kitware/CMake/blob/master/Modules/CMakeClDeps.cmake
onde um regex é usado, posteriormente o prefixo é passado como argumento para a ferramenta,
https://github.com/Kitware/CMake/blob/master/Source/cmcldeps.cxx
e std :: string :: substr é usado para processar a saída cl.exe.

Presumo que o ninja também precise aceitar um argumento adicional (global).
(como o nico sugerido)

O CMake também usa cmcldeps para gerar dependências para arquivos .rc, primeiro "compilando" o arquivo .rc com cl que gera o arquivo de dependência e, em seguida, o processa com a ferramenta rc.
Não tenho certeza se ou como isso poderia ser integrado ao ninja.

https://github.com/martine/ninja/pull/665

Isso funciona com prefixos não ASCII?

665 é mesclado. Podemos ter que iterar um pouco sobre os problemas de codificação ainda, portanto, deixe isso em aberto até que seja verificado o funcionamento.

Com um local francês, ninja 1.8.2 e CMake 3.10.2, isso ainda acontece ...

665 adicionou msvc_deps_prefix. O cmake define isso? @syntheticpp @mathstuf

@nico vejo um código no CMake que faz referência a ele.

Ainda acontecendo na Comunidade do Visual Studio 15.9.7 ...

Para registro, isso ainda está acontecendo comigo com a seguinte configuração:
CMake 3.14
Ninja 1.8.2 (aquele que acompanha o Visual Studio 2019)
Localidade francesa.

EDIT: Melhor solução alternativa: defina VSLANG=1033 no ambiente para forçar o CL a gerar mensagens em inglês.

Antiga solução alternativa:
E para aqueles que também tiveram esse problema, minha solução alternativa foi comentar a seguinte linha em $CMAKE_PATH\share\cmake-3.14\Modules\Platform\Windows-MSVC.cmake :
#set(CMAKE_NINJA_DEPTYPE_${lang} msvc) (linha 368 na minha)

Isso infelizmente faz com que o CMake gere deps = gcc vez de apenas remover a linha deps, mas isso não pareceu quebrar minhas compilações. YMMV. Esta é uma solução alternativa.

Definir deps = gcc provavelmente é benigno sem definir depfile também.

@DrFrankenstein Você estaria disposto a tentar reproduzir isso depois de aplicar este PR à base de código ninja? https://github.com/ninja-build/ninja/pull/1671

Vou tentar esta semana!

Infelizmente, isso não resolveu.

Eu construí o ninja a partir dessa ramificação, então usei essa versão do ninja para construir a si mesmo novamente, e ele ainda vazou as mensagens de inclusão para o terminal.
image

Parece-me que o problema aqui pode ser com o manipulador de inclusão do MSVC.

A gramática para isso não reconhece a saída de cl.exe corretamente?

Nós vamos...

Parece que é um problema com o inglês codificado.

https://github.com/ninja-build/ninja/blob/master/src/clparser.cc

string CLParser::FilterShowIncludes(const string& line,
                                    const string& deps_prefix) {
  const string kDepsPrefixEnglish = "Note: including file: ";
  const char* in = line.c_str();
  const char* end = in + line.size();
  const string& prefix = deps_prefix.empty() ? kDepsPrefixEnglish : deps_prefix;
  if (end - in > (int)prefix.size() &&
      memcmp(in, prefix.c_str(), (int)prefix.size()) == 0) {
    in += prefix.size();
    while (*in == ' ')
      ++in;
    return line.substr(in - line.c_str());
  }
  return "";
}

@DrFrankenstein

Você gostaria de mexer com aquele prefixo em inglês no topo da função para ver se ele funciona melhor?

Ha! Na verdade, eu ia dar uma olhada lá amanhã. Parece que você pegou antes que eu tivesse a chance.

Acabei de desligar meu computador durante a noite. Volto para você amanhã!

É importante notar, porém, que deps_prefix deve conter a string localizada conforme definido no arquivo rules.ninja (geralmente detectado e definido pelo CMake). Ele só usa o codificado se estiver ausente.

Suspeito que a lógica logo após pode ser a verdadeira culpada. Mas, como eu disse, farei uma investigação / sessão de depuração adequada amanhã.

As codificações não correspondem. deps_prefix está em Latin-1 (onde o NBSP antes dos dois pontos é 0xA0), e line está em CP437 por algum motivo (NBSP = 0xFF).
image

Acho que o próprio CL está gerando CP437, mas o rules.ninja gerado pelo CMake está em Latin-1. Eu estou supondo que alguma conversão ocorreu no lado do CMake, mas isso vai requerer mais escavações.

EDITAR: Parece que o CL terá saída em qualquer página de código do console. ( Fonte 1 , Fonte 2 ). Não tenho certeza de como podemos forçá-lo a ser outra coisa.

Talvez possamos unir os dois convertendo-os em uma codificação comum, como UTF-8 (ou qualquer outra que o Ninja prefira usar), por exemplo, chamando MultiByteToWideChar(CP_OEMCP, ...) na saída CL e MultiByteToWideChar(1252, ...) na string que vem de rules.ninja.

Pensando nisso ... isso pode ser culpa do CMake. No Windows, o comando execute_process parece converter a saída do comando em UTF-8 internamente (e aceita um parâmetro ENCODING opcional para especificar a codificação da saída). Portanto, ele grava de volta em UTF-8 no arquivo rules.ninja (onde NBSP é 0xA0 e não 0xFF).

Eu tentei mudar CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX para usar ENCODING NONE (não realizar nenhuma conversão), mas pareceu quebrar todos os tipos de coisas no CMake.

Portanto, a pergunta que estou tendo agora é ... o msvc_deps_prefix do ninja deve ser uma correspondência bit a bit com a saída do compilador ou deve estar em qualquer codificação que o arquivo deve ter, caso em que seria o do Ninja trabalho para fazer as conversões adequadas da saída do compilador?

@bradking Reflexões sobre a codificação e detecção de prefixo aqui?

Historicamente, o ninja tem uma codificação agnóstica (desde que a codificação use o mesmo byte que ASCII para '/'). No entanto, o Windows pode tornar isso difícil.

O CLParser::FilterShowIncludes do Ninja está usando memcmp para comparar msvc_deps_prefix às linhas na saída do MSVC, então, de fato, o valor precisa ser uma correspondência bit a bit. O CMake pode precisar de algum trabalho para preservá-lo. O CMake atualmente converte para UTF-8 internamente, então talvez tudo o que está faltando seja a conversão de volta para a codificação da página de código ao gravar o valor em build.ninja .

A codificação de saída do IIRC, MSVC, pode ser afetada por variáveis ​​de ambiente e / ou sinalizadores. Isso significa que podemos acabar com a saída do compilador em uma codificação diferente da página de código na qual o Ninja está operando e usando para interpretar strings em build.ninja . Esses casos podem exigir suporte extra do Ninja para lidar, mas uma investigação mais aprofundada seria necessária.

Não consegui encontrar nenhuma variável de ambiente afetando a página de código usada pelo CL. Eu acho que ele usa apenas a página de código associada ao processo (que é baseada nas configurações regionais do sistema, ou pelas configurações do console se o processo estiver rodando em um).

No entanto, _is_ uma variável de ambiente que define a linguagem usada pelo CL, VSLANG , que pode ser útil como uma solução alternativa para usuários afetados por este bug. Definir VSLANG=1033 antes de gerar os arquivos ninja impedirá que o bug aconteça.

Apenas para reafirmar meu comentário acima em palavras diferentes: o Ninja trata seus arquivos de entrada como bytes (sem codificação) e faz comparações de strings de bytes sem codificação, para tentar evitar esses problemas. Você precisa dos bytes que aparecem no arquivo build.ninja para corresponder aos bytes que o ninja lê no processo stdout, mas o ninja não se preocupa com as codificações.

Depois de CMake gerar todos os arquivos de construção, eu converti manualmente rules.ninja em UTF-8 que contém uma linha msvc_deps_prefix = 注意: 包含文件: , e então as coisas foram corrigidas. (Esse arquivo costumava estar na codificação GB2312, que corresponde à página de código 936 padrão). Eu acho que mudanças podem ser feitas no CMake para que sempre converta rules.ninja em UTF-8?

Não tenho experiência em trabalhar com localidades diferentes da página de código 936 ou 65001, portanto, não tenho ideia se a solução acima é uma correção universal.

Mesmo problema e consegue apagar esta saída com add / W2 em vez de / W3 em CMAKE_CXX_FLAGS

Isso está relacionado a # 1766

Esta página foi útil?
0 / 5 - 0 avaliações