mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-04 04:40:56 -06:00
Merge topic 'automoc-using-depfiles'
aebfbcaa46AutoGen: Use depfiles for the XXX_autogen ninja targetsf765fdea03AutoGen: Use moc's feature to output dependenciesf8c505d4b3Add a parser for GCC-style depfiles Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Jan Niklas Hasse <jhasse@bixense.com> Merge-request: !4221
This commit is contained in:
@@ -99,6 +99,7 @@ The following individuals and institutions are among the Contributors:
|
||||
* Sebastian Holtermann <sebholt@xwmw.org>
|
||||
* Stephen Kelly <steveire@gmail.com>
|
||||
* Sylvain Joubert <joubert.sy@gmail.com>
|
||||
* The Qt Company Ltd.
|
||||
* Thomas Sondergaard <ts@medical-insight.com>
|
||||
* Tobias Hunger <tobias.hunger@qt.io>
|
||||
* Todd Gamblin <tgamblin@llnl.gov>
|
||||
|
||||
@@ -26,6 +26,9 @@ See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference.
|
||||
By default :prop_tgt:`AUTOMOC_DEPEND_FILTERS` is initialized from
|
||||
:variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default.
|
||||
|
||||
From Qt 5.15.0 on this variable is ignored as moc is able to output the correct
|
||||
dependencies.
|
||||
|
||||
See the :manual:`cmake-qt(7)` manual for more information on using CMake
|
||||
with Qt.
|
||||
|
||||
|
||||
@@ -134,6 +134,9 @@ set(SRCS
|
||||
LexerParser/cmFortranParser.cxx
|
||||
LexerParser/cmFortranParserTokens.h
|
||||
LexerParser/cmFortranParser.y
|
||||
LexerParser/cmGccDepfileLexer.cxx
|
||||
LexerParser/cmGccDepfileLexer.h
|
||||
LexerParser/cmGccDepfileLexer.in.l
|
||||
LexerParser/cmListFileLexer.c
|
||||
LexerParser/cmListFileLexer.in.l
|
||||
|
||||
@@ -270,6 +273,10 @@ set(SRCS
|
||||
cmFortranParserImpl.cxx
|
||||
cmFSPermissions.cxx
|
||||
cmFSPermissions.h
|
||||
cmGccDepfileLexerHelper.cxx
|
||||
cmGccDepfileLexerHelper.h
|
||||
cmGccDepfileReader.cxx
|
||||
cmGccDepfileReader.h
|
||||
cmGeneratedFileStream.cxx
|
||||
cmGeneratorExpressionContext.cxx
|
||||
cmGeneratorExpressionContext.h
|
||||
|
||||
2
Source/LexerParser/.gitattributes
vendored
2
Source/LexerParser/.gitattributes
vendored
@@ -16,4 +16,6 @@
|
||||
/cmFortranLexer.h generated
|
||||
/cmFortranParser.cxx generated
|
||||
/cmFortranParserTokens.h generated
|
||||
/cmGccDepfileLexer.cxx generated
|
||||
/cmGccDepfileLexer.h generated
|
||||
/cmListFileLexer.c generated
|
||||
|
||||
2210
Source/LexerParser/cmGccDepfileLexer.cxx
Normal file
2210
Source/LexerParser/cmGccDepfileLexer.cxx
Normal file
File diff suppressed because it is too large
Load Diff
687
Source/LexerParser/cmGccDepfileLexer.h
Normal file
687
Source/LexerParser/cmGccDepfileLexer.h
Normal file
@@ -0,0 +1,687 @@
|
||||
#ifndef cmGccDepfile_yyHEADER_H
|
||||
#define cmGccDepfile_yyHEADER_H 1
|
||||
#define cmGccDepfile_yyIN_HEADER 1
|
||||
|
||||
#define FLEXINT_H 1
|
||||
#define YY_INT_ALIGNED short int
|
||||
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 6
|
||||
#define YY_FLEX_SUBMINOR_VERSION 4
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
|
||||
#ifdef yy_create_buffer
|
||||
#define cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_create_buffer cmGccDepfile_yy_create_buffer
|
||||
#endif
|
||||
|
||||
#ifdef yy_delete_buffer
|
||||
#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_delete_buffer cmGccDepfile_yy_delete_buffer
|
||||
#endif
|
||||
|
||||
#ifdef yy_scan_buffer
|
||||
#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_scan_buffer cmGccDepfile_yy_scan_buffer
|
||||
#endif
|
||||
|
||||
#ifdef yy_scan_string
|
||||
#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_scan_string cmGccDepfile_yy_scan_string
|
||||
#endif
|
||||
|
||||
#ifdef yy_scan_bytes
|
||||
#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_scan_bytes cmGccDepfile_yy_scan_bytes
|
||||
#endif
|
||||
|
||||
#ifdef yy_init_buffer
|
||||
#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_init_buffer cmGccDepfile_yy_init_buffer
|
||||
#endif
|
||||
|
||||
#ifdef yy_flush_buffer
|
||||
#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_flush_buffer cmGccDepfile_yy_flush_buffer
|
||||
#endif
|
||||
|
||||
#ifdef yy_load_buffer_state
|
||||
#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state
|
||||
#endif
|
||||
|
||||
#ifdef yy_switch_to_buffer
|
||||
#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
|
||||
#else
|
||||
#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer
|
||||
#endif
|
||||
|
||||
#ifdef yypush_buffer_state
|
||||
#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
|
||||
#else
|
||||
#define yypush_buffer_state cmGccDepfile_yypush_buffer_state
|
||||
#endif
|
||||
|
||||
#ifdef yypop_buffer_state
|
||||
#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
|
||||
#else
|
||||
#define yypop_buffer_state cmGccDepfile_yypop_buffer_state
|
||||
#endif
|
||||
|
||||
#ifdef yyensure_buffer_stack
|
||||
#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack
|
||||
#endif
|
||||
|
||||
#ifdef yylex
|
||||
#define cmGccDepfile_yylex_ALREADY_DEFINED
|
||||
#else
|
||||
#define yylex cmGccDepfile_yylex
|
||||
#endif
|
||||
|
||||
#ifdef yyrestart
|
||||
#define cmGccDepfile_yyrestart_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyrestart cmGccDepfile_yyrestart
|
||||
#endif
|
||||
|
||||
#ifdef yylex_init
|
||||
#define cmGccDepfile_yylex_init_ALREADY_DEFINED
|
||||
#else
|
||||
#define yylex_init cmGccDepfile_yylex_init
|
||||
#endif
|
||||
|
||||
#ifdef yylex_init_extra
|
||||
#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
|
||||
#else
|
||||
#define yylex_init_extra cmGccDepfile_yylex_init_extra
|
||||
#endif
|
||||
|
||||
#ifdef yylex_destroy
|
||||
#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED
|
||||
#else
|
||||
#define yylex_destroy cmGccDepfile_yylex_destroy
|
||||
#endif
|
||||
|
||||
#ifdef yyget_debug
|
||||
#define cmGccDepfile_yyget_debug_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_debug cmGccDepfile_yyget_debug
|
||||
#endif
|
||||
|
||||
#ifdef yyset_debug
|
||||
#define cmGccDepfile_yyset_debug_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyset_debug cmGccDepfile_yyset_debug
|
||||
#endif
|
||||
|
||||
#ifdef yyget_extra
|
||||
#define cmGccDepfile_yyget_extra_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_extra cmGccDepfile_yyget_extra
|
||||
#endif
|
||||
|
||||
#ifdef yyset_extra
|
||||
#define cmGccDepfile_yyset_extra_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyset_extra cmGccDepfile_yyset_extra
|
||||
#endif
|
||||
|
||||
#ifdef yyget_in
|
||||
#define cmGccDepfile_yyget_in_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_in cmGccDepfile_yyget_in
|
||||
#endif
|
||||
|
||||
#ifdef yyset_in
|
||||
#define cmGccDepfile_yyset_in_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyset_in cmGccDepfile_yyset_in
|
||||
#endif
|
||||
|
||||
#ifdef yyget_out
|
||||
#define cmGccDepfile_yyget_out_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_out cmGccDepfile_yyget_out
|
||||
#endif
|
||||
|
||||
#ifdef yyset_out
|
||||
#define cmGccDepfile_yyset_out_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyset_out cmGccDepfile_yyset_out
|
||||
#endif
|
||||
|
||||
#ifdef yyget_leng
|
||||
#define cmGccDepfile_yyget_leng_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_leng cmGccDepfile_yyget_leng
|
||||
#endif
|
||||
|
||||
#ifdef yyget_text
|
||||
#define cmGccDepfile_yyget_text_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_text cmGccDepfile_yyget_text
|
||||
#endif
|
||||
|
||||
#ifdef yyget_lineno
|
||||
#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_lineno cmGccDepfile_yyget_lineno
|
||||
#endif
|
||||
|
||||
#ifdef yyset_lineno
|
||||
#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyset_lineno cmGccDepfile_yyset_lineno
|
||||
#endif
|
||||
|
||||
#ifdef yyget_column
|
||||
#define cmGccDepfile_yyget_column_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyget_column cmGccDepfile_yyget_column
|
||||
#endif
|
||||
|
||||
#ifdef yyset_column
|
||||
#define cmGccDepfile_yyset_column_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyset_column cmGccDepfile_yyset_column
|
||||
#endif
|
||||
|
||||
#ifdef yywrap
|
||||
#define cmGccDepfile_yywrap_ALREADY_DEFINED
|
||||
#else
|
||||
#define yywrap cmGccDepfile_yywrap
|
||||
#endif
|
||||
|
||||
#ifdef yyalloc
|
||||
#define cmGccDepfile_yyalloc_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyalloc cmGccDepfile_yyalloc
|
||||
#endif
|
||||
|
||||
#ifdef yyrealloc
|
||||
#define cmGccDepfile_yyrealloc_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyrealloc cmGccDepfile_yyrealloc
|
||||
#endif
|
||||
|
||||
#ifdef yyfree
|
||||
#define cmGccDepfile_yyfree_ALREADY_DEFINED
|
||||
#else
|
||||
#define yyfree cmGccDepfile_yyfree
|
||||
#endif
|
||||
|
||||
/* First, we deal with platform-specific or compiler-specific issues. */
|
||||
|
||||
/* begin standard C headers. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* end standard C headers. */
|
||||
|
||||
/* flex integer type definitions */
|
||||
|
||||
#ifndef FLEXINT_H
|
||||
#define FLEXINT_H
|
||||
|
||||
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
|
||||
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
*/
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
|
||||
/* Limits of integral types. */
|
||||
#ifndef INT8_MIN
|
||||
#define INT8_MIN (-128)
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
#ifndef INT8_MAX
|
||||
#define INT8_MAX (127)
|
||||
#endif
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX (32767)
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX (255U)
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX (65535U)
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX (~(size_t)0)
|
||||
#endif
|
||||
|
||||
#endif /* ! C99 */
|
||||
|
||||
#endif /* ! FLEXINT_H */
|
||||
|
||||
/* begin standard C++ headers. */
|
||||
|
||||
/* TODO: this is always defined, so inline it */
|
||||
#define yyconst const
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
#define yynoreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
#define yynoreturn
|
||||
#endif
|
||||
|
||||
/* An opaque pointer. */
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
/* For convenience, these vars (plus the bison vars far below)
|
||||
are macros in the reentrant scanner. */
|
||||
#define yyin yyg->yyin_r
|
||||
#define yyout yyg->yyout_r
|
||||
#define yyextra yyg->yyextra_r
|
||||
#define yyleng yyg->yyleng_r
|
||||
#define yytext yyg->yytext_r
|
||||
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
|
||||
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
|
||||
#define yy_flex_debug yyg->yy_flex_debug_r
|
||||
|
||||
/* Size of default input buffer. */
|
||||
#ifndef YY_BUF_SIZE
|
||||
#ifdef __ia64__
|
||||
/* On IA-64, the buffer size is 16k, not 8k.
|
||||
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
|
||||
* Ditto for the __ia64__ case accordingly.
|
||||
*/
|
||||
#define YY_BUF_SIZE 32768
|
||||
#else
|
||||
#define YY_BUF_SIZE 16384
|
||||
#endif /* __ia64__ */
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
#define YY_TYPEDEF_YY_SIZE_T
|
||||
typedef size_t yy_size_t;
|
||||
#endif
|
||||
|
||||
#ifndef YY_STRUCT_YY_BUFFER_STATE
|
||||
#define YY_STRUCT_YY_BUFFER_STATE
|
||||
struct yy_buffer_state
|
||||
{
|
||||
FILE *yy_input_file;
|
||||
|
||||
char *yy_ch_buf; /* input buffer */
|
||||
char *yy_buf_pos; /* current position in input buffer */
|
||||
|
||||
/* Size of input buffer in bytes, not including room for EOB
|
||||
* characters.
|
||||
*/
|
||||
int yy_buf_size;
|
||||
|
||||
/* Number of characters read into yy_ch_buf, not including EOB
|
||||
* characters.
|
||||
*/
|
||||
int yy_n_chars;
|
||||
|
||||
/* Whether we "own" the buffer - i.e., we know we created it,
|
||||
* and can realloc() it to grow it, and should free() it to
|
||||
* delete it.
|
||||
*/
|
||||
int yy_is_our_buffer;
|
||||
|
||||
/* Whether this is an "interactive" input source; if so, and
|
||||
* if we're using stdio for input, then we want to use getc()
|
||||
* instead of fread(), to make sure we stop fetching input after
|
||||
* each newline.
|
||||
*/
|
||||
int yy_is_interactive;
|
||||
|
||||
/* Whether we're considered to be at the beginning of a line.
|
||||
* If so, '^' rules will be active on the next match, otherwise
|
||||
* not.
|
||||
*/
|
||||
int yy_at_bol;
|
||||
|
||||
int yy_bs_lineno; /**< The line count. */
|
||||
int yy_bs_column; /**< The column count. */
|
||||
|
||||
/* Whether to try to fill the input buffer when we reach the
|
||||
* end of it.
|
||||
*/
|
||||
int yy_fill_buffer;
|
||||
|
||||
int yy_buffer_status;
|
||||
|
||||
};
|
||||
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
|
||||
|
||||
void yyrestart ( FILE *input_file , yyscan_t yyscanner );
|
||||
void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
|
||||
void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
|
||||
void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
|
||||
void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
|
||||
void yypop_buffer_state ( yyscan_t yyscanner );
|
||||
|
||||
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
|
||||
|
||||
void *yyalloc ( yy_size_t , yyscan_t yyscanner );
|
||||
void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
|
||||
void yyfree ( void * , yyscan_t yyscanner );
|
||||
|
||||
/* Begin user sect3 */
|
||||
|
||||
#define cmGccDepfile_yywrap(yyscanner) (/*CONSTCOND*/1)
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
#define yytext_ptr yytext_r
|
||||
|
||||
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
|
||||
#define INITIAL 0
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YY_EXTRA_TYPE
|
||||
#define YY_EXTRA_TYPE void *
|
||||
#endif
|
||||
|
||||
int yylex_init (yyscan_t* scanner);
|
||||
|
||||
int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
|
||||
|
||||
/* Accessor methods to globals.
|
||||
These are made visible to non-reentrant scanners for convenience. */
|
||||
|
||||
int yylex_destroy ( yyscan_t yyscanner );
|
||||
|
||||
int yyget_debug ( yyscan_t yyscanner );
|
||||
|
||||
void yyset_debug ( int debug_flag , yyscan_t yyscanner );
|
||||
|
||||
YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
|
||||
|
||||
void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
|
||||
|
||||
FILE *yyget_in ( yyscan_t yyscanner );
|
||||
|
||||
void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
|
||||
|
||||
FILE *yyget_out ( yyscan_t yyscanner );
|
||||
|
||||
void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
|
||||
|
||||
int yyget_leng ( yyscan_t yyscanner );
|
||||
|
||||
char *yyget_text ( yyscan_t yyscanner );
|
||||
|
||||
int yyget_lineno ( yyscan_t yyscanner );
|
||||
|
||||
void yyset_lineno ( int _line_number , yyscan_t yyscanner );
|
||||
|
||||
int yyget_column ( yyscan_t yyscanner );
|
||||
|
||||
void yyset_column ( int _column_no , yyscan_t yyscanner );
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
*/
|
||||
|
||||
#ifndef YY_SKIP_YYWRAP
|
||||
#ifdef __cplusplus
|
||||
extern "C" int yywrap ( yyscan_t yyscanner );
|
||||
#else
|
||||
extern int yywrap ( yyscan_t yyscanner );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef yytext_ptr
|
||||
static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifdef YY_NEED_STRLEN
|
||||
static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_INPUT
|
||||
|
||||
#endif
|
||||
|
||||
/* Amount of stuff to slurp up with each read. */
|
||||
#ifndef YY_READ_BUF_SIZE
|
||||
#ifdef __ia64__
|
||||
/* On IA-64, the buffer size is 16k, not 8k */
|
||||
#define YY_READ_BUF_SIZE 16384
|
||||
#else
|
||||
#define YY_READ_BUF_SIZE 8192
|
||||
#endif /* __ia64__ */
|
||||
#endif
|
||||
|
||||
/* Number of entries by which start-condition stack grows. */
|
||||
#ifndef YY_START_STACK_INCR
|
||||
#define YY_START_STACK_INCR 25
|
||||
#endif
|
||||
|
||||
/* Default declaration of generated scanner - a define so the user can
|
||||
* easily add parameters.
|
||||
*/
|
||||
#ifndef YY_DECL
|
||||
#define YY_DECL_IS_OURS 1
|
||||
|
||||
extern int yylex (yyscan_t yyscanner);
|
||||
|
||||
#define YY_DECL int yylex (yyscan_t yyscanner)
|
||||
#endif /* !YY_DECL */
|
||||
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
#undef YY_NEW_FILE
|
||||
#undef YY_FLUSH_BUFFER
|
||||
#undef yy_set_bol
|
||||
#undef yy_new_buffer
|
||||
#undef yy_set_interactive
|
||||
#undef YY_DO_BEFORE_ACTION
|
||||
|
||||
#ifdef YY_DECL_IS_OURS
|
||||
#undef YY_DECL_IS_OURS
|
||||
#undef YY_DECL
|
||||
#endif
|
||||
|
||||
#ifndef cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
|
||||
#undef yy_create_buffer
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
|
||||
#undef yy_delete_buffer
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
|
||||
#undef yy_scan_buffer
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_scan_string_ALREADY_DEFINED
|
||||
#undef yy_scan_string
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
|
||||
#undef yy_scan_bytes
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
|
||||
#undef yy_init_buffer
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
|
||||
#undef yy_flush_buffer
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
|
||||
#undef yy_load_buffer_state
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
|
||||
#undef yy_switch_to_buffer
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
|
||||
#undef yypush_buffer_state
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
|
||||
#undef yypop_buffer_state
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
|
||||
#undef yyensure_buffer_stack
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yylex_ALREADY_DEFINED
|
||||
#undef yylex
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyrestart_ALREADY_DEFINED
|
||||
#undef yyrestart
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yylex_init_ALREADY_DEFINED
|
||||
#undef yylex_init
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
|
||||
#undef yylex_init_extra
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yylex_destroy_ALREADY_DEFINED
|
||||
#undef yylex_destroy
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_debug_ALREADY_DEFINED
|
||||
#undef yyget_debug
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_debug_ALREADY_DEFINED
|
||||
#undef yyset_debug
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_extra_ALREADY_DEFINED
|
||||
#undef yyget_extra
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_extra_ALREADY_DEFINED
|
||||
#undef yyset_extra
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_in_ALREADY_DEFINED
|
||||
#undef yyget_in
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_in_ALREADY_DEFINED
|
||||
#undef yyset_in
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_out_ALREADY_DEFINED
|
||||
#undef yyget_out
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_out_ALREADY_DEFINED
|
||||
#undef yyset_out
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_leng_ALREADY_DEFINED
|
||||
#undef yyget_leng
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_text_ALREADY_DEFINED
|
||||
#undef yyget_text
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_lineno_ALREADY_DEFINED
|
||||
#undef yyget_lineno
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_lineno_ALREADY_DEFINED
|
||||
#undef yyset_lineno
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_column_ALREADY_DEFINED
|
||||
#undef yyget_column
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_column_ALREADY_DEFINED
|
||||
#undef yyset_column
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yywrap_ALREADY_DEFINED
|
||||
#undef yywrap
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_lval_ALREADY_DEFINED
|
||||
#undef yyget_lval
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_lval_ALREADY_DEFINED
|
||||
#undef yyset_lval
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyget_lloc_ALREADY_DEFINED
|
||||
#undef yyget_lloc
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyset_lloc_ALREADY_DEFINED
|
||||
#undef yyset_lloc
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyalloc_ALREADY_DEFINED
|
||||
#undef yyalloc
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyrealloc_ALREADY_DEFINED
|
||||
#undef yyrealloc
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyfree_ALREADY_DEFINED
|
||||
#undef yyfree
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yytext_ALREADY_DEFINED
|
||||
#undef yytext
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyleng_ALREADY_DEFINED
|
||||
#undef yyleng
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyin_ALREADY_DEFINED
|
||||
#undef yyin
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyout_ALREADY_DEFINED
|
||||
#undef yyout
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yy_flex_debug_ALREADY_DEFINED
|
||||
#undef yy_flex_debug
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yylineno_ALREADY_DEFINED
|
||||
#undef yylineno
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yytables_fload_ALREADY_DEFINED
|
||||
#undef yytables_fload
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yytables_destroy_ALREADY_DEFINED
|
||||
#undef yytables_destroy
|
||||
#endif
|
||||
#ifndef cmGccDepfile_yyTABLES_NAME_ALREADY_DEFINED
|
||||
#undef yyTABLES_NAME
|
||||
#endif
|
||||
|
||||
#undef cmGccDepfile_yyIN_HEADER
|
||||
#endif /* cmGccDepfile_yyHEADER_H */
|
||||
72
Source/LexerParser/cmGccDepfileLexer.in.l
Normal file
72
Source/LexerParser/cmGccDepfileLexer.in.l
Normal file
@@ -0,0 +1,72 @@
|
||||
%{
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
|
||||
/* IWYU pragma: no_forward_declare yyguts_t */
|
||||
|
||||
#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
|
||||
|
||||
#include <cmGccDepfileLexerHelper.h>
|
||||
#include <string>
|
||||
%}
|
||||
|
||||
%option prefix="cmGccDepfile_yy"
|
||||
%option noyywrap
|
||||
%option reentrant
|
||||
%pointer
|
||||
|
||||
WSPACE [ \t]
|
||||
NEWLINE \r?\n
|
||||
|
||||
%%
|
||||
\${2} {
|
||||
// Unescape the dollar sign.
|
||||
yyextra->addToCurrentPath("$");
|
||||
}
|
||||
\\# {
|
||||
// Unescape the hash.
|
||||
yyextra->addToCurrentPath("#");
|
||||
}
|
||||
(\\\\)*\\[ ] {
|
||||
// 2N+1 backslashes plus space -> N backslashes plus space.
|
||||
size_t c = (strlen(yytext) - 1) / 2;
|
||||
std::string s(c, '\\');
|
||||
s.push_back(' ');
|
||||
yyextra->addToCurrentPath(s.c_str());
|
||||
}
|
||||
(\\\\)+[ ] {
|
||||
// 2N backslashes plus space -> 2N backslashes, end of filename.
|
||||
yytext[strlen(yytext) - 1] = 0;
|
||||
yyextra->addToCurrentPath(yytext);
|
||||
yyextra->newDependency();
|
||||
}
|
||||
{WSPACE}*\\{NEWLINE} {
|
||||
// A line continuation ends the current file name.
|
||||
yyextra->newDependency();
|
||||
}
|
||||
{NEWLINE} {
|
||||
// A newline ends the current file name and the current rule.
|
||||
yyextra->newEntry();
|
||||
}
|
||||
:{WSPACE}+ {
|
||||
// A colon followed by space ends the rules and starts a new dependency.
|
||||
yyextra->newDependency();
|
||||
}
|
||||
{WSPACE}+ {
|
||||
// Rules and dependencies are separated by blocks of whitespace.
|
||||
yyextra->newRuleOrDependency();
|
||||
}
|
||||
[a-zA-Z0-9+,/_.~()}{%=@\x5B\x5D!\x80-\xFF-]+ {
|
||||
// Got a span of plain text.
|
||||
yyextra->addToCurrentPath(yytext);
|
||||
}
|
||||
. {
|
||||
// Got an otherwise unmatched character.
|
||||
yyextra->addToCurrentPath(yytext);
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* __clang_analyzer__ */
|
||||
126
Source/cmGccDepfileLexerHelper.cxx
Normal file
126
Source/cmGccDepfileLexerHelper.cxx
Normal file
@@ -0,0 +1,126 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmGccDepfileLexerHelper.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmGccDepfileReaderTypes.h"
|
||||
|
||||
#include "LexerParser/cmGccDepfileLexer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include "cmsys/Encoding.h"
|
||||
#endif
|
||||
|
||||
bool cmGccDepfileLexerHelper::readFile(const char* filePath)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wchar_t* wpath = cmsysEncoding_DupToWide(filePath);
|
||||
FILE* file = _wfopen(wpath, L"rb");
|
||||
free(wpath);
|
||||
#else
|
||||
FILE* file = fopen(filePath, "r");
|
||||
#endif
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
newEntry();
|
||||
yyscan_t scanner;
|
||||
cmGccDepfile_yylex_init(&scanner);
|
||||
cmGccDepfile_yyset_extra(this, scanner);
|
||||
cmGccDepfile_yyrestart(file, scanner);
|
||||
cmGccDepfile_yylex(scanner);
|
||||
cmGccDepfile_yylex_destroy(scanner);
|
||||
sanitizeContent();
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGccDepfileLexerHelper::newEntry()
|
||||
{
|
||||
this->HelperState = State::Rule;
|
||||
this->Content.emplace_back();
|
||||
newRule();
|
||||
}
|
||||
|
||||
void cmGccDepfileLexerHelper::newRule()
|
||||
{
|
||||
auto& entry = this->Content.back();
|
||||
if (entry.rules.empty() || !entry.rules.back().empty()) {
|
||||
entry.rules.emplace_back();
|
||||
}
|
||||
}
|
||||
|
||||
void cmGccDepfileLexerHelper::newDependency()
|
||||
{
|
||||
// printf("NEW DEP\n");
|
||||
this->HelperState = State::Dependency;
|
||||
if (this->Content.back().paths.empty() ||
|
||||
!this->Content.back().paths.back().empty()) {
|
||||
this->Content.back().paths.emplace_back();
|
||||
}
|
||||
}
|
||||
|
||||
void cmGccDepfileLexerHelper::newRuleOrDependency()
|
||||
{
|
||||
if (this->HelperState == State::Rule) {
|
||||
newRule();
|
||||
} else {
|
||||
newDependency();
|
||||
}
|
||||
}
|
||||
|
||||
void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
|
||||
{
|
||||
if (this->Content.empty()) {
|
||||
return;
|
||||
}
|
||||
cmGccStyleDependency* dep = &this->Content.back();
|
||||
std::string* dst = nullptr;
|
||||
switch (this->HelperState) {
|
||||
case State::Rule: {
|
||||
if (dep->rules.empty()) {
|
||||
return;
|
||||
}
|
||||
dst = &dep->rules.back();
|
||||
} break;
|
||||
case State::Dependency: {
|
||||
if (dep->paths.empty()) {
|
||||
return;
|
||||
}
|
||||
dst = &dep->paths.back();
|
||||
} break;
|
||||
}
|
||||
dst->append(s);
|
||||
}
|
||||
|
||||
void cmGccDepfileLexerHelper::sanitizeContent()
|
||||
{
|
||||
for (auto it = this->Content.begin(); it != this->Content.end();) {
|
||||
// Remove empty rules
|
||||
for (auto rit = it->rules.begin(); rit != it->rules.end();) {
|
||||
if (rit->empty()) {
|
||||
rit = it->rules.erase(rit);
|
||||
} else {
|
||||
++rit;
|
||||
}
|
||||
}
|
||||
// Remove the entry if rules are empty
|
||||
if (it->rules.empty()) {
|
||||
it = this->Content.erase(it);
|
||||
} else {
|
||||
// Remove empty paths
|
||||
for (auto pit = it->paths.begin(); pit != it->paths.end();) {
|
||||
if (pit->empty()) {
|
||||
pit = it->paths.erase(pit);
|
||||
} else {
|
||||
++pit;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Source/cmGccDepfileLexerHelper.h
Normal file
40
Source/cmGccDepfileLexerHelper.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmGccDepfileLexerHelper_h
|
||||
#define cmGccDepfileLexerHelper_h
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <cmGccDepfileReaderTypes.h>
|
||||
|
||||
class cmGccDepfileLexerHelper
|
||||
{
|
||||
public:
|
||||
cmGccDepfileLexerHelper() = default;
|
||||
|
||||
bool readFile(const char* filePath);
|
||||
cmGccDepfileContent extractContent() && { return std::move(this->Content); }
|
||||
|
||||
// Functions called by the lexer
|
||||
void newEntry();
|
||||
void newRule();
|
||||
void newDependency();
|
||||
void newRuleOrDependency();
|
||||
void addToCurrentPath(const char* s);
|
||||
|
||||
private:
|
||||
void sanitizeContent();
|
||||
|
||||
cmGccDepfileContent Content;
|
||||
|
||||
enum class State
|
||||
{
|
||||
Rule,
|
||||
Dependency
|
||||
};
|
||||
State HelperState = State::Rule;
|
||||
};
|
||||
|
||||
#define YY_EXTRA_TYPE cmGccDepfileLexerHelper*
|
||||
|
||||
#endif
|
||||
18
Source/cmGccDepfileReader.cxx
Normal file
18
Source/cmGccDepfileReader.cxx
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmGccDepfileReader.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "cmGccDepfileLexerHelper.h"
|
||||
|
||||
cmGccDepfileContent cmReadGccDepfile(const char* filePath)
|
||||
{
|
||||
cmGccDepfileContent result;
|
||||
cmGccDepfileLexerHelper helper;
|
||||
if (helper.readFile(filePath)) {
|
||||
result = std::move(helper).extractContent();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
10
Source/cmGccDepfileReader.h
Normal file
10
Source/cmGccDepfileReader.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmGccDepfileReader_h
|
||||
#define cmGccDepfileReader_h
|
||||
|
||||
#include "cmGccDepfileReaderTypes.h"
|
||||
|
||||
cmGccDepfileContent cmReadGccDepfile(const char* filePath);
|
||||
|
||||
#endif
|
||||
17
Source/cmGccDepfileReaderTypes.h
Normal file
17
Source/cmGccDepfileReaderTypes.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmGccDepfileReaderTypes_h
|
||||
#define cmGccDepfileReaderTypes_h
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct cmGccStyleDependency
|
||||
{
|
||||
std::vector<std::string> rules;
|
||||
std::vector<std::string> paths;
|
||||
};
|
||||
|
||||
using cmGccDepfileContent = std::vector<cmGccStyleDependency>;
|
||||
|
||||
#endif
|
||||
@@ -1171,13 +1171,51 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> dependencies(
|
||||
this->AutogenTarget.DependFiles.begin(),
|
||||
this->AutogenTarget.DependFiles.end());
|
||||
|
||||
const bool useNinjaDepfile = this->QtVersion >= IntegerVersion(5, 15) &&
|
||||
this->GlobalGen->GetName().find("Ninja") != std::string::npos;
|
||||
if (useNinjaDepfile) {
|
||||
// Create a custom command that generates a timestamp file and
|
||||
// has a depfile assigned. The depfile is created by JobDepFilesMergeT.
|
||||
|
||||
// Add additional autogen target dependencies
|
||||
for (const cmTarget* t : this->AutogenTarget.DependTargets) {
|
||||
dependencies.push_back(t->GetName());
|
||||
}
|
||||
const char timestampFileName[] = "timestamp";
|
||||
const std::string outputFile =
|
||||
cmStrCat(this->Dir.Build, "/", timestampFileName);
|
||||
this->AutogenTarget.DepFile = cmStrCat(this->Dir.Build, "/deps");
|
||||
this->AutogenTarget.DepFileRuleName =
|
||||
cmStrCat(this->GenTarget->GetName(), "_autogen/", timestampFileName);
|
||||
commandLines.push_back(cmMakeCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
|
||||
|
||||
this->AddGeneratedSource(outputFile, this->Moc);
|
||||
const std::string no_main_dependency;
|
||||
this->LocalGen->AddCustomCommandToOutput(
|
||||
outputFile, dependencies, no_main_dependency, commandLines,
|
||||
autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false,
|
||||
/*escapeOldStyle=*/false,
|
||||
/*uses_terminal=*/false,
|
||||
/*command_expand_lists=*/false, this->AutogenTarget.DepFile);
|
||||
|
||||
// Alter variables for the autogen target which now merely wraps the
|
||||
// custom command
|
||||
dependencies.clear();
|
||||
dependencies.push_back(outputFile);
|
||||
commandLines.clear();
|
||||
autogenComment.clear();
|
||||
}
|
||||
|
||||
// Create autogen target
|
||||
cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
|
||||
this->AutogenTarget.Name, true, this->Dir.Work.c_str(),
|
||||
/*byproducts=*/autogenProvides,
|
||||
std::vector<std::string>(this->AutogenTarget.DependFiles.begin(),
|
||||
this->AutogenTarget.DependFiles.end()),
|
||||
commandLines, false, autogenComment.c_str());
|
||||
/*depends=*/dependencies, commandLines, false, autogenComment.c_str());
|
||||
// Create autogen generator target
|
||||
this->LocalGen->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(autogenTarget, this->LocalGen));
|
||||
@@ -1188,9 +1226,11 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
autogenTarget->AddUtility(depName.Value, this->Makefile);
|
||||
}
|
||||
}
|
||||
// Add additional autogen target dependencies to autogen target
|
||||
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
|
||||
autogenTarget->AddUtility(depTarget->GetName(), this->Makefile);
|
||||
if (!useNinjaDepfile) {
|
||||
// Add additional autogen target dependencies to autogen target
|
||||
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
|
||||
autogenTarget->AddUtility(depTarget->GetName(), this->Makefile);
|
||||
}
|
||||
}
|
||||
|
||||
// Set FOLDER property in autogen target
|
||||
@@ -1408,12 +1448,15 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
|
||||
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
|
||||
|
||||
info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
|
||||
info.SetUInt("QT_VERSION_MINOR", this->QtVersion.Minor);
|
||||
info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable);
|
||||
info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable);
|
||||
|
||||
info.Set("CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
|
||||
info.SetConfig("SETTINGS_FILE", this->AutogenTarget.SettingsFile);
|
||||
info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
|
||||
info.Set("DEP_FILE", this->AutogenTarget.DepFile);
|
||||
info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
|
||||
info.SetArray("HEADER_EXTENSIONS",
|
||||
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
|
||||
info.SetArrayArray(
|
||||
|
||||
@@ -191,6 +191,8 @@ private:
|
||||
bool DependOrigin = false;
|
||||
std::set<std::string> DependFiles;
|
||||
std::set<cmTarget*> DependTargets;
|
||||
std::string DepFile;
|
||||
std::string DepFileRuleName;
|
||||
// Sources to process
|
||||
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
|
||||
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmFileTime.h"
|
||||
#include "cmGccDepfileReader.h"
|
||||
#include "cmGccDepfileReaderTypes.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmQtAutoGenerator.h"
|
||||
@@ -170,7 +172,7 @@ public:
|
||||
// -- Attributes
|
||||
// - Config
|
||||
bool MultiConfig = false;
|
||||
unsigned int QtVersionMajor = 4;
|
||||
IntegerVersion QtVersion = { 4, 0 };
|
||||
unsigned int ThreadCount = 0;
|
||||
// - Directories
|
||||
std::string AutogenBuildDir;
|
||||
@@ -179,6 +181,8 @@ public:
|
||||
std::string CMakeExecutable;
|
||||
cmFileTime CMakeExecutableTime;
|
||||
std::string ParseCacheFile;
|
||||
std::string DepFile;
|
||||
std::string DepFileRuleName;
|
||||
std::vector<std::string> HeaderExtensions;
|
||||
};
|
||||
|
||||
@@ -216,6 +220,7 @@ public:
|
||||
bool SettingsChanged = false;
|
||||
bool RelaxedMode = false;
|
||||
bool PathPrefix = false;
|
||||
bool CanOutputDependencies = false;
|
||||
cmFileTime ExecutableTime;
|
||||
std::string Executable;
|
||||
std::string CompFileAbs;
|
||||
@@ -485,8 +490,17 @@ public:
|
||||
class JobCompileMocT : public JobCompileT
|
||||
{
|
||||
public:
|
||||
using JobCompileT::JobCompileT;
|
||||
JobCompileMocT(MappingHandleT uicMapping,
|
||||
std::unique_ptr<std::string> reason,
|
||||
ParseCacheT::FileHandleT cacheEntry)
|
||||
: JobCompileT(std::move(uicMapping), std::move(reason))
|
||||
, CacheEntry(std::move(cacheEntry))
|
||||
{
|
||||
}
|
||||
void Process() override;
|
||||
|
||||
protected:
|
||||
ParseCacheT::FileHandleT CacheEntry;
|
||||
};
|
||||
|
||||
/** uic compiles a file. */
|
||||
@@ -504,6 +518,12 @@ public:
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
class JobDepFilesMergeT : public JobFenceT
|
||||
{
|
||||
private:
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
/** @brief The last job. */
|
||||
class JobFinishT : public JobFenceT
|
||||
{
|
||||
@@ -546,6 +566,9 @@ private:
|
||||
void Abort(bool error);
|
||||
// -- Generation
|
||||
bool CreateDirectories();
|
||||
// -- Support for depfiles
|
||||
static std::vector<std::string> dependenciesFromDepFile(
|
||||
const char* filePath);
|
||||
|
||||
private:
|
||||
// -- Settings
|
||||
@@ -951,7 +974,7 @@ void cmQtAutoMocUicT::JobParseT::MocMacro()
|
||||
|
||||
void cmQtAutoMocUicT::JobParseT::MocDependecies()
|
||||
{
|
||||
if (MocConst().DependFilters.empty()) {
|
||||
if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1674,8 +1697,13 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping,
|
||||
if (Probe(*mapping, reason.get())) {
|
||||
// Register the parent directory for creation
|
||||
MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
|
||||
// Fetch the cache entry for the source file
|
||||
std::string const& sourceFile = mapping->SourceFile->FileName;
|
||||
ParseCacheT::GetOrInsertT cacheEntry =
|
||||
BaseEval().ParseCache.GetOrInsert(sourceFile);
|
||||
// Add moc job
|
||||
Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason));
|
||||
Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(
|
||||
mapping, std::move(reason), std::move(cacheEntry.first));
|
||||
// Check if a moc job for a mocs_compilation.cpp entry was generated
|
||||
if (compFile) {
|
||||
MocEval().CompUpdated = true;
|
||||
@@ -1779,6 +1807,14 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
|
||||
std::string const& sourceDir, std::string const& includeString) const
|
||||
{
|
||||
using ResPair = std::pair<std::string, cmFileTime>;
|
||||
// moc's dependency file contains absolute paths
|
||||
if (MocConst().CanOutputDependencies) {
|
||||
ResPair res{ includeString, {} };
|
||||
if (res.second.Load(res.first)) {
|
||||
return res;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
// Search in vicinity of the source
|
||||
{
|
||||
ResPair res{ sourceDir + includeString, {} };
|
||||
@@ -1898,6 +1934,11 @@ void cmQtAutoMocUicT::JobProbeDepsFinishT::Process()
|
||||
Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
|
||||
}
|
||||
|
||||
if (!BaseConst().DepFile.empty()) {
|
||||
// Add job to merge dep files
|
||||
Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>();
|
||||
}
|
||||
|
||||
// Add finish job
|
||||
Gen()->WorkerPool().EmplaceJob<JobFinishT>();
|
||||
}
|
||||
@@ -1947,6 +1988,9 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
|
||||
}
|
||||
// Add extra options
|
||||
cm::append(cmd, MocConst().OptionsExtra);
|
||||
if (MocConst().CanOutputDependencies) {
|
||||
cmd.emplace_back("--output-dep-file");
|
||||
}
|
||||
// Add output file
|
||||
cmd.emplace_back("-o");
|
||||
cmd.push_back(outputFile);
|
||||
@@ -1956,12 +2000,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
|
||||
|
||||
// Execute moc command
|
||||
cmWorkerPool::ProcessResultT result;
|
||||
if (RunProcess(GenT::MOC, result, cmd, Reason.get())) {
|
||||
// Moc command success. Print moc output.
|
||||
if (!result.StdOut.empty()) {
|
||||
Log().Info(GenT::MOC, result.StdOut);
|
||||
}
|
||||
} else {
|
||||
if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) {
|
||||
// Moc command failed
|
||||
std::string includers;
|
||||
if (!Mapping->IncluderFiles.empty()) {
|
||||
@@ -1976,6 +2015,28 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
|
||||
MessagePath(outputFile), '\n', includers,
|
||||
result.ErrorMessage),
|
||||
cmd, result.StdOut);
|
||||
return;
|
||||
}
|
||||
|
||||
// Moc command success. Print moc output.
|
||||
if (!result.StdOut.empty()) {
|
||||
Log().Info(GenT::MOC, result.StdOut);
|
||||
}
|
||||
|
||||
// Extract dependencies from the dep file moc generated for us
|
||||
if (MocConst().CanOutputDependencies) {
|
||||
const std::string depfile = outputFile + ".d";
|
||||
if (Log().Verbose()) {
|
||||
Log().Info(GenT::MOC,
|
||||
"Reading dependencies from " + MessagePath(depfile));
|
||||
}
|
||||
if (!cmSystemTools::FileExists(depfile)) {
|
||||
Log().Warning(GenT::MOC,
|
||||
"Dependency file " + MessagePath(depfile) +
|
||||
" does not exist.");
|
||||
return;
|
||||
}
|
||||
CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1992,7 +2053,7 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
|
||||
auto optionIt = UicConst().UiFiles.find(sourceFile);
|
||||
if (optionIt != UicConst().UiFiles.end()) {
|
||||
UicMergeOptions(allOpts, optionIt->second.Options,
|
||||
(BaseConst().QtVersionMajor == 5));
|
||||
(BaseConst().QtVersion.Major == 5));
|
||||
}
|
||||
cm::append(cmd, allOpts);
|
||||
}
|
||||
@@ -2067,6 +2128,106 @@ void cmQtAutoMocUicT::JobMocsCompilationT::Process()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Escapes paths for Ninja depfiles.
|
||||
* This is a re-implementation of what moc does when writing depfiles.
|
||||
*/
|
||||
std::string escapeDependencyPath(cm::string_view path)
|
||||
{
|
||||
std::string escapedPath;
|
||||
escapedPath.reserve(path.size());
|
||||
const size_t s = path.size();
|
||||
int backslashCount = 0;
|
||||
for (size_t i = 0; i < s; ++i) {
|
||||
if (path[i] == '\\') {
|
||||
++backslashCount;
|
||||
} else {
|
||||
if (path[i] == '$') {
|
||||
escapedPath.push_back('$');
|
||||
} else if (path[i] == '#') {
|
||||
escapedPath.push_back('\\');
|
||||
} else if (path[i] == ' ') {
|
||||
// Double the amount of written backslashes,
|
||||
// and add one more to escape the space.
|
||||
while (backslashCount-- >= 0) {
|
||||
escapedPath.push_back('\\');
|
||||
}
|
||||
}
|
||||
backslashCount = 0;
|
||||
}
|
||||
escapedPath.push_back(path[i]);
|
||||
}
|
||||
return escapedPath;
|
||||
}
|
||||
|
||||
void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
|
||||
{
|
||||
if (Log().Verbose()) {
|
||||
Log().Info(GenT::MOC, "Merging MOC dependencies");
|
||||
}
|
||||
auto processDepFile =
|
||||
[](const std::string& mocOutputFile) -> std::vector<std::string> {
|
||||
std::string f = mocOutputFile + ".d";
|
||||
if (!cmSystemTools::FileExists(f)) {
|
||||
return {};
|
||||
}
|
||||
return dependenciesFromDepFile(f.c_str());
|
||||
};
|
||||
|
||||
std::vector<std::string> dependencies;
|
||||
ParseCacheT& parseCache = BaseEval().ParseCache;
|
||||
auto processMappingEntry = [&](const MappingMapT::value_type& m) {
|
||||
auto cacheEntry = parseCache.GetOrInsert(m.first);
|
||||
if (cacheEntry.first->Moc.Depends.empty()) {
|
||||
cacheEntry.first->Moc.Depends = processDepFile(m.second->OutputFile);
|
||||
}
|
||||
dependencies.insert(dependencies.end(),
|
||||
cacheEntry.first->Moc.Depends.begin(),
|
||||
cacheEntry.first->Moc.Depends.end());
|
||||
};
|
||||
|
||||
std::for_each(MocEval().HeaderMappings.begin(),
|
||||
MocEval().HeaderMappings.end(), processMappingEntry);
|
||||
std::for_each(MocEval().SourceMappings.begin(),
|
||||
MocEval().SourceMappings.end(), processMappingEntry);
|
||||
|
||||
// Remove duplicates to make the depfile smaller
|
||||
std::sort(dependencies.begin(), dependencies.end());
|
||||
dependencies.erase(std::unique(dependencies.begin(), dependencies.end()),
|
||||
dependencies.end());
|
||||
|
||||
// Add form files
|
||||
for (const auto& uif : UicEval().UiFiles) {
|
||||
dependencies.push_back(uif.first);
|
||||
}
|
||||
|
||||
// Write the file
|
||||
cmsys::ofstream ofs;
|
||||
ofs.open(BaseConst().DepFile.c_str(),
|
||||
(std::ios::out | std::ios::binary | std::ios::trunc));
|
||||
if (!ofs) {
|
||||
LogError(GenT::GEN,
|
||||
cmStrCat("Cannot open ", MessagePath(BaseConst().DepFile),
|
||||
" for writing."));
|
||||
return;
|
||||
}
|
||||
ofs << BaseConst().DepFileRuleName << ": \\" << std::endl;
|
||||
for (const std::string& file : dependencies) {
|
||||
ofs << '\t' << escapeDependencyPath(file) << " \\" << std::endl;
|
||||
if (!ofs.good()) {
|
||||
LogError(GenT::GEN,
|
||||
cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile),
|
||||
" failed."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the CMake executable to re-new cache data if necessary.
|
||||
// Also, this is the last entry, so don't add a backslash.
|
||||
ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void cmQtAutoMocUicT::JobFinishT::Process()
|
||||
{
|
||||
Gen()->AbortSuccess();
|
||||
@@ -2082,7 +2243,8 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
|
||||
{
|
||||
// -- Required settings
|
||||
if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
|
||||
!info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) ||
|
||||
!info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) ||
|
||||
!info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) ||
|
||||
!info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
|
||||
!info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
|
||||
!info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir,
|
||||
@@ -2090,6 +2252,9 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
|
||||
!info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) ||
|
||||
!info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile,
|
||||
true) ||
|
||||
!info.GetString("DEP_FILE", BaseConst_.DepFile, false) ||
|
||||
!info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName,
|
||||
false) ||
|
||||
!info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
|
||||
!info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
|
||||
!info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
|
||||
@@ -2143,8 +2308,10 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
|
||||
MocConst_.MacroFilters.emplace_back(
|
||||
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
|
||||
}
|
||||
// Dependency filters
|
||||
{
|
||||
// Can moc output dependencies or do we need to setup dependency filters?
|
||||
if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) {
|
||||
MocConst_.CanOutputDependencies = true;
|
||||
} else {
|
||||
Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS");
|
||||
if (!val.isArray()) {
|
||||
return info.LogError("MOC_DEPEND_FILTERS JSON value is not an array.");
|
||||
@@ -2660,6 +2827,19 @@ bool cmQtAutoMocUicT::CreateDirectories()
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
|
||||
const char* filePath)
|
||||
{
|
||||
cmGccDepfileContent content = cmReadGccDepfile(filePath);
|
||||
if (content.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Moc outputs a depfile with exactly one rule.
|
||||
// Discard the rule and return the dependencies.
|
||||
return content.front().paths;
|
||||
}
|
||||
|
||||
void cmQtAutoMocUicT::Abort(bool error)
|
||||
{
|
||||
if (error) {
|
||||
|
||||
@@ -11,6 +11,7 @@ set(CMakeLib_TESTS
|
||||
testCTestResourceAllocator.cxx
|
||||
testCTestResourceSpec.cxx
|
||||
testCTestResourceGroups.cxx
|
||||
testGccDepfileReader.cxx
|
||||
testGeneratedFileStream.cxx
|
||||
testRST.cxx
|
||||
testRange.cxx
|
||||
@@ -35,6 +36,7 @@ set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(testUVProcessChain_ARGS $<TARGET_FILE:testUVProcessChainHelper>)
|
||||
set(testUVStreambuf_ARGS $<TARGET_FILE:cmake>)
|
||||
set(testCTestResourceSpec_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(testGccDepfileReader_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND CMakeLib_TESTS
|
||||
|
||||
131
Tests/CMakeLib/testGccDepfileReader.cxx
Normal file
131
Tests/CMakeLib/testGccDepfileReader.cxx
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmGccDepfileReader.h"
|
||||
#include "cmGccDepfileReaderTypes.h" // for cmGccDepfileContent, cmGccStyle...
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
namespace {
|
||||
|
||||
cmGccDepfileContent readPlainDepfile(const char* filePath)
|
||||
{
|
||||
cmGccDepfileContent result;
|
||||
cmsys::ifstream is(filePath);
|
||||
if (!is.is_open())
|
||||
return result;
|
||||
std::string line;
|
||||
|
||||
cmGccStyleDependency dep;
|
||||
bool readingRules = true;
|
||||
while (cmSystemTools::GetLineFromStream(is, line)) {
|
||||
if (line == "--RULES--") {
|
||||
if (!dep.rules.empty()) {
|
||||
result.push_back(std::move(dep));
|
||||
dep = cmGccStyleDependency();
|
||||
}
|
||||
readingRules = true;
|
||||
} else if (line == "--DEPENDENCIES--") {
|
||||
readingRules = false;
|
||||
} else {
|
||||
std::vector<std::string>& dst = readingRules ? dep.rules : dep.paths;
|
||||
dst.push_back(std::move(line));
|
||||
line = std::string();
|
||||
}
|
||||
}
|
||||
|
||||
if (!dep.rules.empty()) {
|
||||
result.push_back(std::move(dep));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool compare(const std::vector<std::string>& actual,
|
||||
const std::vector<std::string>& expected, const char* msg)
|
||||
{
|
||||
if (actual.size() != expected.size()) {
|
||||
std::cerr << msg << "expected " << expected.size() << " entries."
|
||||
<< std::endl
|
||||
<< "Actual number of entries: " << actual.size() << std::endl;
|
||||
return false;
|
||||
}
|
||||
for (std::size_t i = 0; i < actual.size(); ++i) {
|
||||
if (actual[i] != expected[i]) {
|
||||
std::cerr << msg << std::endl
|
||||
<< "expected: " << expected[i] << std::endl
|
||||
<< "actual: " << actual[i] << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare(const cmGccDepfileContent& actual,
|
||||
const cmGccDepfileContent& expected)
|
||||
{
|
||||
if (actual.size() != expected.size()) {
|
||||
std::cerr << "Expected " << expected.size() << " entries." << std::endl
|
||||
<< "Actual number of entries: " << actual.size() << std::endl;
|
||||
return false;
|
||||
}
|
||||
for (std::size_t i = 0; i < actual.size(); ++i) {
|
||||
if (!compare(actual[i].rules, expected[i].rules, "Rules differ: ") ||
|
||||
!compare(actual[i].paths, expected[i].paths, "Paths differ: ")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void dump(const char* label, const cmGccDepfileContent& dfc)
|
||||
{
|
||||
std::cerr << label << std::endl;
|
||||
for (const auto& entry : dfc) {
|
||||
auto rit = entry.rules.cbegin();
|
||||
if (rit != entry.rules.cend()) {
|
||||
std::cerr << *rit;
|
||||
for (++rit; rit != entry.rules.cend(); ++rit) {
|
||||
std::cerr << " " << *rit;
|
||||
}
|
||||
std::cerr << ": " << std::endl;
|
||||
}
|
||||
for (const auto& path : entry.paths) {
|
||||
std::cerr << " " << path << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int testGccDepfileReader(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
std::cout << "Invalid arguments.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string dataDirPath = argv[1];
|
||||
dataDirPath += "/testGccDepfileReader_data";
|
||||
const int numberOfTestFiles = 3;
|
||||
for (int i = 1; i <= numberOfTestFiles; ++i) {
|
||||
const std::string base = dataDirPath + "/deps" + std::to_string(i);
|
||||
const std::string depfile = base + ".d";
|
||||
const std::string plainDepfile = base + ".txt";
|
||||
std::cout << "Comparing " << base << " with " << plainDepfile << std::endl;
|
||||
const auto actual = cmReadGccDepfile(depfile.c_str());
|
||||
const auto expected = readPlainDepfile(plainDepfile.c_str());
|
||||
if (!compare(actual, expected)) {
|
||||
dump("actual", actual);
|
||||
dump("expected", expected);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
Tests/CMakeLib/testGccDepfileReader_data/deps1.d
Normal file
20
Tests/CMakeLib/testGccDepfileReader_data/deps1.d
Normal file
@@ -0,0 +1,20 @@
|
||||
main.o: main.cpp /usr/include/stdc-predef.h /usr/include/stdio.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/libc-header-start.h \
|
||||
/usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/wordsize.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/long-double.h \
|
||||
/usr/include/x86_64-linux-gnu/gnu/stubs.h \
|
||||
/usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h \
|
||||
/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/typesizes.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__FILE.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/FILE.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/sys_errlist.h
|
||||
26
Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
Normal file
26
Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
--RULES--
|
||||
main.o
|
||||
--DEPENDENCIES--
|
||||
main.cpp
|
||||
/usr/include/stdc-predef.h
|
||||
/usr/include/stdio.h
|
||||
/usr/include/x86_64-linux-gnu/bits/libc-header-start.h
|
||||
/usr/include/features.h
|
||||
/usr/include/x86_64-linux-gnu/sys/cdefs.h
|
||||
/usr/include/x86_64-linux-gnu/bits/wordsize.h
|
||||
/usr/include/x86_64-linux-gnu/bits/long-double.h
|
||||
/usr/include/x86_64-linux-gnu/gnu/stubs.h
|
||||
/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
|
||||
/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h
|
||||
/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types.h
|
||||
/usr/include/x86_64-linux-gnu/bits/typesizes.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/__FILE.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/FILE.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h
|
||||
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h
|
||||
/usr/include/x86_64-linux-gnu/bits/stdio_lim.h
|
||||
/usr/include/x86_64-linux-gnu/bits/sys_errlist.h
|
||||
1
Tests/CMakeLib/testGccDepfileReader_data/deps2.d
Normal file
1
Tests/CMakeLib/testGccDepfileReader_data/deps2.d
Normal file
@@ -0,0 +1 @@
|
||||
foo.o bar.o: foobar.c
|
||||
5
Tests/CMakeLib/testGccDepfileReader_data/deps2.txt
Normal file
5
Tests/CMakeLib/testGccDepfileReader_data/deps2.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
--RULES--
|
||||
foo.o
|
||||
bar.o
|
||||
--DEPENDENCIES--
|
||||
foobar.c
|
||||
2
Tests/CMakeLib/testGccDepfileReader_data/deps3.d
Normal file
2
Tests/CMakeLib/testGccDepfileReader_data/deps3.d
Normal file
@@ -0,0 +1,2 @@
|
||||
main.o: main.cpp foo\#bar.h foo\\#bar.h foo\ bar.h \
|
||||
foo\\\ bar.h foo\\\\\ bar.h foo\\\\ foo$$bar.h
|
||||
11
Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
Normal file
11
Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
--RULES--
|
||||
main.o
|
||||
--DEPENDENCIES--
|
||||
main.cpp
|
||||
foo#bar.h
|
||||
foo\#bar.h
|
||||
foo bar.h
|
||||
foo\ bar.h
|
||||
foo\\ bar.h
|
||||
foo\\\\
|
||||
foo$bar.h
|
||||
@@ -10,7 +10,7 @@ class StyleA : public QStylePlugin
|
||||
Q_OBJECT
|
||||
// Json file in source local directory
|
||||
Q_PLUGIN_METADATA(IID "org.styles.A" FILE "StyleA.json")
|
||||
A_CUSTOM_MACRO(SomeArg, "StyleA_Custom.json", AnotherArg)
|
||||
A_CUSTOM_MACRO(org.styles.A, "StyleA_Custom.json", AnotherArg)
|
||||
public:
|
||||
QStyle* create(const QString& key);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ class StyleB : public QStylePlugin
|
||||
Q_OBJECT
|
||||
// Json file in source local subdirectory
|
||||
Q_PLUGIN_METADATA(IID "org.styles.B" FILE "jsonIn/StyleB.json")
|
||||
A_CUSTOM_MACRO(SomeArg, "jsonIn/StyleB_Custom.json", AnotherArg)
|
||||
A_CUSTOM_MACRO(org.styles.B, "jsonIn/StyleB_Custom.json", AnotherArg)
|
||||
public:
|
||||
QStyle* create(const QString& key);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ class StyleC : public QStylePlugin
|
||||
Q_OBJECT
|
||||
// Json file in global root directory
|
||||
Q_PLUGIN_METADATA(IID "org.styles.C" FILE "StyleC.json")
|
||||
A_CUSTOM_MACRO(SomeArg, "StyleC_Custom.json", AnotherArg)
|
||||
A_CUSTOM_MACRO(org.styles.C, "StyleC_Custom.json", AnotherArg)
|
||||
public:
|
||||
QStyle* create(const QString& key);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ class StyleD : public QStylePlugin
|
||||
Q_OBJECT
|
||||
// Json file in global sub director
|
||||
Q_PLUGIN_METADATA(IID "org.styles.D" FILE "sub/StyleD.json")
|
||||
A_CUSTOM_MACRO(SomeArg, "sub/StyleD_Custom.json", AnotherArg)
|
||||
A_CUSTOM_MACRO(org.styles.D, "sub/StyleD_Custom.json", AnotherArg)
|
||||
public:
|
||||
QStyle* create(const QString& key);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ class StyleE : public QStylePlugin
|
||||
Q_OBJECT
|
||||
// Json files in global root directory
|
||||
Q_PLUGIN_METADATA(IID "org.styles.E" FILE "StyleE.json")
|
||||
A_CUSTOM_MACRO(SomeArg, "StyleE_Custom.json", AnotherArg)
|
||||
A_CUSTOM_MACRO(org.styles.E, "StyleE_Custom.json", AnotherArg)
|
||||
public:
|
||||
QStyle* create(const QString& key);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef UTILITYMACROS_HPP
|
||||
#define UTILITYMACROS_HPP
|
||||
|
||||
// Empty test macro definition
|
||||
#define A_CUSTOM_MACRO(name, jsonFile, pluginRegistrations)
|
||||
#define A_CUSTOM_MACRO(url, jsonFile, pluginRegistrations) \
|
||||
Q_PLUGIN_METADATA(IID #url FILE jsonFile)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,8 +11,20 @@ target_link_libraries(exe PRIVATE Qt5::Core)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
|
||||
generate_output_files(exe)
|
||||
|
||||
set(moc_writes_depfiles 0)
|
||||
if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0")
|
||||
set(moc_writes_depfiles 1)
|
||||
endif()
|
||||
|
||||
set(autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/mocs_compilation.cpp")
|
||||
if(moc_writes_depfiles)
|
||||
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/deps")
|
||||
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/timestamp")
|
||||
endif()
|
||||
foreach(c IN LISTS CMAKE_CONFIGURATION_TYPES)
|
||||
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp")
|
||||
if(moc_writes_depfiles)
|
||||
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp.d")
|
||||
endif()
|
||||
endforeach()
|
||||
file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(AUTOGEN_FILES [==[${autogen_files}]==])\n")
|
||||
|
||||
@@ -14,7 +14,8 @@ for lexer in \
|
||||
CTestResourceGroups \
|
||||
DependsJava \
|
||||
Expr \
|
||||
Fortran
|
||||
Fortran \
|
||||
GccDepfile
|
||||
do
|
||||
cxx_file=cm${lexer}Lexer.cxx
|
||||
h_file=cm${lexer}Lexer.h
|
||||
|
||||
Reference in New Issue
Block a user