Инициализация исходников QtVsTools v2.8.1
594 files added
1 files modified
New file |
| | |
| | | # Remove the line below if you want to inherit .editorconfig settings from higher directories
|
| | | root = true
|
| | |
|
| | | # C# files
|
| | | [*.cs]
|
| | |
|
| | | #### Core EditorConfig Options ####
|
| | |
|
| | | # Indentation and spacing
|
| | | indent_size = 4
|
| | | indent_style = space
|
| | | tab_width = 4
|
| | |
|
| | | # New line preferences
|
| | | end_of_line = crlf
|
| | | insert_final_newline = false
|
| | |
|
| | | #### .NET Coding Conventions ####
|
| | |
|
| | | # Organize usings
|
| | | dotnet_separate_import_directive_groups = false
|
| | | dotnet_sort_system_directives_first = false
|
| | | file_header_template = unset
|
| | |
|
| | | # this. and Me. preferences
|
| | | dotnet_style_qualification_for_event = false
|
| | | dotnet_style_qualification_for_field = false
|
| | | dotnet_style_qualification_for_method = false
|
| | | dotnet_style_qualification_for_property = false
|
| | |
|
| | | # Language keywords vs BCL types preferences
|
| | | dotnet_style_predefined_type_for_locals_parameters_members = true
|
| | | dotnet_style_predefined_type_for_member_access = true
|
| | |
|
| | | # Parentheses preferences
|
| | | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
|
| | | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
|
| | | dotnet_style_parentheses_in_other_operators = never_if_unnecessary
|
| | | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
|
| | |
|
| | | # Modifier preferences
|
| | | dotnet_style_require_accessibility_modifiers = for_non_interface_members
|
| | |
|
| | | # Expression-level preferences
|
| | | dotnet_style_coalesce_expression = true
|
| | | dotnet_style_collection_initializer = true
|
| | | dotnet_style_explicit_tuple_names = true
|
| | | dotnet_style_namespace_match_folder = true
|
| | | dotnet_style_null_propagation = true
|
| | | dotnet_style_object_initializer = true
|
| | | dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
| | | dotnet_style_prefer_auto_properties = true
|
| | | dotnet_style_prefer_compound_assignment = true
|
| | | dotnet_style_prefer_conditional_expression_over_assignment = true
|
| | | dotnet_style_prefer_conditional_expression_over_return = true
|
| | | dotnet_style_prefer_inferred_anonymous_type_member_names = true
|
| | | dotnet_style_prefer_inferred_tuple_names = true
|
| | | dotnet_style_prefer_is_null_check_over_reference_equality_method = true
|
| | | dotnet_style_prefer_simplified_boolean_expressions = true
|
| | | dotnet_style_prefer_simplified_interpolation = true
|
| | |
|
| | | # Field preferences
|
| | | dotnet_style_readonly_field = true
|
| | |
|
| | | # Parameter preferences
|
| | | dotnet_code_quality_unused_parameters = all
|
| | |
|
| | | # Suppression preferences
|
| | | dotnet_remove_unnecessary_suppression_exclusions = none
|
| | |
|
| | | # New line preferences
|
| | | dotnet_style_allow_multiple_blank_lines_experimental = true
|
| | | dotnet_style_allow_statement_immediately_after_block_experimental = true
|
| | |
|
| | | #### C# Coding Conventions ####
|
| | |
|
| | | # var preferences
|
| | | csharp_style_var_elsewhere = false
|
| | | csharp_style_var_for_built_in_types = false
|
| | | csharp_style_var_when_type_is_apparent = false
|
| | |
|
| | | # Expression-bodied members
|
| | | csharp_style_expression_bodied_accessors = true
|
| | | csharp_style_expression_bodied_constructors = false
|
| | | csharp_style_expression_bodied_indexers = true
|
| | | csharp_style_expression_bodied_lambdas = true
|
| | | csharp_style_expression_bodied_local_functions = false
|
| | | csharp_style_expression_bodied_methods = false
|
| | | csharp_style_expression_bodied_operators = false
|
| | | csharp_style_expression_bodied_properties = true
|
| | |
|
| | | # Pattern matching preferences
|
| | | csharp_style_pattern_matching_over_as_with_null_check = true
|
| | | csharp_style_pattern_matching_over_is_with_cast_check = true
|
| | | csharp_style_prefer_not_pattern = true
|
| | | csharp_style_prefer_pattern_matching = true
|
| | | csharp_style_prefer_switch_expression = true
|
| | |
|
| | | # Null-checking preferences
|
| | | csharp_style_conditional_delegate_call = true
|
| | |
|
| | | # Modifier preferences
|
| | | csharp_prefer_static_local_function = true
|
| | | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
|
| | |
|
| | | # Code-block preferences
|
| | | csharp_prefer_braces = true
|
| | | csharp_prefer_simple_using_statement = true
|
| | | csharp_style_namespace_declarations = block_scoped
|
| | |
|
| | | # Expression-level preferences
|
| | | csharp_prefer_simple_default_expression = true
|
| | | csharp_style_deconstructed_variable_declaration = true
|
| | | csharp_style_implicit_object_creation_when_type_is_apparent = true
|
| | | csharp_style_inlined_variable_declaration = true
|
| | | csharp_style_pattern_local_over_anonymous_function = true
|
| | | csharp_style_prefer_index_operator = true
|
| | | csharp_style_prefer_null_check_over_type_check = true
|
| | | csharp_style_prefer_range_operator = true
|
| | | csharp_style_throw_expression = true
|
| | | csharp_style_unused_value_assignment_preference = discard_variable
|
| | | csharp_style_unused_value_expression_statement_preference = discard_variable
|
| | |
|
| | | # 'using' directive preferences
|
| | | csharp_using_directive_placement = outside_namespace
|
| | |
|
| | | # New line preferences
|
| | | csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
|
| | | csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
|
| | | csharp_style_allow_embedded_statements_on_same_line_experimental = true
|
| | |
|
| | | #### C# Formatting Rules ####
|
| | |
|
| | | # New line preferences
|
| | | csharp_new_line_before_catch = false
|
| | | csharp_new_line_before_else = false
|
| | | csharp_new_line_before_finally = false
|
| | | csharp_new_line_before_members_in_anonymous_types = true
|
| | | csharp_new_line_before_members_in_object_initializers = true
|
| | | csharp_new_line_before_open_brace = accessors,anonymous_methods,anonymous_types,lambdas,methods,object_collection_array_initializers,properties,types
|
| | | csharp_new_line_between_query_expression_clauses = true
|
| | |
|
| | | # Indentation preferences
|
| | | csharp_indent_block_contents = true
|
| | | csharp_indent_braces = false
|
| | | csharp_indent_case_contents =true
|
| | | csharp_indent_case_contents_when_block =true
|
| | | csharp_indent_labels = flush_left
|
| | | csharp_indent_switch_labels =false
|
| | |
|
| | | # Space preferences
|
| | | csharp_space_after_cast =false
|
| | | csharp_space_after_colon_in_inheritance_clause = true
|
| | | csharp_space_after_comma = true
|
| | | csharp_space_after_dot = false
|
| | | csharp_space_after_keywords_in_control_flow_statements = true
|
| | | csharp_space_after_semicolon_in_for_statement = true
|
| | | csharp_space_around_binary_operators = ignore
|
| | | csharp_space_around_declaration_statements = false
|
| | | csharp_space_before_colon_in_inheritance_clause = true
|
| | | csharp_space_before_comma = false
|
| | | csharp_space_before_dot = false
|
| | | csharp_space_before_open_square_brackets = false
|
| | | csharp_space_before_semicolon_in_for_statement = false
|
| | | csharp_space_between_empty_square_brackets = false
|
| | | csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
| | | csharp_space_between_method_call_name_and_opening_parenthesis = false
|
| | | csharp_space_between_method_call_parameter_list_parentheses = false
|
| | | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
| | | csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
| | | csharp_space_between_method_declaration_parameter_list_parentheses = false
|
| | | csharp_space_between_parentheses = false
|
| | | csharp_space_between_square_brackets = false
|
| | |
|
| | | # Wrapping preferences
|
| | | csharp_preserve_single_line_blocks = true
|
| | | csharp_preserve_single_line_statements = true
|
| | |
|
| | | #### Naming styles ####
|
| | |
|
| | | # Naming rules
|
| | |
|
| | | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
|
| | | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
| | | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
| | |
|
| | | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
| | | dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
| | | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
| | |
|
| | | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
|
| | | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
| | | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
| | |
|
| | | # Symbol specifications
|
| | |
|
| | | dotnet_naming_symbols.interface.applicable_kinds = interface
|
| | | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
| | | dotnet_naming_symbols.interface.required_modifiers = |
| | |
|
| | | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
| | | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
| | | dotnet_naming_symbols.types.required_modifiers = |
| | |
|
| | | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
| | | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
| | | dotnet_naming_symbols.non_field_members.required_modifiers = |
| | |
|
| | | # Naming styles
|
| | |
|
| | | dotnet_naming_style.pascal_case.required_prefix = |
| | | dotnet_naming_style.pascal_case.required_suffix = |
| | | dotnet_naming_style.pascal_case.word_separator = |
| | | dotnet_naming_style.pascal_case.capitalization = pascal_case
|
| | |
|
| | | dotnet_naming_style.begins_with_i.required_prefix = I
|
| | | dotnet_naming_style.begins_with_i.required_suffix = |
| | | dotnet_naming_style.begins_with_i.word_separator = |
| | | dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
| | |
| | | *~ |
| | | ui_*.h |
| | | *.swp |
| | | *.idb |
| | | *.pdb |
| | | *.ib_pdb_index |
| | | *.ncb |
| | | *.suo |
| | | *.user |
| | | Makefile |
| | | Makefile.* |
| | | debug/ |
| | | Debug/ |
| | | release/ |
| | | Release/ |
| | | GeneratedFiles/ |
| | | help/test |
| | | *.UnmanagedRegistration.cache |
| | | Trolltech.Qt4VS200?Base.xml |
| | | *_wrapper.bat |
| | | *_plugin_import.cpp |
| | | qrceditor/bin/ |
| | | qmakefilereader/bin/ |
| | | *.metaproj* |
| | | *.binlog |
| | | |
| | | ## Ignore Visual Studio temporary files, build results, and |
| | | ## files generated by popular Visual Studio add-ons. |
| | | |
| | | # User-specific files |
| | | *.suo |
| | | *.user |
| | | *.userosscache |
| | | *.sln.docstates |
| | | |
| | | # User-specific files (MonoDevelop/Xamarin Studio) |
| | | *.userprefs |
| | | |
| | | # Build results |
| | | [Dd]ebug/ |
| | | [Dd]ebugPublic/ |
| | | [Rr]elease/ |
| | | [Rr]eleases/ |
| | | x64/ |
| | | build/ |
| | | [Xx]64/ |
| | | [Xx]86/ |
| | | [Bb]uild/ |
| | | bld/ |
| | | [Bb]in/ |
| | | [Oo]bj/ |
| | | |
| | | # Roslyn cache directories |
| | | *.ide/ |
| | | # Visual Studio 2015 cache/options directory |
| | | .vs/ |
| | | # Uncomment if you have tasks that create the project's static files in wwwroot |
| | | #wwwroot/ |
| | | |
| | | # MSTest test Results |
| | | [Tt]est[Rr]esult*/ |
| | | [Bb]uild[Ll]og.* |
| | | |
| | | #NUNIT |
| | | # NUNIT |
| | | *.VisualState.xml |
| | | TestResult.xml |
| | | |
| | |
| | | [Dd]ebugPS/ |
| | | [Rr]eleasePS/ |
| | | dlldata.c |
| | | |
| | | # DNX |
| | | project.lock.json |
| | | artifacts/ |
| | | |
| | | *_i.c |
| | | *_p.c |
| | |
| | | ipch/ |
| | | *.aps |
| | | *.ncb |
| | | *.opendb |
| | | *.opensdf |
| | | *.sdf |
| | | *.cachefile |
| | | *.VC.db |
| | | |
| | | # Visual Studio profiler |
| | | *.psess |
| | | *.vsp |
| | | *.vspx |
| | | *.sap |
| | | |
| | | # TFS 2012 Local Workspace |
| | | $tf/ |
| | |
| | | *.[Rr]e[Ss]harper |
| | | *.DotSettings.user |
| | | |
| | | # JustCode is a .NET coding addin-in |
| | | # JustCode is a .NET coding add-in |
| | | .JustCode |
| | | |
| | | # TeamCity is a build add-in |
| | |
| | | # NCrunch |
| | | _NCrunch_* |
| | | .*crunch*.local.xml |
| | | nCrunchTemp_* |
| | | |
| | | # MightyMoose |
| | | *.mm.* |
| | |
| | | # Publish Web Output |
| | | *.[Pp]ublish.xml |
| | | *.azurePubxml |
| | | ## TODO: Comment the next line if you want to checkin your |
| | | ## web deploy settings but do note that will include unencrypted |
| | | ## passwords |
| | | *.pubxml |
| | | |
| | | # TODO: Un-comment the next line if you do not want to checkin |
| | | # your web deploy settings because they may include unencrypted |
| | | # passwords |
| | | #*.pubxml |
| | | *.publishproj |
| | | |
| | | # NuGet Packages |
| | | packages/* |
| | | *.nupkg |
| | | ## TODO: If the tool you use requires repositories.config |
| | | ## uncomment the next line |
| | | #!packages/repositories.config |
| | | # The packages folder can be ignored because of Package Restore |
| | | **/packages/* |
| | | # except build/, which is used as an MSBuild target. |
| | | !**/packages/build/ |
| | | # Uncomment if necessary however generally it will be regenerated when needed |
| | | #!**/packages/repositories.config |
| | | # NuGet v3's project.json files produces more ignoreable files |
| | | *.nuget.props |
| | | *.nuget.targets |
| | | |
| | | # Enable "build/" folder in the NuGet Packages folder since |
| | | # NuGet packages use it for MSBuild targets. |
| | | # This line needs to be after the ignore of the build folder |
| | | # (and the packages folder if the line above has been uncommented) |
| | | !packages/build/ |
| | | |
| | | # Windows Azure Build Output |
| | | # Microsoft Azure Build Output |
| | | csx/ |
| | | *.build.csdef |
| | | |
| | | # Microsoft Azure Emulator |
| | | ecf/ |
| | | rcf/ |
| | | |
| | | # Microsoft Azure ApplicationInsights config file |
| | | ApplicationInsights.config |
| | | |
| | | # Windows Store app package directory |
| | | AppPackages/ |
| | | BundleArtifacts/ |
| | | |
| | | # Visual Studio cache files |
| | | # files ending in .cache can be ignored |
| | | *.[Cc]ache |
| | | # but keep track of directories ending in .cache |
| | | !*.[Cc]ache/ |
| | | |
| | | # Others |
| | | sql/ |
| | | *.Cache |
| | | ClientBin/ |
| | | [Ss]tyle[Cc]op.* |
| | | ~$* |
| | |
| | | *.pfx |
| | | *.publishsettings |
| | | node_modules/ |
| | | orleans.codegen.cs |
| | | |
| | | # RIA/Silverlight projects |
| | | Generated_Code/ |
| | |
| | | |
| | | # Microsoft Fakes |
| | | FakesAssemblies/ |
| | | |
| | | # GhostDoc plugin setting file |
| | | *.GhostDoc.xml |
| | | |
| | | # Node.js Tools for Visual Studio |
| | | .ntvs_analysis.dat |
| | | |
| | | # Visual Studio 6 build log |
| | | *.plg |
| | | |
| | | # Visual Studio 6 workspace options file |
| | | *.opt |
| | | |
| | | # Visual Studio LightSwitch build output |
| | | **/*.HTMLClient/GeneratedArtifacts |
| | | **/*.DesktopClient/GeneratedArtifacts |
| | | **/*.DesktopClient/ModelManifest.xml |
| | | **/*.Server/GeneratedArtifacts |
| | | **/*.Server/ModelManifest.xml |
| | | _Pvt_Extensions |
| | | |
| | | # LightSwitch generated files |
| | | GeneratedArtifacts/ |
| | | ModelManifest.xml |
| | | |
| | | # Paket dependency manager |
| | | .paket/paket.exe |
| | | |
| | | # FAKE - F# Make |
| | | .fake/ |
| | | |
| | | # Generated Files |
| | | MSBuild.MetaInfo.cs |
| | | qtvstools.package/package/Version.tt.cs |
| | | qtvstools.package/Properties/AssemblyInfo.tt.cs |
| | | qtvstools.package/QtMenus.vsct |
| | | qtvstools.package/Marketplace/Overview.html |
| | | qtvstools.core/Properties/AssemblyInfo.tt.cs |
| | | qtvstools.wizards/Properties/AssemblyInfo.tt.cs |
| | | templates/qmldir/Properties/AssemblyInfo.tt.cs |
| | | templates/qml/Properties/AssemblyInfo.tt.cs |
| | | templates/console/Properties/AssemblyInfo.tt.cs |
| | | templates/designer/Properties/AssemblyInfo.tt.cs |
| | | templates/dialogbuttonbottom/Properties/AssemblyInfo.tt.cs |
| | | templates/dialogbuttonright/Properties/AssemblyInfo.tt.cs |
| | | templates/empty/Properties/AssemblyInfo.tt.cs |
| | | templates/quick/Properties/AssemblyInfo.tt.cs |
| | | templates/gui/Properties/AssemblyInfo.tt.cs |
| | | templates/lib/Properties/AssemblyInfo.tt.cs |
| | | templates/mainwindow/Properties/AssemblyInfo.tt.cs |
| | | templates/resource/Properties/AssemblyInfo.tt.cs |
| | | templates/server/Properties/AssemblyInfo.tt.cs |
| | | templates/widget/Properties/AssemblyInfo.tt.cs |
| | | templates/console/console.vstemplate |
| | | templates/designer/designer.vstemplate |
| | | templates/empty/empty.vstemplate |
| | | templates/quick/quick.vstemplate |
| | | templates/gui/gui.vstemplate |
| | | templates/lib/lib.vstemplate |
| | | templates/server/server.vstemplate |
| | | qtmsbuild/Properties/AssemblyInfo.tt.cs |
| | | qtmsbuild/QtMsBuild/moc/qtmoc_v3.xml |
| | | qtmsbuild/QtMsBuild/moc/qtmoc_cl.targets |
| | | qtmsbuild/QtMsBuild/rcc/qtrcc_v3.xml |
| | | qtmsbuild/QtMsBuild/rcc/qtrcc_cl.targets |
| | | qtmsbuild/QtMsBuild/repc/qtrepc_v3.xml |
| | | qtmsbuild/QtMsBuild/repc/qtrepc_cl.targets |
| | | qtmsbuild/QtMSBuild/qt_tasks.targets |
| | | qtvstest/csmacro.tmLanguage |
| | | qtvstest/csmacro.tmTheme |
| | | qtvstest/Properties/AssemblyInfo.tt.cs |
| | | qtvstest/source.extension.vsixmanifest |
| | | QtVsTools.Package/source.extension.vsixmanifest |
| | | QtNatvisPoC/*.txt |
| | | Tests/BigSolution/generated/ |
| | | vstools.pri |
New file |
| | |
| | | Qt Visual Studio Tools version 2.8.1:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-340: QML files are not updated with lupdate
|
| | | - Fixed QTVSADDINBUG-431: Difficult to find feature to change Qt Version
|
| | | - Fixed QTVSADDINBUG-801, QTVSADDINBUG-498: Error in qt5.natvis: "identifier "$T1" is undefined"
|
| | | - Fixed QTVSADDINBUG-628: Change Qt Project settings lead to an error message
|
| | | - Fixed QTVSADDINBUG-659: Missing Qurl debug visualizer
|
| | | - Fixed QTVSADDINBUG-700: In debug, a QStandardItem will not be resolved unless inside the class
|
| | | - Fixed QTVSADDINBUG-701: "Qt Project Settings" incorrect behavior
|
| | | - Fixed QTVSADDINBUG-831: Error creating new Qt project when "application icon" option is enabled
|
| | | - Fixed QTVSADDINBUG-883: Background build error when using common props file
|
| | | - Fixed QTVSADDINBUG-919: Missing QML/QtQuick plugins when using a static Qt build
|
| | | - Fixed QTVSADDINBUG-924: New Qt projects use C++14 standard by default
|
| | | - Fixed QTVSADDINBUG-926: Qt module selection can't be confirmed
|
| | | - Fixed QTVSADDINBUG-930: "Finish" button always disabled in Qt Class Wizard
|
| | | - Fixed QTVSADDINBUG-936: Generated C++ source file fails to compile with precompiled header
|
| | | - Fixed QTVSADDINBUG-941: "Translation disabled during build; skipping"
|
| | | - Fixed QTVSADDINBUG-943: Document Qt 6 Support
|
| | | - Fixed QTVSADDINBUG-950: Get Qt build settings from 'vcapp' qmake template
|
| | | - Fixed QTVSADDINBUG-952: lupdate is not run during build
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.8.0:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Added support for Visual Studio 2022
|
| | | - Fixed QTVSADDINBUG-927: Post-build refresh of IntelliSense data slows down/freezes the VS IDE
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.7.2:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-805: Q_NAMESPACE needs mocing
|
| | | - Fixed QTVSADDINBUG-871: lupdate/lrelease not working on .ts file context menu
|
| | | - Fixed QTVSADDINBUG-873: Update list of Qt modules
|
| | | - Fixed QTVSADDINBUG-874: Add option to open Designer in detached window
|
| | | - Fixed QTVSADDINBUG-875: Can't open .ui files if path has space
|
| | | - Fixed QTVSADDINBUG-887: Cannot add Qt version
|
| | | - Fixed QTVSADDINBUG-888: lupdate fails to locate source files
|
| | | - Fixed QTVSADDINBUG-890: Background build and VS2019 freeze on open solution
|
| | | - Fixed QTVSADDINBUG-898: .ts files not processed
|
| | | - Fixed QTVSADDINBUG-916: Build concurrency issues
|
| | | - Fixed QTVSADDINBUG-917: Build concurrency issues
|
| | | - Added module selection popup in Qt Settings property page
|
| | | - Optimized IntelliSense updates ("background build")
|
| | | - UI feedback of IntelliSense update, with the option to cancel background tasks
|
| | | - Context menu option to update Qt project IntelliSense information (Qt > Refresh IntelliSense)
|
| | | - Notification of available development release
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.7.1:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Translation tools integrated with Qt/MSBuild
|
| | | - Qt.props property sheet accessible through the VS Property Manager window
|
| | | - Qt editors are opened in a document window inside Visual Studio
|
| | | - IntelliSense is updated on changes to .ui files
|
| | | - The Qt Options UI will be displayed as part of the standard VS 'Tools > Options' dialog
|
| | | - Added the following new fields to the Qt Options page:
|
| | | * QML debugger connection timeout
|
| | | * Path to Qt/MSBuild files
|
| | | * Enable QML debugger (overrides project settings)
|
| | | * Enable refresh of IntelliSense after build
|
| | | * Enable refresh of IntelliSense when a .ui file is changed
|
| | | - Pressing F1 will query Qt documentation
|
| | | - Fixed QTVSADDINBUG-698: Qt online help not working
|
| | | - Fixed QTVSADDINBUG-755: QML debug not working without a QRC file
|
| | | - Fixed QTVSADDINBUG-822: Incorrect generation of command line options
|
| | | - Fixed QTVSADDINBUG-825: Calls to qmake fail silently
|
| | | - Fixed QTVSADDINBUG-826: Crash in new-project wizard
|
| | | - Fixed QTVSADDINBUG-827: Command line options of Qt tools generated incorrectly
|
| | | - Fixed QTVSADDINBUG-837: Debug output cluttered with QML debugger status messages
|
| | | - Fixed QTVSADDINBUG-841: Incremental build failure
|
| | | - Fixed QTVSADDINBUG-857: Build fails due to concurrency issues
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.6.0:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Support for cross-compilation with the Linux development VS workload
|
| | | - Integration of Qt for Windows deployment tool (windeployqt)
|
| | | - Fixed QTVSADDINBUG-797: Incorrect generation of command-line flags for Qt tools
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.5.2:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-749: lupdate/lrelease options ignored
|
| | | - Fixed QTVSADDINBUG-756, QTVSADDINBUG-783: Qt tools generate files outside of project directory
|
| | | - Fixed QTVSADDINBUG-760: repc output directory not added to include path
|
| | | - Fixed QTVSADDINBUG-772, QTVSADDINBUG-777: Qt tools fail to run if path contains spaces
|
| | | - Fixed QTVSADDINBUG-780: Regression in Qt Quick compiler integration
|
| | | - Fixed QTVSADDINBUG-781: Error accessing Qt version when using non-ASCII characters in paths
|
| | | - Fixed QTVSADDINBUG-782: Incorrect build settings in the debug configuration of Qt Console apps
|
| | | - Fixed QTVSADDINBUG-785: OBJECTS_DIR ignored when importing .pro
|
| | | - Fixed QTVSADDINBUG-786: repc command line generated incorrectly
|
| | | - Fixed QTVSADDINBUG-790: Build errors when temp directory ends with .lnk
|
| | | - Fixed QTVSADDINBUG-792: Files with Q_OBJECT macro not handled correctly
|
| | | - Fixed QTVSADDINBUG-793: Backslashes in Qt version name causes error
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.5.1:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Minimum supported version of VS2017 (15.8.28010.0) enforced by installer
|
| | | - Improved IntelliSense synchronization
|
| | | - Fixed QTVSADDINBUG-545: Missing support for custom installations of Qt
|
| | | - Fixed QTVSADDINBUG-771: .pro import does not replace Qt path with $(QTDIR)
|
| | | - Fixed QTVSADDINBUG-771: .pro import removes explicit reference to opengl32.lib
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.5.0:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - New-project wizards will now allow choice of Qt version per configuration (QTVSADDINBUG-737)
|
| | | - Added the Qt Quick Application project wizard (QTVSADDINBUG-589)
|
| | | - Renamed Qt GUI Application wizard to Qt Widgets Application (QTVSADDINBUG-589)
|
| | | - Added support for rcc two-pass mode (QTVSADDINBUG-564)
|
| | | - Fixed QTVSADDINBUG-642: Ignoring changes to VS document folder path when deploying .natvis
|
| | | - Fixed QTVSADDINBUG-643: Debug visualizer for QHash does not work with const key type
|
| | | - Fixed QTVSADDINBUG-644: Error message "Qt not configured" does not identify the project
|
| | | - Fixed QTVSADDINBUG-646: QML debugging will not work if command-line arguments are added
|
| | | - Fixed QTVSADDINBUG-647: If no Qt version is configured in VS, a generic error message is shown
|
| | | - Fixed QTVSADDINBUG-648: Importing .pro shows qmake status and error messages out-of-sync
|
| | | - Fixed QTVSADDINBUG-704: Importing .pro ignores private Qt modules
|
| | | - Fixed QTVSADDINBUG-711: Incompatibility with VS unity builds
|
| | | - Fixed QTVSADDINBUG-721: Target path for Qt properties file cannot be changed
|
| | | - Fixed QTVSADDINBUG-732: Importing .pro blindly substitutes the string 'release' in file names
|
| | | - Fixed QTVSADDINBUG-733: NDEBUG defined in Release configurations
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.4.3 includes several bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-560: New Qt projects with duplicate GUID
|
| | | - Fixed QTVSADDINBUG-685: Property sheets not working with Qt projects
|
| | | - Fixed QTVSADDINBUG-690: All configs not named 'Debug' use release build settings
|
| | | - Fixed QTVSADDINBUG-702: Conversion errors when project has empty property values
|
| | | - Fixed QTVSADDINBUG-703: Pre-compiled header disabled for generated sources
|
| | | - Fixed QTVSADDINBUG-708: Link errors with projects including Windows resources (.rc file)
|
| | | - Fixed QTVSADDINBUG-709: Qt-related menu items show in non-Qt project context menu
|
| | | - Fixed QTVSADDINBUG-712: Qt INCLUDEPATH property has incorrect values
|
| | | - Fixed QTVSADDINBUG-717: Qt project build fails when multiple VS instances are launched
|
| | | - Fixed QTVSADDINBUG-722: Error getting Qt property values from generated Makefile
|
| | | - Fixed QTVSADDINBUG-723: Projects built multiple times when dependencies are defined
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.4.2 includes several bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-674: Error importing .pro: "invalid character in path"
|
| | | - Fixed QTVSADDINBUG-676: Link error in project with references to other projects
|
| | | - Fixed QTVSADDINBUG-681: Error importing .pro using static build of Qt
|
| | | - Fixed QTVSADDINBUG-683: Error building with long PATH value
|
| | | - Fixed QTVSADDINBUG-684: Build error: " was unexpected
|
| | | - Fixed QTVSADDINBUG-693: Compiling sources generated by Qt tools produces unexpected .asm files
|
| | | - Fixed QTVSADDINBUG-694: Project is never up-to-date
|
| | | - Fixed QTVSADDINBUG-699: Error compiling qrc-generated sources with pre-compiled headers
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.4.1 includes several bug fixes.
|
| | |
|
| | | Rev. 12
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-663: Project format conversion fails due to unexpected elements in .vcxproj
|
| | | - Fixed QTVSADDINBUG-665: $(DefaultVersion) no longer works
|
| | | - Fixed QTVSADDINBUG-670: Unicode WinAPI functions called despite using multi-byte char set
|
| | | - Fixed QTVSADDINBUG-671: Error "command too long" when using static build of Qt
|
| | | - Fixed QTVSADDINBUG-672: Extension does not load in VS2019 v16.2 or earlier
|
| | | - Fixed QTVSADDINBUG-673: Intellisense is unable to locate Qt headers
|
| | | - Fixed QTVSADDINBUG-680: Build errors when using an earlier version of Qt (<= 5.7)
|
| | | - Fixed QTVSADDINBUG-682: Menu open "Qt Project Settings" opens empty dialog
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-391: Qt VS Tools no longer works with static builds
|
| | | - Fixed QTVSADDINBUG-496: VS crashes if no Qt version is installed
|
| | | - Fixed QTVSADDINBUG-545: No support for third-party library managers (e.g. vcpkg)
|
| | | - Fixed QTVSADDINBUG-597: Converted projects lose excluded-from-build settings
|
| | | - Fixed QTVSADDINBUG-640: Qt tools not invoked if project includes a "custom build step"
|
| | | - Fixed QTVSADDINBUG-650: Setting the QtInstall property to a path does not work
|
| | | - Fixed QTVSADDINBUG-651: The QtInstall property does not expand macros
|
| | | - Fixed QTVSADDINBUG-653: Build errors when using configuration names containing spaces
|
| | | - Fixed QTVSADDINBUG-657: Projects imported from .pro files lose reference to QtHelp module
|
| | | - Fixed QTVSADDINBUG-658: Build errors in Qt project with pre-compiled headers
|
| | | - Fixed QTVSADDINBUG-661: Selected files build: missing path to uic-generated headers
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.4.0 implements Qt project settings as MSBuild properties, and
|
| | | also adds support for Qt Remote Objects.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Qt settings are now stored as fully fledged MSBuild properties (QTVSADDINBUG-575)
|
| | | - Added support for Qt Remote Objects (QTVSADDINBUG-585)
|
| | | - Fixed QTVSADDINBUG-598: Cannot export library projects to .pro files
|
| | | - Fixed QTVSADDINBUG-632: Include path out-of-sync between moc and C++ compiler
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.3.2 contains several bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-601: Pressing Alt-F1 crashes VS or fails to find selected documentation
|
| | | - Fixed QTVSADDINBUG-608: Error in QRC compilation when paths contain spaces
|
| | | - Fixed QTVSADDINBUG-609: C++ compiler output directories are not created
|
| | | - Fixed QTVSADDINBUG-610: QML debug blocked when path to executable contains spaces
|
| | | - Fixed QTVSADDINBUG-611: Build errors when combining RelativeDir with absolute paths in Qt tools
|
| | | - Fixed QTVSADDINBUG-613: Project dependencies ignored
|
| | | - Fixed QTVSADDINBUG-615: Unable to set breakpoints in .js files
|
| | | - Fixed QTVSADDINBUG-618: Error when building with FIPS group policy enabled
|
| | | - Will now display the version of the Qt Visual Studio Tools in the main menu (QTVSADDINBUG-607).
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.3.1 adds support for Visual Studio 2019. This version also
|
| | | includes fixes to bugs reported in the previous version.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Added support for Visual Studio 2019
|
| | | - Extension initialization will now run in the background
|
| | | - Fixed QTVSADDINBUG-583: Incorrect conversion of custom build to Qt/MSBuild
|
| | | - Fixed QTVSADDINBUG-592: Custom build steps running after Qt tools and C++ compilation
|
| | | - Fixed QTVSADDINBUG-593: .natvis files not installed if visualizers directory does not yet exist
|
| | | - Fixed QTVSADDINBUG-594: Failed to build project with QRC files and precompiled headers
|
| | | - Fixed QTVSADDINBUG-599: Debug session frozen if QML debugging is enabled
|
| | | - Fixed QTVSADDINBUG-601: Pressing Alt+F1 for help on a Qt class member crashes Visual Studio
|
| | | - Fixed QTVSADDINBUG-604: Conversion to Qt/MSBuild seems to freeze when errors occur
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.3.0 introduces QML debugging in Visual Studio, as well as the
|
| | | ahead-of-time compilation of QML files using the Qt Quick Compiler. This release also includes a
|
| | | number of bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Debug QML programs in the Visual Studio IDE
|
| | | - Ahead-of-time compilation of QML files using the Qt Quick Compiler
|
| | | - Fixed QTVSADDINBUG-120: Output directories (MOC_DIR, UI_DIR, RCC_DIR) in imported .pro ignored
|
| | | - Fixed QTVSADDINBUG-378: Debug data visualization not working with Qt built with namespace
|
| | | - Fixed QTVSADDINBUG-526: QRC not rebuilt if resources are updated
|
| | | - Fixed QTVSADDINBUG-550: Standard Visual Studio macros not allowed in rcc and uic path setting
|
| | | - Fixed QTVSADDINBUG-584: Compilation of selected files (i.e. 'right-click' > 'Compile') not working
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.2.2 contains several bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-544: Build is never up-to-date, even if no files have been changed.
|
| | | - Fixed QTVSADDINBUG-551: Qt VS Tools adds a delay to Visual Studio startup.
|
| | | - Fixed QTVSADDINBUG-558: Missing Qt module: Data Visualization
|
| | | - Fixed QTVSADDINBUG-559: Missing Qt module: Charts
|
| | | - Fixed QTVSADDINBUG-563: Error "same key already added" when converting project to Qt/MSBuild
|
| | | - Fixed QTVSADDINBUG-566: Error converting to Qt/MSBuild if custom build command has a newline
|
| | | - Fixed QTVSADDINBUG-569: %QTMSBUILD% environment variable always overwritten at start-up
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.2.1 contains several bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed QTVSADDINBUG-509: Noticeable delays when saving any .cpp file in larger projects created
|
| | | with previous versions of the Qt VS Tools
|
| | | - Fixed QTVSADDINBUG-510: Errors converting .pro files with long INCLUDEPATH definitions
|
| | | - Fixed QTVSADDINBUG-511: Incorrect usage of $(IntDir) in the definition of QtWorkFilePath
|
| | | - Fixed QTVSADDINBUG-512: PrecompiledHeaders.h include missing in moc after adding new class
|
| | | - Fixed QTVSADDINBUG-514: Quotes removed from preprocessor definition
|
| | | - Fixed QTVSADDINBUG-515: Visual Studio unresponsive while Converting custom build to Qt/MSBuild
|
| | | - Fixed QTVSADDINBUG-520: Delay when starting build in solutions with many projects/configurations
|
| | | - Fixed QTVSADDINBUG-521: Unable to use Qt version if it was built with -qtlibinfix
|
| | | - Fixed QTVSADDINBUG-522: Duplicating defines and include paths from moc in the C++ dynamic source
|
| | | - Fixed QTVSADDINBUG-523: Qt VS Tools stopped working with static builds
|
| | | - Fixed QTVSADDINBUG-530: When a file includes the generated moc output for a header file as well
|
| | | as its own generated moc output then it will fail to build
|
| | | - Fixed QTVSADDINBUG-531: Project not being built when a .uic or .qrc file is changed
|
| | | - Fixed QTVSADDINBUG-532: Delay when continuing execution after hitting breakpoint
|
| | | - Fixed QTVSADDINBUG-533: Errors in conversion to Qt/MSBuild when using MOC_DIR or the '@' option
|
| | | - Fixed QTVSADDINBUG-534: Problems with inheritance of properties defined in property sheets.
|
| | | - Fixed QTVSADDINBUG-535: Problems with incremental build
|
| | | - Fixed QTVSADDINBUG-537: Delay after changing C++ properties in large project
|
| | | - Fixed QTVSADDINBUG-538: Incorrect escaping of paths in command line strings
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.2.0 is the first official release of the Visual Studio add-in
|
| | | for Visual Studio 2017, 2015 and 2013.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - New approach to moc, rcc and uic integration using MSBuild rules and targets
|
| | | - No longer adds generated files to projects
|
| | | - Creates Universal Windows projects when using a WinRT version of Qt
|
| | | - Allows import of .pro files using a WinRT version of Qt
|
| | | - Optimized the performance of adding header files (QTVSADDINBUG-64)
|
| | | - Optimized the performance of the .pro import procedure (QTVSADDINBUG-442)
|
| | | - Parallel execution of moc, rcc and uic processes (QTVSADDINBUG-124)
|
| | | - Uses multi-processor compilation of C++ by default (QTVSADDINBUG-443)
|
| | | - Updated list of Qt modules (QTVSADDINBUG-411)
|
| | | - Fixed QTVSADDINBUG-105: moced source files are output to the same directory, prone to filename
|
| | | clashes
|
| | | - Fixed QTVSADDINBUG-140: VS2012 Doesn't start-up anymore correctly after VSAddin usage.
|
| | | - Fixed QTVSADDINBUG-363: When the QTDIR variable is set after the LocalDebuggerEnvironment
|
| | | variable in the users file for a project then it will not find the debugger
|
| | | - Fixed QTVSADDINBUG-439: Visual Studio Addin creates bad project file if "flat" flag is removed
|
| | | from config before converting to Visual Studio project
|
| | | - Fixed QTVSADDINBUG-479: Error building Qt projects in VS 2017: SDK not found
|
| | | - Fixed QTVSADDINBUG-485: Microsoft.Cpp.$(Platform).user.props absent
|
| | | - Fixed QTVSADDINBUG-489: When a qrc file is added to the project it is defaulting to being
|
| | | processed with -no-compress which is not the default on the command line
|
| | | - Fixed QTVSADDINBUG-491: lupdate no longer works via Visual Studio Add-in
|
| | | - Fixed QTVSADDINBUG-493: The application exited with an error (ExitCode 1)
|
| | | - Fixed QTVSADDINBUG-504: Changing the project's Qt from Desktop to UWP causes linker errors
|
| | | - Fixed QTVSADDINBUG-505: Opening a .pro file that does not contain Qt3D causes "3D module" to be
|
| | | checked in project's Qt settings
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.1.2 contains support for VS 2017 and several bug fixes.
|
| | |
|
| | | QTVSADDINBUG-459: Fix reported issues against the VS2017 beta release
|
| | | QTVSADDINBUG-396: Fix new item with VS not generating the moc
|
| | | QTVSADDINBUG-472: Fix opening pro file with Qt 5.9
|
| | | QTVSADDINBUG-460: Fix package containing corrupted data
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.1.1 contains a bug fix for QTVSADDINBUG-453
|
| | |
|
| | | The Qt Visual Studio Tools version 2.1.0 contains improvements for QML syntax highlighting and
|
| | | several bug fixes.
|
| | |
|
| | | - Some speed improvements while importing large qmake based projects
|
| | | - Better handling of $(QTDIR) environment and possible related errors
|
| | | - Use TextMate language files for QML and qmake syntax highlighting (VS 2015)
|
| | |
|
| | | - QTVSADDINBUG-445: Fix wrong usage of QT_STATIC and QT_DLL
|
| | | - QTVSADDINBUG-407: Fix Environment variables are not saved/restored after VS restart
|
| | |
|
| | |
|
| | | The Qt Visual Studio Tools version 2.0.0 is an update of the existing Add-In implementation
|
| | | to the newer Visual Studio Package (VSIX extension) system.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Rewrite the Add-In as VSIX extension
|
| | | - Known issues: Missing QML, help and localization support
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.2.5 contains an update of the Qt documentation
|
| | | and some bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Qt 5.6 help documents included.
|
| | | - Fixed wrong VCProjectEngine dependency for 2012 installer, which prevented the Add-In from being
|
| | | loaded (QTVSADDINBUG-392)
|
| | | - Use correct solution platform when creating projects using x64 Qt build (QTVSADDINBUG-377)
|
| | | - Fixed several issues with projects' Qt modules settings (QTVSADDINBUG-344, QTVSADDINBUG-359,
|
| | | QTVSADDINBUG-388, QTVSADDINBUG-390)
|
| | | - Do not overwrite debugging environment on project loading (QTVSADDINBUG-375)
|
| | | - Fixed issues that prevented Qt 5.6 version from being registered to the Add-In (QTVSADDINBUG-418)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.2.4 contains updated help
|
| | | documents and a bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Qt 5.4 help documents included.
|
| | | - Fixed crash when creating new Qt5 app in VS2008 (QTVSADDINBUG-385)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.2.3 contains support for VS2013,
|
| | | updated help documents and some bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Visual Studio 2013 support.
|
| | | - Qt 5.3 help documents included.
|
| | | - Handle wchar_t as builtin type, fixed. (QTVSADDINBUG-171)
|
| | | - Fix for detecting wince build. (QTVSADDINBUG-176)
|
| | | - Release project with debug info enabled links wrong qt dll's, fixed.(QTVSADDINBUG-350)
|
| | | - Generated pri/pro files have mixed line endings (LF/CRLF), fixed.(QTVSADDINBUG-351)
|
| | | - Intermediate Directory needs a trailing slash, fixed.(QTVSADDINBUG-356)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.2.2 contains updated help documents and
|
| | | two bug fixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Qt 5.1 help documents included.
|
| | | - Incorrect overwriting of the environment setting value on every build/run
|
| | | removed. (QTVSADDINBUG-159)
|
| | | - Links in Qt help not working, fixed. (QTVSADDINBUG-160)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.2.1 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Qt 5.0.1 help documents included
|
| | | - Qmake wrapper COM component removed and replaced with command line tool
|
| | | qmakefilereader to avoid need to load Qt5 library binaries to Visual Studio
|
| | | process. And to get installation of add-in easier, especially with VS2008.
|
| | | - Qt4 add-in is not allowed to run same time, if found it will be closed.
|
| | | Also if Qt4 add-in is present in system, default editor values for .ts, .ui
|
| | | and .qrc file types are not permanently overwritten by Qt5 add-in. Values are
|
| | | written when Qt5 add-in loads and Qt4 values are set when Qt5 add-in unloads.
|
| | | This should make it possible to install and use both Qt4 and Qt5 versions of
|
| | | add-in. Not to use same time but in turns. Though user must be careful what he
|
| | | does.
|
| | | - Recognizing Qt5 CE build. (QTVSADDINBUG-153)
|
| | | - Incorrect additional directories paths set when Qt modules added/removed from
|
| | | Qt Project Settings page. (QTVSADDINBUG-151)
|
| | | - Include directories search path for some Qt modules fixed (QTVSADDINBUG-150)
|
| | | - Invalid Qt module names fixed (QTVSADDINBUG-142)
|
| | | - Crash when importing .pri file fixed (QTVSADDINBUG-139)
|
| | | - Qt default settings saving problem fixed (QTVSADDINBUG-137)
|
| | | - Naming of precompiled header fixed (QTVSADDINBUG-132)
|
| | | - Support for debugger visualizers in VS2012 (QTVSADDINBUG-129)
|
| | | - Setting Qt libraries path for debugging session fixed (QTVSADDINBUG-125)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.2.0 supports Qt 5.0.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Parameter passing to lupdate fixed (QTVSADDINBUG-131)
|
| | | - Project creation wizards updated to follow Qt5 module structure
|
| | | - Project settings form updated to follow Qt5 module structure
|
| | | - Help documents updated to Qt5
|
| | | - No more Qt4 project creation wizards and project settings
|
| | | - Support for Visual Studio 2012
|
| | | - All project files (*.sln, *.csproj etc) are renamed to Qt5
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.11 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Documentation updated
|
| | | - Documentation support for Visual Studio 2010. (QTVSADDINBUG-15)
|
| | | - Fixed always moc'ing problem. (QTVSADDINBUG-92)
|
| | | - Fixed .pro file opening having include to "." path. (QTVSADDINBUG-117)
|
| | | - Removed extra back slashes from qmake arg paths.
|
| | | - Fixed some additional include dir handling causing same path to be added multiple times to custom
|
| | | build step.
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.10 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Be aware of comments when parsing qmake.conf. (QTVSADDINBUG-76)
|
| | | - Fixed exception when using using unsupported lupdate parameters. (QTVSADDINGBUG-70)
|
| | | - Detecting the MSVC version from qmake.conf was fixed.
|
| | | - Added QtScriptTools and QtUiTools to project settings. (QTVSADDINBUG-71)
|
| | | - Removed the MSVC version check when adding Qt versions. As this "feature" seems to cause more
|
| | | trouble than it solves, we decided to remove it. Checking for the makefile generator should at
|
| | | least prevent people from trying to add MinGW builds.
|
| | | - Fixed creation of addin projects from 64 bit Qt qmake projects.
|
| | | - Do not add the include path "$QTDIR/include/qtmain".
|
| | | This path is a relict and confuses IntelliSense. (QTVSADDINBUG-81)
|
| | | - Be aware of strings when looking for Q_OBJECT macros. (QTVSADDINBUG-75)
|
| | | - Fix problems with the debugging environment. (QTVSADDINBUG-93)
|
| | | - Pass correct QtDesigner4.lib library name to linker. (QTVSADDINBUG-85)
|
| | | - Fix cleaning of autoexp.dat on uninstallation for VS 2005. (QTVSADDINBUG-67)
|
| | | - Use slashes as path separators in includes in moc files. (QTVSADDINBUG-84)
|
| | | - Choose a valid Qt version if the default Qt version becomes invalid. (QTVSADDINBUG-60)
|
| | | - Prevent infinite loop if QtAppWrapper cannot connect. (QTVSADDINBUG-73)
|
| | | - Add and remove the correct OpenGL libraries when changing project's Qt version. (QTVSADDINBUG-80)
|
| | | - Use project macro for filenames in moc step. (QTVSADDINBUG-30)
|
| | | - Fixed batch builds of Qt projects for multiple platforms. (QTVSADDINBUG-51)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.9 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fix a regression when importing .pro files that was introduced in 1.1.8.
|
| | | - Make the add-in work with Intel VTune projects. (QTVSADDINBUG-65)
|
| | | - Check for compatibility with VS version when adding new Qt version. This will hopefully stop
|
| | | people from trying to use a MinGW Qt build with Visual Studio. (QTVSADDINBUG-58)
|
| | | - Added possiblity to specifiy lupdate/lrelease options. (QTVSADDINBUG-48)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.8 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Do not save the QTDIR in a property sheet for VS 2010. (QTVSADDINBUG-12)
|
| | | - QtDeclarative module added to the modules page and wizards. (QTVSADDINBUG-44)
|
| | | - Fix import of .pri files. (QTVSADDINBUG-38)
|
| | | - Save the modified generated .vc(x)proj after .pro file import. (QTVSADDINBUG-40)
|
| | | - Proper handling of moc file exclusion when saving cpp files. (QTVSADDINBUG-33)
|
| | | - Remove user macro from property sheed when $(QTDIR) is used in VS2010. (QTVSADDINBUG-12)
|
| | | - Documented possibility to add $(QTDIR) version. (QTVSADDINGBUG-19)
|
| | | - Fix broken include paths in moc calls for VS 2010. (QTVSADDINBUG-34)
|
| | | - Fix import of previously unloaded projects. (QTVSADDINBUG-31)
|
| | | - Preserve line breaks in custom build steps after import. (QTVSADDINBUG-32)
|
| | | - Fix exception that could be raised when changing the Qt version of solutions that contained
|
| | | non-C++ projects. (QTVSADDINBUG-50)
|
| | | - Fix moc command line creation for include paths that contain whitespace
|
| | | characters. (QTVSADDINBUG-53)
|
| | | - Fixed the Windows CE wizards that stopped working under certain circumstances. (QTVSADDINBUG-42)
|
| | | - Several fixes for Windows CE project generation.
|
| | | - Qt 4.7.2 documentation included.
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.7 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fix import of .pro files with "CONFIG -= flat". (QTVSADDINBUG-10)
|
| | | - Fix naming of classes in generated .ui files. (QTVSADDINBUG-9)
|
| | | - Visualizers for QPolygon and QPolygonF fixed. (QTVSADDINBUG-8)
|
| | | - Fix expanding filters on build.
|
| | | - Fix Qt 4.7 qmake warning wrt backslash escaping on import.
|
| | | - VS2010: fix AddMocStep for new header files. (QTVSADDINBUG-2)
|
| | | - GUI class wizard: fix .ui file overwriting check. (QTVSADDINBUG-3)
|
| | | - When adding moc step, do not assume that cpp file is present. (QTVSADDINBUG-1)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.6 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed collapse of Generated files after import/build on Visual Studio
|
| | | 2005. (QTBUG-4750)
|
| | | - Support for Visual Studio 2010. (QTBUG-5374)
|
| | | - Added check for invalid variables in Rcc/Uic directories in Qt (project) settings. (QTBUG-6818)
|
| | | - Updated documentation for changing the target platform. (QTBUG-7262)
|
| | | - Translate filter names on .pro file import or when switching from a qmake generated
|
| | | (qmake -tp vc) project to an Add-in project. (QTBUG-11325)
|
| | | - Fixed regression in custom build step generation. (QTBUG-11527)
|
| | | - Fixed "Change Solution's Qt version" for solutions that contain Intel Fortran
|
| | | projects. (QTBUG-11567)
|
| | | - Fix output paths for custom build steps in release configuration. (QTBUG-12145)
|
| | | - Fix import if CONFIG contains "silent". (QTBUG-12344)
|
| | | - Phonon is added automatically if WebKit is selected. (QTBUG-10154)
|
| | | - Fixed display of uninitialized QSet and QHash object. (QTBUG-12890)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.5 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed setting of preprocessor definitions when changing to a Windows CE Qt version. (QTBUG-10564)
|
| | | - Added contribution for QMap visualization. (QTBUG-3970)
|
| | | - Recursively look for includes/defines in PropertySheets. (QTBUG-10406)
|
| | | - Fixed bugs affecting Q_OBJECTs in .cpp files.
|
| | | - On import, the content of .qrc files is added to the Resources filter of the Visual Studio
|
| | | project. (QTBUG-10113)
|
| | | - QRC Editor: The add-in will synchronize the list of resources in a .qrc file with the files in
|
| | | the Resources filter of the project. (QTBUG-6103)
|
| | | - QRC Editor: show full resource URL. (QTBUG-3801)
|
| | | - Refresh moc steps when PCH options are changed. (QTBUG-7700)
|
| | | - You don't have to be admin anymore to set Windows CE Qt versions. (QTBUG-9550)
|
| | | - QtAppWrapper: Do not stop listening to new connections if error occurs. (QTBUG-8508)
|
| | | - Handle C++ comments correctly. (QTBUG-7641)
|
| | | - Support $(PlatformName) for moc, uic and rcc directories. (QTBUG-5814)
|
| | | - Fixed exception when exporting non-C++ projects. (QTBUG-9234)
|
| | | - Fixed module handling for static libraries. (QTBUG-8670)
|
| | | - Resolve %BASECLASS% in Qt4Class template again, to keep old custom class wizard additions
|
| | | working. (QTBUG-8615)
|
| | | - Fixed wrong DLL names in Windows CE deployment of Qt modules. (QTBUG-8622)
|
| | | - Fixed import of .pro files with library dependency paths that contain whitespace
|
| | | characters. (QTBUG-8493)
|
| | | - Added possibility to use mocDir without $(ConfigurationName). (QTBUG-7288)
|
| | | - Fixed import for projects with relative moc dir settings. (QTBUG-8372)
|
| | | - Fixed import for project without resources.
|
| | | - Don't depend on .NET Framework 3.5 SP1. (QTBUG-8415)
|
| | | - Fix moc steps for file names, that are contain substrings of variables,
|
| | | like "Config.h" (QTBUG-8218)
|
| | | - Detection of invalid class names in projects wizards. (QTBUG-8154)
|
| | | - Fixed creation of translation files when custom cultures are present. (QTBUG-11124)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.4 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Several bugs when opening .ui and .ts files have been fixed. The qtappwrapper has been
|
| | | overhauled. (QTBUG-6857, QTBUG-7491)
|
| | | - Importing .pro files with source files in subdirectories does not longer cause creation of
|
| | | invalid moc steps. (QTBUG-7603)
|
| | | - The Qt Multimedia module is now available in all project wizards and the Qt modules
|
| | | dialog. (QTBUG-7487)
|
| | | - The "Generated Files" filter is collapsed after .pro file import. (QTBUG-7687)
|
| | | - Automatically checkout .ui, .qrc and .ts files if they are under source control. (QTBUG-7680)
|
| | | - Remove .res files from the "Generated Files" filter after .pro file import as
|
| | | they are not needed. (QTBUG-7494)
|
| | | - Class wizards: Take care of forbidden characters when building include guards for
|
| | | header files. (QTBUG-7811)
|
| | | - Fix exception when accessing the Qt project settings for projects, that do not have
|
| | | a compiler tool. (QTBUG-7930)
|
| | | - Fix bug in moc step update, which occured when there was more than one file in
|
| | | the "Outputs" property of the custom build step. (QTBUG-7937)
|
| | | - Added an option to turn off the automatic moc steps update. (QTBUG-7938)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.3 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Added checks to avoid unneeded access to .vcproj file when saving files
|
| | | with Q_OBJECT. (QTBUG-5813)
|
| | | - When using Visual Studio 2005 the project tree is no longer expanded
|
| | | after each build. (QTBUG-6482)
|
| | | - Switching between qmake and AddIn projects more robust. (QTBUG-6434)
|
| | | - Set target machine explicitly when changing Qt version. (QTBUG-5206)
|
| | | - Work around Visual Studio bug to support the simplified Chinese
|
| | | version of Visual Studio. (QTBUG-6318)
|
| | | - Fixed bug for Windows CE static builds. (QTBUG-3493)
|
| | | - Create signature step for Windows CE projects. (QTBUG-3493)
|
| | | - Fixed visualizers for QList and QMap. (very simple version for QMap as
|
| | | an appropiate visualization seems impossible in autoexp.dat) (QTBUG-660
|
| | | and QTBUG-3970)
|
| | | - Fixed visualizers for QVector. (QTBUG-7121)
|
| | | - Support empty base classes in Qt4Class wizard. (QTBUG-6797)
|
| | | - Support namespaces when creating Qt classes. (QTBUG-5227)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.2 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed various problems concerning precompiled headers (stdafx as default
|
| | | (QTBUG-5226), change of settings when building...)
|
| | | - Increased support for solution folders (QTBUG-4914)
|
| | | - Detection of solution .pro files fixed (be aware of possible newline
|
| | | after \)
|
| | | - Fixed bug, which could appear when moc steps had to be updated.
|
| | | The update caused an invalid moc commandline which made the build fail.
|
| | | - Added support for Q_Gadget macro(QTBUG-5291)
|
| | | - Project tree is not expanded on every build when using VS2005 (QTBUG-5291)
|
| | | - Fixed conversion from AddIn project to Qmake project and vice
|
| | | versa (QTBUG5380)
|
| | | - Repair moc path when importing .pro file (QTBUG-4221)
|
| | | - Support of commandline builds (QTBUG-5321)
|
| | | (In VS2005 there are some issues when trying to load AddIns from the
|
| | | commandline. See http://support.microsoft.com/kb/934517)
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.1 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Fixed startup of Qt Designer and Qt Linguist when the application was
|
| | | not build for the current project's Qt Version. The Add-In tries to find
|
| | | the needed tool inside the directory of the other registered Qt Versions.
|
| | | - "Generate basic pro file" gets disabled in project's context menu and Qt
|
| | | menu if the current project is a qmake generated project.
|
| | | - When importing a solution file while a solution is opened, the user gets
|
| | | the possibility to automatically close the current solution.
|
| | | - Avoid infinite recursion in inclusion which happened when moccing .cpp
|
| | | files, which used precompiled headers.
|
| | | - Translation files are added when exporting project to a .pri file.
|
| | | - Project is cleaned, when its Qt version is changed.
|
| | | - As there is no way to avoid the expansion of generated files filter when
|
| | | the project is built the first time, the generated files are collapsed
|
| | | after the build has finished (QTBUG-4750).
|
| | | - Changing the project's Qt Version after importing a .pro file does not
|
| | | longer make the build fail (QTBUG-4756)
|
| | | - Exclusion of .cpp and .h files cause the mocced files to be excluded from
|
| | | build too (QTBUG-3404)
|
| | | - Adding a Qt class no longer implies that precompiled headers are used.
|
| | | - Fixed processing of lupdate in projects with a big amount of files
|
| | | (QTBUG-4783).
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.1.0 contains multiple bugfixes and
|
| | | improvements.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - The custom build step generation has been changed to use a subfolder for
|
| | | every configuration. This solves the problem of heavy changes in the vcproj
|
| | | file whenever the user switches to another build configuration. (Task 251918)
|
| | | - Qt Designer, Qt Linguist and the QRC Editor are started via a properly
|
| | | registered editor wrapper. Now its possible to open ui files in other
|
| | | editors, like the built-in XML editor. (Task 250601)
|
| | | - Projects can be converted from Qt Add-in projects to qmake generated
|
| | | projects and back. (Task 153484)
|
| | | - Fixing the behaviour of adding a file to a filter. (Task 254968)
|
| | | - Opening a vcproj file that has a non-defined Qt version works now like in
|
| | | the old Qt VS integration. (Task 258704)
|
| | | - The detection of Windows CE Qt builds has been fixed.
|
| | | - OpenGL Desktop Windows libraries aren't added to linker options in
|
| | | Windows CE projects. (Task 260550)
|
| | | - If there's no Generated Files folder, then we don't try to delete its
|
| | | content. (Task 260723)
|
| | | - Fix bug for solutions that contain disabled (unloaded) projects. (Task 259807)
|
| | | - Switching between static and dynamic Qt builds has been fixed.
|
| | | - Add-in's documentation has been updated.
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.0.2 contains multiple bugfixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Platform was not set correctly when solution contains several projects.
|
| | | - Repair broken QTDIR Variable when project is added to solution.
|
| | | - Fix problem with dots in pro file names.
|
| | | - Qt module Phonon added to wizards and dialogs.
|
| | | - Don't mess around with whitespaces in every source file we add. (Task 251987)
|
| | | - Prevent duplicates in additional dependencies, includes etc.
|
| | | - Fix rare exception when importing solution pro file.
|
| | | - Fix switching between static and dynamic Qt build.
|
| | | - Enable the user to add a "$(QTDIR)" Qt version even if QTDIR is not set.
|
| | |
|
| | | The Qt Visual Studio Add-In version 1.0.1 contains multiple bugfixes.
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Qt .pro file import fixed for projects containing SUBDIRS.
|
| | | - Fixed moc file build exclusion when saving a .cpp file.
|
| | | - Keep user defined debugging environment when adding the Qt environment.
|
| | | - Fix the display of full file paths in custom build tool descriptions.
|
| | | - Documentation updated.
|
| | |
|
New file |
| | |
| | | This is the GNU General Public License version 3, annotated with The
|
| | | Qt Company GPL Exception 1.0:
|
| | |
|
| | | -------------------------------------------------------------------------
|
| | |
|
| | | The Qt Company GPL Exception 1.0
|
| | |
|
| | | Exception 1:
|
| | |
|
| | | As a special exception you may create a larger work which contains the
|
| | | output of this application and distribute that work under terms of your
|
| | | choice, so long as the work is not otherwise derived from or based on
|
| | | this application and so long as the work does not in itself generate
|
| | | output that contains the output from this application in its original
|
| | | or modified form.
|
| | |
|
| | | Exception 2:
|
| | |
|
| | | As a special exception, you have permission to combine this application
|
| | | with Plugins licensed under the terms of your choice, to produce an
|
| | | executable, and to copy and distribute the resulting executable under
|
| | | the terms of your choice. However, the executable must be accompanied
|
| | | by a prominent notice offering all users of the executable the entire
|
| | | source code to this application, excluding the source code of the
|
| | | independent modules, but including any changes you have made to this
|
| | | application, under the terms of this license.
|
| | |
|
| | |
|
| | | -------------------------------------------------------------------------
|
| | |
|
| | | GNU GENERAL PUBLIC LICENSE
|
| | | Version 3, 29 June 2007
|
| | |
|
| | | Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
| | | Everyone is permitted to copy and distribute verbatim copies
|
| | | of this license document, but changing it is not allowed.
|
| | |
|
| | | Preamble
|
| | |
|
| | | The GNU General Public License is a free, copyleft license for
|
| | | software and other kinds of works.
|
| | |
|
| | | The licenses for most software and other practical works are designed
|
| | | to take away your freedom to share and change the works. By contrast,
|
| | | the GNU General Public License is intended to guarantee your freedom to
|
| | | share and change all versions of a program--to make sure it remains free
|
| | | software for all its users. We, the Free Software Foundation, use the
|
| | | GNU General Public License for most of our software; it applies also to
|
| | | any other work released this way by its authors. You can apply it to
|
| | | your programs, too.
|
| | |
|
| | | When we speak of free software, we are referring to freedom, not
|
| | | price. Our General Public Licenses are designed to make sure that you
|
| | | have the freedom to distribute copies of free software (and charge for
|
| | | them if you wish), that you receive source code or can get it if you
|
| | | want it, that you can change the software or use pieces of it in new
|
| | | free programs, and that you know you can do these things.
|
| | |
|
| | | To protect your rights, we need to prevent others from denying you
|
| | | these rights or asking you to surrender the rights. Therefore, you have
|
| | | certain responsibilities if you distribute copies of the software, or if
|
| | | you modify it: responsibilities to respect the freedom of others.
|
| | |
|
| | | For example, if you distribute copies of such a program, whether
|
| | | gratis or for a fee, you must pass on to the recipients the same
|
| | | freedoms that you received. You must make sure that they, too, receive
|
| | | or can get the source code. And you must show them these terms so they
|
| | | know their rights.
|
| | |
|
| | | Developers that use the GNU GPL protect your rights with two steps:
|
| | | (1) assert copyright on the software, and (2) offer you this License
|
| | | giving you legal permission to copy, distribute and/or modify it.
|
| | |
|
| | | For the developers' and authors' protection, the GPL clearly explains
|
| | | that there is no warranty for this free software. For both users' and
|
| | | authors' sake, the GPL requires that modified versions be marked as
|
| | | changed, so that their problems will not be attributed erroneously to
|
| | | authors of previous versions.
|
| | |
|
| | | Some devices are designed to deny users access to install or run
|
| | | modified versions of the software inside them, although the manufacturer
|
| | | can do so. This is fundamentally incompatible with the aim of
|
| | | protecting users' freedom to change the software. The systematic
|
| | | pattern of such abuse occurs in the area of products for individuals to
|
| | | use, which is precisely where it is most unacceptable. Therefore, we
|
| | | have designed this version of the GPL to prohibit the practice for those
|
| | | products. If such problems arise substantially in other domains, we
|
| | | stand ready to extend this provision to those domains in future versions
|
| | | of the GPL, as needed to protect the freedom of users.
|
| | |
|
| | | Finally, every program is threatened constantly by software patents.
|
| | | States should not allow patents to restrict development and use of
|
| | | software on general-purpose computers, but in those that do, we wish to
|
| | | avoid the special danger that patents applied to a free program could
|
| | | make it effectively proprietary. To prevent this, the GPL assures that
|
| | | patents cannot be used to render the program non-free.
|
| | |
|
| | | The precise terms and conditions for copying, distribution and
|
| | | modification follow.
|
| | |
|
| | | TERMS AND CONDITIONS
|
| | |
|
| | | 0. Definitions.
|
| | |
|
| | | "This License" refers to version 3 of the GNU General Public License.
|
| | |
|
| | | "Copyright" also means copyright-like laws that apply to other kinds of
|
| | | works, such as semiconductor masks.
|
| | |
|
| | | "The Program" refers to any copyrightable work licensed under this
|
| | | License. Each licensee is addressed as "you". "Licensees" and
|
| | | "recipients" may be individuals or organizations.
|
| | |
|
| | | To "modify" a work means to copy from or adapt all or part of the work
|
| | | in a fashion requiring copyright permission, other than the making of an
|
| | | exact copy. The resulting work is called a "modified version" of the
|
| | | earlier work or a work "based on" the earlier work.
|
| | |
|
| | | A "covered work" means either the unmodified Program or a work based
|
| | | on the Program.
|
| | |
|
| | | To "propagate" a work means to do anything with it that, without
|
| | | permission, would make you directly or secondarily liable for
|
| | | infringement under applicable copyright law, except executing it on a
|
| | | computer or modifying a private copy. Propagation includes copying,
|
| | | distribution (with or without modification), making available to the
|
| | | public, and in some countries other activities as well.
|
| | |
|
| | | To "convey" a work means any kind of propagation that enables other
|
| | | parties to make or receive copies. Mere interaction with a user through
|
| | | a computer network, with no transfer of a copy, is not conveying.
|
| | |
|
| | | An interactive user interface displays "Appropriate Legal Notices"
|
| | | to the extent that it includes a convenient and prominently visible
|
| | | feature that (1) displays an appropriate copyright notice, and (2)
|
| | | tells the user that there is no warranty for the work (except to the
|
| | | extent that warranties are provided), that licensees may convey the
|
| | | work under this License, and how to view a copy of this License. If
|
| | | the interface presents a list of user commands or options, such as a
|
| | | menu, a prominent item in the list meets this criterion.
|
| | |
|
| | | 1. Source Code.
|
| | |
|
| | | The "source code" for a work means the preferred form of the work
|
| | | for making modifications to it. "Object code" means any non-source
|
| | | form of a work.
|
| | |
|
| | | A "Standard Interface" means an interface that either is an official
|
| | | standard defined by a recognized standards body, or, in the case of
|
| | | interfaces specified for a particular programming language, one that
|
| | | is widely used among developers working in that language.
|
| | |
|
| | | The "System Libraries" of an executable work include anything, other
|
| | | than the work as a whole, that (a) is included in the normal form of
|
| | | packaging a Major Component, but which is not part of that Major
|
| | | Component, and (b) serves only to enable use of the work with that
|
| | | Major Component, or to implement a Standard Interface for which an
|
| | | implementation is available to the public in source code form. A
|
| | | "Major Component", in this context, means a major essential component
|
| | | (kernel, window system, and so on) of the specific operating system
|
| | | (if any) on which the executable work runs, or a compiler used to
|
| | | produce the work, or an object code interpreter used to run it.
|
| | |
|
| | | The "Corresponding Source" for a work in object code form means all
|
| | | the source code needed to generate, install, and (for an executable
|
| | | work) run the object code and to modify the work, including scripts to
|
| | | control those activities. However, it does not include the work's
|
| | | System Libraries, or general-purpose tools or generally available free
|
| | | programs which are used unmodified in performing those activities but
|
| | | which are not part of the work. For example, Corresponding Source
|
| | | includes interface definition files associated with source files for
|
| | | the work, and the source code for shared libraries and dynamically
|
| | | linked subprograms that the work is specifically designed to require,
|
| | | such as by intimate data communication or control flow between those
|
| | | subprograms and other parts of the work.
|
| | |
|
| | | The Corresponding Source need not include anything that users
|
| | | can regenerate automatically from other parts of the Corresponding
|
| | | Source.
|
| | |
|
| | | The Corresponding Source for a work in source code form is that
|
| | | same work.
|
| | |
|
| | | 2. Basic Permissions.
|
| | |
|
| | | All rights granted under this License are granted for the term of
|
| | | copyright on the Program, and are irrevocable provided the stated
|
| | | conditions are met. This License explicitly affirms your unlimited
|
| | | permission to run the unmodified Program. The output from running a
|
| | | covered work is covered by this License only if the output, given its
|
| | | content, constitutes a covered work. This License acknowledges your
|
| | | rights of fair use or other equivalent, as provided by copyright law.
|
| | |
|
| | | You may make, run and propagate covered works that you do not
|
| | | convey, without conditions so long as your license otherwise remains
|
| | | in force. You may convey covered works to others for the sole purpose
|
| | | of having them make modifications exclusively for you, or provide you
|
| | | with facilities for running those works, provided that you comply with
|
| | | the terms of this License in conveying all material for which you do
|
| | | not control copyright. Those thus making or running the covered works
|
| | | for you must do so exclusively on your behalf, under your direction
|
| | | and control, on terms that prohibit them from making any copies of
|
| | | your copyrighted material outside their relationship with you.
|
| | |
|
| | | Conveying under any other circumstances is permitted solely under
|
| | | the conditions stated below. Sublicensing is not allowed; section 10
|
| | | makes it unnecessary.
|
| | |
|
| | | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
| | |
|
| | | No covered work shall be deemed part of an effective technological
|
| | | measure under any applicable law fulfilling obligations under article
|
| | | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
| | | similar laws prohibiting or restricting circumvention of such
|
| | | measures.
|
| | |
|
| | | When you convey a covered work, you waive any legal power to forbid
|
| | | circumvention of technological measures to the extent such circumvention
|
| | | is effected by exercising rights under this License with respect to
|
| | | the covered work, and you disclaim any intention to limit operation or
|
| | | modification of the work as a means of enforcing, against the work's
|
| | | users, your or third parties' legal rights to forbid circumvention of
|
| | | technological measures.
|
| | |
|
| | | 4. Conveying Verbatim Copies.
|
| | |
|
| | | You may convey verbatim copies of the Program's source code as you
|
| | | receive it, in any medium, provided that you conspicuously and
|
| | | appropriately publish on each copy an appropriate copyright notice;
|
| | | keep intact all notices stating that this License and any
|
| | | non-permissive terms added in accord with section 7 apply to the code;
|
| | | keep intact all notices of the absence of any warranty; and give all
|
| | | recipients a copy of this License along with the Program.
|
| | |
|
| | | You may charge any price or no price for each copy that you convey,
|
| | | and you may offer support or warranty protection for a fee.
|
| | |
|
| | | 5. Conveying Modified Source Versions.
|
| | |
|
| | | You may convey a work based on the Program, or the modifications to
|
| | | produce it from the Program, in the form of source code under the
|
| | | terms of section 4, provided that you also meet all of these conditions:
|
| | |
|
| | | a) The work must carry prominent notices stating that you modified
|
| | | it, and giving a relevant date.
|
| | |
|
| | | b) The work must carry prominent notices stating that it is
|
| | | released under this License and any conditions added under section
|
| | | 7. This requirement modifies the requirement in section 4 to
|
| | | "keep intact all notices".
|
| | |
|
| | | c) You must license the entire work, as a whole, under this
|
| | | License to anyone who comes into possession of a copy. This
|
| | | License will therefore apply, along with any applicable section 7
|
| | | additional terms, to the whole of the work, and all its parts,
|
| | | regardless of how they are packaged. This License gives no
|
| | | permission to license the work in any other way, but it does not
|
| | | invalidate such permission if you have separately received it.
|
| | |
|
| | | d) If the work has interactive user interfaces, each must display
|
| | | Appropriate Legal Notices; however, if the Program has interactive
|
| | | interfaces that do not display Appropriate Legal Notices, your
|
| | | work need not make them do so.
|
| | |
|
| | | A compilation of a covered work with other separate and independent
|
| | | works, which are not by their nature extensions of the covered work,
|
| | | and which are not combined with it such as to form a larger program,
|
| | | in or on a volume of a storage or distribution medium, is called an
|
| | | "aggregate" if the compilation and its resulting copyright are not
|
| | | used to limit the access or legal rights of the compilation's users
|
| | | beyond what the individual works permit. Inclusion of a covered work
|
| | | in an aggregate does not cause this License to apply to the other
|
| | | parts of the aggregate.
|
| | |
|
| | | 6. Conveying Non-Source Forms.
|
| | |
|
| | | You may convey a covered work in object code form under the terms
|
| | | of sections 4 and 5, provided that you also convey the
|
| | | machine-readable Corresponding Source under the terms of this License,
|
| | | in one of these ways:
|
| | |
|
| | | a) Convey the object code in, or embodied in, a physical product
|
| | | (including a physical distribution medium), accompanied by the
|
| | | Corresponding Source fixed on a durable physical medium
|
| | | customarily used for software interchange.
|
| | |
|
| | | b) Convey the object code in, or embodied in, a physical product
|
| | | (including a physical distribution medium), accompanied by a
|
| | | written offer, valid for at least three years and valid for as
|
| | | long as you offer spare parts or customer support for that product
|
| | | model, to give anyone who possesses the object code either (1) a
|
| | | copy of the Corresponding Source for all the software in the
|
| | | product that is covered by this License, on a durable physical
|
| | | medium customarily used for software interchange, for a price no
|
| | | more than your reasonable cost of physically performing this
|
| | | conveying of source, or (2) access to copy the
|
| | | Corresponding Source from a network server at no charge.
|
| | |
|
| | | c) Convey individual copies of the object code with a copy of the
|
| | | written offer to provide the Corresponding Source. This
|
| | | alternative is allowed only occasionally and noncommercially, and
|
| | | only if you received the object code with such an offer, in accord
|
| | | with subsection 6b.
|
| | |
|
| | | d) Convey the object code by offering access from a designated
|
| | | place (gratis or for a charge), and offer equivalent access to the
|
| | | Corresponding Source in the same way through the same place at no
|
| | | further charge. You need not require recipients to copy the
|
| | | Corresponding Source along with the object code. If the place to
|
| | | copy the object code is a network server, the Corresponding Source
|
| | | may be on a different server (operated by you or a third party)
|
| | | that supports equivalent copying facilities, provided you maintain
|
| | | clear directions next to the object code saying where to find the
|
| | | Corresponding Source. Regardless of what server hosts the
|
| | | Corresponding Source, you remain obligated to ensure that it is
|
| | | available for as long as needed to satisfy these requirements.
|
| | |
|
| | | e) Convey the object code using peer-to-peer transmission, provided
|
| | | you inform other peers where the object code and Corresponding
|
| | | Source of the work are being offered to the general public at no
|
| | | charge under subsection 6d.
|
| | |
|
| | | A separable portion of the object code, whose source code is excluded
|
| | | from the Corresponding Source as a System Library, need not be
|
| | | included in conveying the object code work.
|
| | |
|
| | | A "User Product" is either (1) a "consumer product", which means any
|
| | | tangible personal property which is normally used for personal, family,
|
| | | or household purposes, or (2) anything designed or sold for incorporation
|
| | | into a dwelling. In determining whether a product is a consumer product,
|
| | | doubtful cases shall be resolved in favor of coverage. For a particular
|
| | | product received by a particular user, "normally used" refers to a
|
| | | typical or common use of that class of product, regardless of the status
|
| | | of the particular user or of the way in which the particular user
|
| | | actually uses, or expects or is expected to use, the product. A product
|
| | | is a consumer product regardless of whether the product has substantial
|
| | | commercial, industrial or non-consumer uses, unless such uses represent
|
| | | the only significant mode of use of the product.
|
| | |
|
| | | "Installation Information" for a User Product means any methods,
|
| | | procedures, authorization keys, or other information required to install
|
| | | and execute modified versions of a covered work in that User Product from
|
| | | a modified version of its Corresponding Source. The information must
|
| | | suffice to ensure that the continued functioning of the modified object
|
| | | code is in no case prevented or interfered with solely because
|
| | | modification has been made.
|
| | |
|
| | | If you convey an object code work under this section in, or with, or
|
| | | specifically for use in, a User Product, and the conveying occurs as
|
| | | part of a transaction in which the right of possession and use of the
|
| | | User Product is transferred to the recipient in perpetuity or for a
|
| | | fixed term (regardless of how the transaction is characterized), the
|
| | | Corresponding Source conveyed under this section must be accompanied
|
| | | by the Installation Information. But this requirement does not apply
|
| | | if neither you nor any third party retains the ability to install
|
| | | modified object code on the User Product (for example, the work has
|
| | | been installed in ROM).
|
| | |
|
| | | The requirement to provide Installation Information does not include a
|
| | | requirement to continue to provide support service, warranty, or updates
|
| | | for a work that has been modified or installed by the recipient, or for
|
| | | the User Product in which it has been modified or installed. Access to a
|
| | | network may be denied when the modification itself materially and
|
| | | adversely affects the operation of the network or violates the rules and
|
| | | protocols for communication across the network.
|
| | |
|
| | | Corresponding Source conveyed, and Installation Information provided,
|
| | | in accord with this section must be in a format that is publicly
|
| | | documented (and with an implementation available to the public in
|
| | | source code form), and must require no special password or key for
|
| | | unpacking, reading or copying.
|
| | |
|
| | | 7. Additional Terms.
|
| | |
|
| | | "Additional permissions" are terms that supplement the terms of this
|
| | | License by making exceptions from one or more of its conditions.
|
| | | Additional permissions that are applicable to the entire Program shall
|
| | | be treated as though they were included in this License, to the extent
|
| | | that they are valid under applicable law. If additional permissions
|
| | | apply only to part of the Program, that part may be used separately
|
| | | under those permissions, but the entire Program remains governed by
|
| | | this License without regard to the additional permissions.
|
| | |
|
| | | When you convey a copy of a covered work, you may at your option
|
| | | remove any additional permissions from that copy, or from any part of
|
| | | it. (Additional permissions may be written to require their own
|
| | | removal in certain cases when you modify the work.) You may place
|
| | | additional permissions on material, added by you to a covered work,
|
| | | for which you have or can give appropriate copyright permission.
|
| | |
|
| | | Notwithstanding any other provision of this License, for material you
|
| | | add to a covered work, you may (if authorized by the copyright holders of
|
| | | that material) supplement the terms of this License with terms:
|
| | |
|
| | | a) Disclaiming warranty or limiting liability differently from the
|
| | | terms of sections 15 and 16 of this License; or
|
| | |
|
| | | b) Requiring preservation of specified reasonable legal notices or
|
| | | author attributions in that material or in the Appropriate Legal
|
| | | Notices displayed by works containing it; or
|
| | |
|
| | | c) Prohibiting misrepresentation of the origin of that material, or
|
| | | requiring that modified versions of such material be marked in
|
| | | reasonable ways as different from the original version; or
|
| | |
|
| | | d) Limiting the use for publicity purposes of names of licensors or
|
| | | authors of the material; or
|
| | |
|
| | | e) Declining to grant rights under trademark law for use of some
|
| | | trade names, trademarks, or service marks; or
|
| | |
|
| | | f) Requiring indemnification of licensors and authors of that
|
| | | material by anyone who conveys the material (or modified versions of
|
| | | it) with contractual assumptions of liability to the recipient, for
|
| | | any liability that these contractual assumptions directly impose on
|
| | | those licensors and authors.
|
| | |
|
| | | All other non-permissive additional terms are considered "further
|
| | | restrictions" within the meaning of section 10. If the Program as you
|
| | | received it, or any part of it, contains a notice stating that it is
|
| | | governed by this License along with a term that is a further
|
| | | restriction, you may remove that term. If a license document contains
|
| | | a further restriction but permits relicensing or conveying under this
|
| | | License, you may add to a covered work material governed by the terms
|
| | | of that license document, provided that the further restriction does
|
| | | not survive such relicensing or conveying.
|
| | |
|
| | | If you add terms to a covered work in accord with this section, you
|
| | | must place, in the relevant source files, a statement of the
|
| | | additional terms that apply to those files, or a notice indicating
|
| | | where to find the applicable terms.
|
| | |
|
| | | Additional terms, permissive or non-permissive, may be stated in the
|
| | | form of a separately written license, or stated as exceptions;
|
| | | the above requirements apply either way.
|
| | |
|
| | | 8. Termination.
|
| | |
|
| | | You may not propagate or modify a covered work except as expressly
|
| | | provided under this License. Any attempt otherwise to propagate or
|
| | | modify it is void, and will automatically terminate your rights under
|
| | | this License (including any patent licenses granted under the third
|
| | | paragraph of section 11).
|
| | |
|
| | | However, if you cease all violation of this License, then your
|
| | | license from a particular copyright holder is reinstated (a)
|
| | | provisionally, unless and until the copyright holder explicitly and
|
| | | finally terminates your license, and (b) permanently, if the copyright
|
| | | holder fails to notify you of the violation by some reasonable means
|
| | | prior to 60 days after the cessation.
|
| | |
|
| | | Moreover, your license from a particular copyright holder is
|
| | | reinstated permanently if the copyright holder notifies you of the
|
| | | violation by some reasonable means, this is the first time you have
|
| | | received notice of violation of this License (for any work) from that
|
| | | copyright holder, and you cure the violation prior to 30 days after
|
| | | your receipt of the notice.
|
| | |
|
| | | Termination of your rights under this section does not terminate the
|
| | | licenses of parties who have received copies or rights from you under
|
| | | this License. If your rights have been terminated and not permanently
|
| | | reinstated, you do not qualify to receive new licenses for the same
|
| | | material under section 10.
|
| | |
|
| | | 9. Acceptance Not Required for Having Copies.
|
| | |
|
| | | You are not required to accept this License in order to receive or
|
| | | run a copy of the Program. Ancillary propagation of a covered work
|
| | | occurring solely as a consequence of using peer-to-peer transmission
|
| | | to receive a copy likewise does not require acceptance. However,
|
| | | nothing other than this License grants you permission to propagate or
|
| | | modify any covered work. These actions infringe copyright if you do
|
| | | not accept this License. Therefore, by modifying or propagating a
|
| | | covered work, you indicate your acceptance of this License to do so.
|
| | |
|
| | | 10. Automatic Licensing of Downstream Recipients.
|
| | |
|
| | | Each time you convey a covered work, the recipient automatically
|
| | | receives a license from the original licensors, to run, modify and
|
| | | propagate that work, subject to this License. You are not responsible
|
| | | for enforcing compliance by third parties with this License.
|
| | |
|
| | | An "entity transaction" is a transaction transferring control of an
|
| | | organization, or substantially all assets of one, or subdividing an
|
| | | organization, or merging organizations. If propagation of a covered
|
| | | work results from an entity transaction, each party to that
|
| | | transaction who receives a copy of the work also receives whatever
|
| | | licenses to the work the party's predecessor in interest had or could
|
| | | give under the previous paragraph, plus a right to possession of the
|
| | | Corresponding Source of the work from the predecessor in interest, if
|
| | | the predecessor has it or can get it with reasonable efforts.
|
| | |
|
| | | You may not impose any further restrictions on the exercise of the
|
| | | rights granted or affirmed under this License. For example, you may
|
| | | not impose a license fee, royalty, or other charge for exercise of
|
| | | rights granted under this License, and you may not initiate litigation
|
| | | (including a cross-claim or counterclaim in a lawsuit) alleging that
|
| | | any patent claim is infringed by making, using, selling, offering for
|
| | | sale, or importing the Program or any portion of it.
|
| | |
|
| | | 11. Patents.
|
| | |
|
| | | A "contributor" is a copyright holder who authorizes use under this
|
| | | License of the Program or a work on which the Program is based. The
|
| | | work thus licensed is called the contributor's "contributor version".
|
| | |
|
| | | A contributor's "essential patent claims" are all patent claims
|
| | | owned or controlled by the contributor, whether already acquired or
|
| | | hereafter acquired, that would be infringed by some manner, permitted
|
| | | by this License, of making, using, or selling its contributor version,
|
| | | but do not include claims that would be infringed only as a
|
| | | consequence of further modification of the contributor version. For
|
| | | purposes of this definition, "control" includes the right to grant
|
| | | patent sublicenses in a manner consistent with the requirements of
|
| | | this License.
|
| | |
|
| | | Each contributor grants you a non-exclusive, worldwide, royalty-free
|
| | | patent license under the contributor's essential patent claims, to
|
| | | make, use, sell, offer for sale, import and otherwise run, modify and
|
| | | propagate the contents of its contributor version.
|
| | |
|
| | | In the following three paragraphs, a "patent license" is any express
|
| | | agreement or commitment, however denominated, not to enforce a patent
|
| | | (such as an express permission to practice a patent or covenant not to
|
| | | sue for patent infringement). To "grant" such a patent license to a
|
| | | party means to make such an agreement or commitment not to enforce a
|
| | | patent against the party.
|
| | |
|
| | | If you convey a covered work, knowingly relying on a patent license,
|
| | | and the Corresponding Source of the work is not available for anyone
|
| | | to copy, free of charge and under the terms of this License, through a
|
| | | publicly available network server or other readily accessible means,
|
| | | then you must either (1) cause the Corresponding Source to be so
|
| | | available, or (2) arrange to deprive yourself of the benefit of the
|
| | | patent license for this particular work, or (3) arrange, in a manner
|
| | | consistent with the requirements of this License, to extend the patent
|
| | | license to downstream recipients. "Knowingly relying" means you have
|
| | | actual knowledge that, but for the patent license, your conveying the
|
| | | covered work in a country, or your recipient's use of the covered work
|
| | | in a country, would infringe one or more identifiable patents in that
|
| | | country that you have reason to believe are valid.
|
| | |
|
| | | If, pursuant to or in connection with a single transaction or
|
| | | arrangement, you convey, or propagate by procuring conveyance of, a
|
| | | covered work, and grant a patent license to some of the parties
|
| | | receiving the covered work authorizing them to use, propagate, modify
|
| | | or convey a specific copy of the covered work, then the patent license
|
| | | you grant is automatically extended to all recipients of the covered
|
| | | work and works based on it.
|
| | |
|
| | | A patent license is "discriminatory" if it does not include within
|
| | | the scope of its coverage, prohibits the exercise of, or is
|
| | | conditioned on the non-exercise of one or more of the rights that are
|
| | | specifically granted under this License. You may not convey a covered
|
| | | work if you are a party to an arrangement with a third party that is
|
| | | in the business of distributing software, under which you make payment
|
| | | to the third party based on the extent of your activity of conveying
|
| | | the work, and under which the third party grants, to any of the
|
| | | parties who would receive the covered work from you, a discriminatory
|
| | | patent license (a) in connection with copies of the covered work
|
| | | conveyed by you (or copies made from those copies), or (b) primarily
|
| | | for and in connection with specific products or compilations that
|
| | | contain the covered work, unless you entered into that arrangement,
|
| | | or that patent license was granted, prior to 28 March 2007.
|
| | |
|
| | | Nothing in this License shall be construed as excluding or limiting
|
| | | any implied license or other defenses to infringement that may
|
| | | otherwise be available to you under applicable patent law.
|
| | |
|
| | | 12. No Surrender of Others' Freedom.
|
| | |
|
| | | If conditions are imposed on you (whether by court order, agreement or
|
| | | otherwise) that contradict the conditions of this License, they do not
|
| | | excuse you from the conditions of this License. If you cannot convey a
|
| | | covered work so as to satisfy simultaneously your obligations under this
|
| | | License and any other pertinent obligations, then as a consequence you may
|
| | | not convey it at all. For example, if you agree to terms that obligate you
|
| | | to collect a royalty for further conveying from those to whom you convey
|
| | | the Program, the only way you could satisfy both those terms and this
|
| | | License would be to refrain entirely from conveying the Program.
|
| | |
|
| | | 13. Use with the GNU Affero General Public License.
|
| | |
|
| | | Notwithstanding any other provision of this License, you have
|
| | | permission to link or combine any covered work with a work licensed
|
| | | under version 3 of the GNU Affero General Public License into a single
|
| | | combined work, and to convey the resulting work. The terms of this
|
| | | License will continue to apply to the part which is the covered work,
|
| | | but the special requirements of the GNU Affero General Public License,
|
| | | section 13, concerning interaction through a network will apply to the
|
| | | combination as such.
|
| | |
|
| | | 14. Revised Versions of this License.
|
| | |
|
| | | The Free Software Foundation may publish revised and/or new versions of
|
| | | the GNU General Public License from time to time. Such new versions will
|
| | | be similar in spirit to the present version, but may differ in detail to
|
| | | address new problems or concerns.
|
| | |
|
| | | Each version is given a distinguishing version number. If the
|
| | | Program specifies that a certain numbered version of the GNU General
|
| | | Public License "or any later version" applies to it, you have the
|
| | | option of following the terms and conditions either of that numbered
|
| | | version or of any later version published by the Free Software
|
| | | Foundation. If the Program does not specify a version number of the
|
| | | GNU General Public License, you may choose any version ever published
|
| | | by the Free Software Foundation.
|
| | |
|
| | | If the Program specifies that a proxy can decide which future
|
| | | versions of the GNU General Public License can be used, that proxy's
|
| | | public statement of acceptance of a version permanently authorizes you
|
| | | to choose that version for the Program.
|
| | |
|
| | | Later license versions may give you additional or different
|
| | | permissions. However, no additional obligations are imposed on any
|
| | | author or copyright holder as a result of your choosing to follow a
|
| | | later version.
|
| | |
|
| | | 15. Disclaimer of Warranty.
|
| | |
|
| | | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
| | | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
| | | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
| | | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
| | | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| | | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
| | | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
| | | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
| | |
|
| | | 16. Limitation of Liability.
|
| | |
|
| | | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
| | | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
| | | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
| | | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
| | | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
| | | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
| | | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
| | | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
| | | SUCH DAMAGES.
|
| | |
|
| | | 17. Interpretation of Sections 15 and 16.
|
| | |
|
| | | If the disclaimer of warranty and limitation of liability provided
|
| | | above cannot be given local legal effect according to their terms,
|
| | | reviewing courts shall apply local law that most closely approximates
|
| | | an absolute waiver of all civil liability in connection with the
|
| | | Program, unless a warranty or assumption of liability accompanies a
|
| | | copy of the Program in return for a fee.
|
| | |
|
| | | END OF TERMS AND CONDITIONS
|
| | |
|
| | | How to Apply These Terms to Your New Programs
|
| | |
|
| | | If you develop a new program, and you want it to be of the greatest
|
| | | possible use to the public, the best way to achieve this is to make it
|
| | | free software which everyone can redistribute and change under these terms.
|
| | |
|
| | | To do so, attach the following notices to the program. It is safest
|
| | | to attach them to the start of each source file to most effectively
|
| | | state the exclusion of warranty; and each file should have at least
|
| | | the "copyright" line and a pointer to where the full notice is found.
|
| | |
|
| | | <one line to give the program's name and a brief idea of what it does.>
|
| | | Copyright (C) <year> <name of author>
|
| | |
|
| | | This program 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.
|
| | |
|
| | | This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
| | |
|
| | | Also add information on how to contact you by electronic and paper mail.
|
| | |
|
| | | If the program does terminal interaction, make it output a short
|
| | | notice like this when it starts in an interactive mode:
|
| | |
|
| | | <program> Copyright (C) <year> <name of author>
|
| | | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
| | | This is free software, and you are welcome to redistribute it
|
| | | under certain conditions; type `show c' for details.
|
| | |
|
| | | The hypothetical commands `show w' and `show c' should show the appropriate
|
| | | parts of the General Public License. Of course, your program's commands
|
| | | might be different; for a GUI interface, you would use an "about box".
|
| | |
|
| | | You should also get your employer (if you work as a programmer) or school,
|
| | | if any, to sign a "copyright disclaimer" for the program, if necessary.
|
| | | For more information on this, and how to apply and follow the GNU GPL, see
|
| | | <http://www.gnu.org/licenses/>.
|
| | |
|
| | | The GNU General Public License does not permit incorporating your program
|
| | | into proprietary programs. If your program is a subroutine library, you
|
| | | may consider it more useful to permit linking proprietary applications with
|
| | | the library. If this is what you want to do, use the GNU Lesser General
|
| | | Public License instead of this License. But first, please read
|
| | | <http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "evalhandler.h"
|
| | |
|
| | | void EvalHandler::message(int type, const QString &msg, const QString &fileName, int lineNo)
|
| | | {
|
| | | Q_UNUSED(type);
|
| | | Q_UNUSED(msg);
|
| | | Q_UNUSED(fileName);
|
| | | Q_UNUSED(lineNo);
|
| | | }
|
| | |
|
| | | void EvalHandler::fileMessage(const QString &msg)
|
| | | {
|
| | | Q_UNUSED(msg);
|
| | | }
|
| | |
|
| | | void EvalHandler::aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type)
|
| | | {
|
| | | Q_UNUSED(parent);
|
| | | Q_UNUSED(proFile);
|
| | | Q_UNUSED(type);
|
| | | }
|
| | |
|
| | | void EvalHandler::doneWithEval(ProFile *parent)
|
| | | {
|
| | | Q_UNUSED(parent);
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef EVALHANDLER_H
|
| | | #define EVALHANDLER_H
|
| | |
|
| | | #include <qmakeevaluator.h>
|
| | |
|
| | | /**
|
| | | * Dummy handler to please qmake's parser.
|
| | | */
|
| | | class EvalHandler : public QMakeHandler
|
| | | {
|
| | | public:
|
| | | void message(int type, const QString &msg, const QString &fileName, int lineNo);
|
| | | void fileMessage(const QString &msg);
|
| | | void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type);
|
| | | void doneWithEval(ProFile *parent);
|
| | | };
|
| | |
|
| | | #endif // EVALHANDLER_H
|
New file |
| | |
| | | This is a copy of qmake's parser and evaluator from qmake/library
|
| | | directory in the qtbase repository at git://gitorious.org/qt/qtbase.git.
|
| | | It has been taken at 5e525d283d308fe462e83955996fc53d80465c1b.
|
| | |
|
| | | If you do changes to these files, please make sure they are upstreamed!
|
| | |
|
New file |
| | |
| | | INCLUDEPATH *= $$PWD
|
| | | DEPENDPATH *= $$PWD
|
| | |
|
| | | INCLUDEPATH += \
|
| | | $$QMAKE_PARSER_DIR
|
| | |
|
| | | HEADERS += \
|
| | | $$PWD/ioutils.h \
|
| | | $$PWD/proitems.h \
|
| | | $$PWD/qmakeevaluator.h \
|
| | | $$PWD/qmakeevaluator_p.h \
|
| | | $$PWD/qmakeglobals.h \
|
| | | $$PWD/qmakeparser.h \
|
| | | $$PWD/qmake_global.h
|
| | |
|
| | | SOURCES += \
|
| | | $$PWD/ioutils.cpp \
|
| | | $$PWD/proitems.cpp \
|
| | | $$PWD/qmakebuiltins.cpp \
|
| | | $$PWD/qmakeevaluator.cpp \
|
| | | $$PWD/qmakeglobals.cpp \
|
| | | $$PWD/qmakeparser.cpp
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "ioutils.h"
|
| | |
|
| | | #include <qdir.h>
|
| | | #include <qfile.h>
|
| | |
|
| | | #ifdef Q_OS_WIN
|
| | | # include <windows.h>
|
| | | #else
|
| | | # include <sys/types.h>
|
| | | # include <sys/stat.h>
|
| | | # include <unistd.h>
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | using namespace QMakeInternal;
|
| | |
|
| | | IoUtils::FileType IoUtils::fileType(const QString &fileName)
|
| | | {
|
| | | Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName));
|
| | | #ifdef Q_OS_WIN
|
| | | DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16());
|
| | | if (attr == INVALID_FILE_ATTRIBUTES)
|
| | | return FileNotFound;
|
| | | return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular;
|
| | | #else
|
| | | struct ::stat st;
|
| | | if (::stat(fileName.toLocal8Bit().constData(), &st))
|
| | | return FileNotFound;
|
| | | return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular;
|
| | | #endif
|
| | | }
|
| | |
|
| | | bool IoUtils::isRelativePath(const QString &path)
|
| | | {
|
| | | if (path.startsWith(QLatin1Char('/')))
|
| | | return false;
|
| | | #ifdef Q_OS_WIN
|
| | | if (path.startsWith(QLatin1Char('\\')))
|
| | | return false;
|
| | | // Unlike QFileInfo, this won't accept a relative path with a drive letter.
|
| | | // Such paths result in a royal mess anyway ...
|
| | | if (path.length() >= 3 && path.at(1) == QLatin1Char(':') && path.at(0).isLetter()
|
| | | && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\')))
|
| | | return false;
|
| | | #endif
|
| | | return true;
|
| | | }
|
| | |
|
| | | QStringRef IoUtils::fileName(const QString &fileName)
|
| | | {
|
| | | return fileName.midRef(fileName.lastIndexOf(QLatin1Char('/')) + 1);
|
| | | }
|
| | |
|
| | | QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
|
| | | {
|
| | | if (fileName.isEmpty())
|
| | | return QString();
|
| | | if (isAbsolutePath(fileName))
|
| | | return QDir::cleanPath(fileName);
|
| | | return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
|
| | | }
|
| | |
|
| | | inline static
|
| | | bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
|
| | | {
|
| | | for (int x = arg.length() - 1; x >= 0; --x) {
|
| | | ushort c = arg.unicode()[x].unicode();
|
| | | if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
|
| | | return true;
|
| | | }
|
| | | return false;
|
| | | }
|
| | |
|
| | | QString IoUtils::shellQuoteUnix(const QString &arg)
|
| | | {
|
| | | // Chars that should be quoted (TM). This includes:
|
| | | static const uchar iqm[] = {
|
| | | 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
|
| | | 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
|
| | | }; // 0-32 \'"$`<>|;&(){}*?#!~[]
|
| | |
|
| | | if (!arg.length())
|
| | | return QString::fromLatin1("\"\"");
|
| | |
|
| | | QString ret(arg);
|
| | | if (hasSpecialChars(ret, iqm)) {
|
| | | ret.replace(QLatin1Char('\''), QLatin1String("'\\''"));
|
| | | ret.prepend(QLatin1Char('\''));
|
| | | ret.append(QLatin1Char('\''));
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QString IoUtils::shellQuoteWin(const QString &arg)
|
| | | {
|
| | | // Chars that should be quoted (TM). This includes:
|
| | | // - control chars & space
|
| | | // - the shell meta chars "&()<>^|
|
| | | // - the potential separators ,;=
|
| | | static const uchar iqm[] = {
|
| | | 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
|
| | | 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
|
| | | };
|
| | |
|
| | | if (!arg.length())
|
| | | return QString::fromLatin1("\"\"");
|
| | |
|
| | | QString ret(arg);
|
| | | if (hasSpecialChars(ret, iqm)) {
|
| | | // Quotes are escaped and their preceding backslashes are doubled.
|
| | | // It's impossible to escape anything inside a quoted string on cmd
|
| | | // level, so the outer quoting must be "suspended".
|
| | | ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\""));
|
| | | // The argument must not end with a \ since this would be interpreted
|
| | | // as escaping the quote -- rather put the \ behind the quote: e.g.
|
| | | // rather use "foo"\ than "foo\"
|
| | | int i = ret.length();
|
| | | while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
|
| | | --i;
|
| | | ret.insert(i, QLatin1Char('"'));
|
| | | ret.prepend(QLatin1Char('"'));
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef IOUTILS_H
|
| | | #define IOUTILS_H
|
| | |
|
| | | #include <qstring.h>
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | namespace QMakeInternal {
|
| | |
|
| | | /*!
|
| | | This class provides replacement functionality for QFileInfo, QFile & QDir,
|
| | | as these are abysmally slow.
|
| | | */
|
| | | class IoUtils {
|
| | | public:
|
| | | enum FileType {
|
| | | FileNotFound = 0,
|
| | | FileIsRegular = 1,
|
| | | FileIsDir = 2
|
| | | };
|
| | |
|
| | | static FileType fileType(const QString &fileName);
|
| | | static bool exists(const QString &fileName) { return fileType(fileName) != FileNotFound; }
|
| | | static bool isRelativePath(const QString &fileName);
|
| | | static bool isAbsolutePath(const QString &fileName) { return !isRelativePath(fileName); }
|
| | | static QStringRef fileName(const QString &fileName); // Requires normalized path
|
| | | static QString resolvePath(const QString &baseDir, const QString &fileName);
|
| | | static QString shellQuoteUnix(const QString &arg);
|
| | | static QString shellQuoteWin(const QString &arg);
|
| | | static QString shellQuote(const QString &arg)
|
| | | #ifdef Q_OS_UNIX
|
| | | { return shellQuoteUnix(arg); }
|
| | | #else
|
| | | { return shellQuoteWin(arg); }
|
| | | #endif
|
| | | };
|
| | |
|
| | | } // namespace ProFileEvaluatorInternal
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // IOUTILS_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "proitems.h"
|
| | |
|
| | | #include <qfileinfo.h>
|
| | | #include <qset.h>
|
| | | #include <qstringlist.h>
|
| | | #include <qtextstream.h>
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | // from qhash.cpp
|
| | | uint ProString::hash(const QChar *p, int n)
|
| | | {
|
| | | uint h = 0;
|
| | |
|
| | | while (n--) {
|
| | | h = (h << 4) + (*p++).unicode();
|
| | | h ^= (h & 0xf0000000) >> 23;
|
| | | h &= 0x0fffffff;
|
| | | }
|
| | | return h;
|
| | | }
|
| | |
|
| | | ProString::ProString() :
|
| | | m_offset(0), m_length(0), m_file(0), m_hash(0x80000000)
|
| | | {
|
| | | }
|
| | |
|
| | | ProString::ProString(const ProString &other) :
|
| | | m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(other.m_hash)
|
| | | {
|
| | | }
|
| | |
|
| | | ProString::ProString(const ProString &other, OmitPreHashing) :
|
| | | m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000)
|
| | | {
|
| | | }
|
| | |
|
| | | ProString::ProString(const QString &str, DoPreHashing) :
|
| | | m_string(str), m_offset(0), m_length(str.length()), m_file(0)
|
| | | {
|
| | | updatedHash();
|
| | | }
|
| | |
|
| | | ProString::ProString(const QString &str) :
|
| | | m_string(str), m_offset(0), m_length(str.length()), m_file(0), m_hash(0x80000000)
|
| | | {
|
| | | }
|
| | |
|
| | | ProString::ProString(const char *str, DoPreHashing) :
|
| | | m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0)
|
| | | {
|
| | | updatedHash();
|
| | | }
|
| | |
|
| | | ProString::ProString(const char *str) :
|
| | | m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0), m_hash(0x80000000)
|
| | | {
|
| | | }
|
| | |
|
| | | ProString::ProString(const QString &str, int offset, int length, DoPreHashing) :
|
| | | m_string(str), m_offset(offset), m_length(length), m_file(0)
|
| | | {
|
| | | updatedHash();
|
| | | }
|
| | |
|
| | | ProString::ProString(const QString &str, int offset, int length, uint hash) :
|
| | | m_string(str), m_offset(offset), m_length(length), m_file(0), m_hash(hash)
|
| | | {
|
| | | }
|
| | |
|
| | | ProString::ProString(const QString &str, int offset, int length) :
|
| | | m_string(str), m_offset(offset), m_length(length), m_file(0), m_hash(0x80000000)
|
| | | {
|
| | | }
|
| | |
|
| | | void ProString::setValue(const QString &str)
|
| | | {
|
| | | m_string = str, m_offset = 0, m_length = str.length(), m_hash = 0x80000000;
|
| | | }
|
| | |
|
| | | uint ProString::updatedHash() const
|
| | | {
|
| | | return (m_hash = hash(m_string.constData() + m_offset, m_length));
|
| | | }
|
| | |
|
| | | uint qHash(const ProString &str)
|
| | | {
|
| | | if (!(str.m_hash & 0x80000000))
|
| | | return str.m_hash;
|
| | | return str.updatedHash();
|
| | | }
|
| | |
|
| | | ProKey::ProKey(const QString &str) :
|
| | | ProString(str, DoHash)
|
| | | {
|
| | | }
|
| | |
|
| | | ProKey::ProKey(const char *str) :
|
| | | ProString(str, DoHash)
|
| | | {
|
| | | }
|
| | |
|
| | | ProKey::ProKey(const QString &str, int off, int len) :
|
| | | ProString(str, off, len, DoHash)
|
| | | {
|
| | | }
|
| | |
|
| | | ProKey::ProKey(const QString &str, int off, int len, uint hash) :
|
| | | ProString(str, off, len, hash)
|
| | | {
|
| | | }
|
| | |
|
| | | void ProKey::setValue(const QString &str)
|
| | | {
|
| | | m_string = str, m_offset = 0, m_length = str.length();
|
| | | updatedHash();
|
| | | }
|
| | |
|
| | | QString ProString::toQString() const
|
| | | {
|
| | | return m_string.mid(m_offset, m_length);
|
| | | }
|
| | |
|
| | | QString &ProString::toQString(QString &tmp) const
|
| | | {
|
| | | return tmp.setRawData(m_string.constData() + m_offset, m_length);
|
| | | }
|
| | |
|
| | | QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget)
|
| | | {
|
| | | if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) {
|
| | | m_string.reserve(0); // Prevent the resize() below from reallocating
|
| | | QChar *ptr = (QChar *)m_string.constData();
|
| | | if (m_offset != thisTarget)
|
| | | memmove(ptr + thisTarget, ptr + m_offset, m_length * 2);
|
| | | ptr += extraTarget;
|
| | | m_offset = 0;
|
| | | m_length += extraLen;
|
| | | m_string.resize(m_length);
|
| | | m_hash = 0x80000000;
|
| | | return ptr;
|
| | | } else {
|
| | | QString neu(m_length + extraLen, Qt::Uninitialized);
|
| | | QChar *ptr = (QChar *)neu.constData();
|
| | | memcpy(ptr + thisTarget, m_string.constData() + m_offset, m_length * 2);
|
| | | ptr += extraTarget;
|
| | | *this = ProString(neu);
|
| | | return ptr;
|
| | | }
|
| | | }
|
| | |
|
| | | ProString &ProString::prepend(const ProString &other)
|
| | | {
|
| | | if (other.m_length) {
|
| | | if (!m_length) {
|
| | | *this = other;
|
| | | } else {
|
| | | QChar *ptr = prepareExtend(other.m_length, other.m_length, 0);
|
| | | memcpy(ptr, other.constData(), other.m_length * 2);
|
| | | if (!m_file)
|
| | | m_file = other.m_file;
|
| | | }
|
| | | }
|
| | | return *this;
|
| | | }
|
| | |
|
| | | ProString &ProString::append(const QLatin1String other)
|
| | | {
|
| | | const char *latin1 = other.latin1();
|
| | | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
| | | int size = other.size();
|
| | | #else
|
| | | int size = strlen(latin1);
|
| | | #endif
|
| | | if (size) {
|
| | | QChar *ptr = prepareExtend(size, 0, m_length);
|
| | | for (int i = 0; i < size; i++)
|
| | | *ptr++ = QLatin1Char(latin1[i]);
|
| | | }
|
| | | return *this;
|
| | | }
|
| | |
|
| | | ProString &ProString::append(QChar other)
|
| | | {
|
| | | QChar *ptr = prepareExtend(1, 0, m_length);
|
| | | *ptr = other;
|
| | | return *this;
|
| | | }
|
| | |
|
| | | // If pending != 0, prefix with space if appending to non-empty non-pending
|
| | | ProString &ProString::append(const ProString &other, bool *pending)
|
| | | {
|
| | | if (other.m_length) {
|
| | | if (!m_length) {
|
| | | *this = other;
|
| | | } else {
|
| | | QChar *ptr;
|
| | | if (pending && !*pending) {
|
| | | ptr = prepareExtend(1 + other.m_length, 0, m_length);
|
| | | *ptr++ = 32;
|
| | | } else {
|
| | | ptr = prepareExtend(other.m_length, 0, m_length);
|
| | | }
|
| | | memcpy(ptr, other.m_string.constData() + other.m_offset, other.m_length * 2);
|
| | | if (other.m_file)
|
| | | m_file = other.m_file;
|
| | | }
|
| | | if (pending)
|
| | | *pending = true;
|
| | | }
|
| | | return *this;
|
| | | }
|
| | |
|
| | | ProString &ProString::append(const ProStringList &other, bool *pending, bool skipEmpty1st)
|
| | | {
|
| | | if (const int sz = other.size()) {
|
| | | int startIdx = 0;
|
| | | if (pending && !*pending && skipEmpty1st && other.at(0).isEmpty()) {
|
| | | if (sz == 1)
|
| | | return *this;
|
| | | startIdx = 1;
|
| | | }
|
| | | if (!m_length && sz == startIdx + 1) {
|
| | | *this = other.at(startIdx);
|
| | | } else {
|
| | | int totalLength = sz - startIdx;
|
| | | for (int i = startIdx; i < sz; ++i)
|
| | | totalLength += other.at(i).size();
|
| | | bool putSpace = false;
|
| | | if (pending && !*pending && m_length)
|
| | | putSpace = true;
|
| | | else
|
| | | totalLength--;
|
| | |
|
| | | QChar *ptr = prepareExtend(totalLength, 0, m_length);
|
| | | for (int i = startIdx; i < sz; ++i) {
|
| | | if (putSpace)
|
| | | *ptr++ = 32;
|
| | | else
|
| | | putSpace = true;
|
| | | const ProString &str = other.at(i);
|
| | | memcpy(ptr, str.m_string.constData() + str.m_offset, str.m_length * 2);
|
| | | ptr += str.m_length;
|
| | | }
|
| | | if (other.last().m_file)
|
| | | m_file = other.last().m_file;
|
| | | }
|
| | | if (pending)
|
| | | *pending = true;
|
| | | }
|
| | | return *this;
|
| | | }
|
| | |
|
| | | QString operator+(const ProString &one, const ProString &two)
|
| | | {
|
| | | if (two.m_length) {
|
| | | if (!one.m_length) {
|
| | | return two.toQString();
|
| | | } else {
|
| | | QString neu(one.m_length + two.m_length, Qt::Uninitialized);
|
| | | ushort *ptr = (ushort *)neu.constData();
|
| | | memcpy(ptr, one.m_string.constData() + one.m_offset, one.m_length * 2);
|
| | | memcpy(ptr + one.m_length, two.m_string.constData() + two.m_offset, two.m_length * 2);
|
| | | return neu;
|
| | | }
|
| | | }
|
| | | return one.toQString();
|
| | | }
|
| | |
|
| | |
|
| | | ProString ProString::mid(int off, int len) const
|
| | | {
|
| | | ProString ret(*this, NoHash);
|
| | | if (off > m_length)
|
| | | off = m_length;
|
| | | ret.m_offset += off;
|
| | | ret.m_length -= off;
|
| | | if ((uint)ret.m_length > (uint)len) // Unsigned comparison to interpret < 0 as infinite
|
| | | ret.m_length = len;
|
| | | return ret;
|
| | | }
|
| | |
|
| | | ProString ProString::trimmed() const
|
| | | {
|
| | | ProString ret(*this, NoHash);
|
| | | int cur = m_offset;
|
| | | int end = cur + m_length;
|
| | | const QChar *data = m_string.constData();
|
| | | for (; cur < end; cur++)
|
| | | if (!data[cur].isSpace()) {
|
| | | // No underrun check - we know there is at least one non-whitespace
|
| | | while (data[end - 1].isSpace())
|
| | | end--;
|
| | | break;
|
| | | }
|
| | | ret.m_offset = cur;
|
| | | ret.m_length = end - cur;
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QTextStream &operator<<(QTextStream &t, const ProString &str)
|
| | | {
|
| | | t << str.toQString(); // XXX optimize ... somehow
|
| | | return t;
|
| | | }
|
| | |
|
| | | static QString ProStringList_join(const ProStringList &this_, const QChar *sep, const size_t sepSize)
|
| | | {
|
| | | int totalLength = 0;
|
| | | const int sz = this_.size();
|
| | |
|
| | | for (int i = 0; i < sz; ++i)
|
| | | totalLength += this_.at(i).size();
|
| | |
|
| | | if (sz)
|
| | | totalLength += sepSize * (sz - 1);
|
| | |
|
| | | QString res(totalLength, Qt::Uninitialized);
|
| | | QChar *ptr = (QChar *)res.constData();
|
| | | for (int i = 0; i < sz; ++i) {
|
| | | if (i) {
|
| | | memcpy(ptr, sep, sepSize * sizeof(QChar));
|
| | | ptr += sepSize;
|
| | | }
|
| | | const ProString &str = this_.at(i);
|
| | | memcpy(ptr, str.constData(), str.size() * sizeof(QChar));
|
| | | ptr += str.size();
|
| | | }
|
| | | return res;
|
| | | }
|
| | |
|
| | | QString ProStringList::join(const QString &sep) const
|
| | | {
|
| | | return ProStringList_join(*this, sep.constData(), sep.size());
|
| | | }
|
| | |
|
| | | QString ProStringList::join(QChar sep) const
|
| | | {
|
| | | return ProStringList_join(*this, &sep, 1);
|
| | | }
|
| | |
|
| | | void ProStringList::removeAll(const ProString &str)
|
| | | {
|
| | | for (int i = size(); --i >= 0; )
|
| | | if (at(i) == str)
|
| | | remove(i);
|
| | | }
|
| | |
|
| | | void ProStringList::removeAll(const char *str)
|
| | | {
|
| | | for (int i = size(); --i >= 0; )
|
| | | if (at(i) == str)
|
| | | remove(i);
|
| | | }
|
| | |
|
| | | void ProStringList::removeDuplicates()
|
| | | {
|
| | | int n = size();
|
| | | int j = 0;
|
| | | QSet<ProString> seen;
|
| | | seen.reserve(n);
|
| | | for (int i = 0; i < n; ++i) {
|
| | | const ProString &s = at(i);
|
| | | if (seen.contains(s))
|
| | | continue;
|
| | | seen.insert(s);
|
| | | if (j != i)
|
| | | (*this)[j] = s;
|
| | | ++j;
|
| | | }
|
| | | if (n != j)
|
| | | erase(begin() + j, end());
|
| | | }
|
| | |
|
| | | ProStringList::ProStringList(const QStringList &list)
|
| | | {
|
| | | reserve(list.size());
|
| | | foreach (const QString &str, list)
|
| | | *this << ProString(str);
|
| | | }
|
| | |
|
| | | QStringList ProStringList::toQStringList() const
|
| | | {
|
| | | QStringList ret;
|
| | | ret.reserve(size());
|
| | | foreach (const ProString &str, *this)
|
| | | ret << str.toQString();
|
| | | return ret;
|
| | | }
|
| | |
|
| | | bool ProStringList::contains(const ProString &str, Qt::CaseSensitivity cs) const
|
| | | {
|
| | | for (int i = 0; i < size(); i++)
|
| | | if (!at(i).compare(str, cs))
|
| | | return true;
|
| | | return false;
|
| | | }
|
| | |
|
| | | bool ProStringList::contains(const char *str, Qt::CaseSensitivity cs) const
|
| | | {
|
| | | for (int i = 0; i < size(); i++)
|
| | | if (!at(i).compare(str, cs))
|
| | | return true;
|
| | | return false;
|
| | | }
|
| | |
|
| | | ProFile::ProFile(const QString &fileName)
|
| | | : m_refCount(1),
|
| | | m_fileName(fileName),
|
| | | m_ok(true),
|
| | | m_hostBuild(false)
|
| | | {
|
| | | if (!fileName.startsWith(QLatin1Char('(')))
|
| | | m_directoryName = QFileInfo( // qmake sickness: canonicalize only the directory!
|
| | | fileName.left(fileName.lastIndexOf(QLatin1Char('/')))).canonicalFilePath();
|
| | | }
|
| | |
|
| | | ProFile::~ProFile()
|
| | | {
|
| | | }
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef PROITEMS_H
|
| | | #define PROITEMS_H
|
| | |
|
| | | #include "qmake_global.h"
|
| | |
|
| | | #include <qstring.h>
|
| | | #include <qvector.h>
|
| | | #include <qhash.h>
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | class QTextStream;
|
| | |
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | typedef QAtomicInt ProItemRefCount;
|
| | | #else
|
| | | class ProItemRefCount {
|
| | | public:
|
| | | ProItemRefCount(int cnt = 0) : m_cnt(cnt) {}
|
| | | bool ref() { return ++m_cnt != 0; }
|
| | | bool deref() { return --m_cnt != 0; }
|
| | | ProItemRefCount &operator=(int value) { m_cnt = value; return *this; }
|
| | | private:
|
| | | int m_cnt;
|
| | | };
|
| | | #endif
|
| | |
|
| | | #ifndef QT_BUILD_QMAKE
|
| | | # define PROITEM_EXPLICIT explicit
|
| | | #else
|
| | | # define PROITEM_EXPLICIT
|
| | | #endif
|
| | |
|
| | | class ProKey;
|
| | | class ProStringList;
|
| | | class ProFile;
|
| | |
|
| | | class ProString {
|
| | | public:
|
| | | ProString();
|
| | | ProString(const ProString &other);
|
| | | PROITEM_EXPLICIT ProString(const QString &str);
|
| | | PROITEM_EXPLICIT ProString(const char *str);
|
| | | ProString(const QString &str, int offset, int length);
|
| | | void setValue(const QString &str);
|
| | | void clear() { m_string.clear(); m_length = 0; }
|
| | | ProString &setSource(const ProString &other) { m_file = other.m_file; return *this; }
|
| | | ProString &setSource(const ProFile *pro) { m_file = pro; return *this; }
|
| | | const ProFile *sourceFile() const { return m_file; }
|
| | |
|
| | | ProString &prepend(const ProString &other);
|
| | | ProString &append(const ProString &other, bool *pending = 0);
|
| | | ProString &append(const QString &other) { return append(ProString(other)); }
|
| | | ProString &append(const QLatin1String other);
|
| | | ProString &append(const char *other) { return append(QLatin1String(other)); }
|
| | | ProString &append(QChar other);
|
| | | ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false);
|
| | | ProString &operator+=(const ProString &other) { return append(other); }
|
| | | ProString &operator+=(const QString &other) { return append(other); }
|
| | | ProString &operator+=(const QLatin1String other) { return append(other); }
|
| | | ProString &operator+=(const char *other) { return append(other); }
|
| | | ProString &operator+=(QChar other) { return append(other); }
|
| | |
|
| | | void chop(int n) { Q_ASSERT(n <= m_length); m_length -= n; }
|
| | | void chopFront(int n) { Q_ASSERT(n <= m_length); m_offset += n; m_length -= n; }
|
| | |
|
| | | bool operator==(const ProString &other) const { return toQStringRef() == other.toQStringRef(); }
|
| | | bool operator==(const QString &other) const { return toQStringRef() == other; }
|
| | | bool operator==(QLatin1String other) const { return toQStringRef() == other; }
|
| | | bool operator==(const char *other) const { return toQStringRef() == QLatin1String(other); }
|
| | | bool operator!=(const ProString &other) const { return !(*this == other); }
|
| | | bool operator!=(const QString &other) const { return !(*this == other); }
|
| | | bool operator!=(QLatin1String other) const { return !(*this == other); }
|
| | | bool operator!=(const char *other) const { return !(*this == other); }
|
| | | bool isNull() const { return m_string.isNull(); }
|
| | | bool isEmpty() const { return !m_length; }
|
| | | int length() const { return m_length; }
|
| | | int size() const { return m_length; }
|
| | | QChar at(int i) const { Q_ASSERT((uint)i < (uint)m_length); return constData()[i]; }
|
| | | const QChar *constData() const { return m_string.constData() + m_offset; }
|
| | | ProString mid(int off, int len = -1) const;
|
| | | ProString left(int len) const { return mid(0, len); }
|
| | | ProString right(int len) const { return mid(qMax(0, size() - len)); }
|
| | | ProString trimmed() const;
|
| | | int compare(const ProString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(sub.toQStringRef(), cs); }
|
| | | int compare(const QString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(sub, cs); }
|
| | | int compare(const char *sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(QLatin1String(sub), cs); }
|
| | | bool startsWith(const ProString &sub) const { return toQStringRef().startsWith(sub.toQStringRef()); }
|
| | | bool startsWith(const QString &sub) const { return toQStringRef().startsWith(sub); }
|
| | | bool startsWith(const char *sub) const { return toQStringRef().startsWith(QLatin1String(sub)); }
|
| | | bool startsWith(QChar c) const { return toQStringRef().startsWith(c); }
|
| | | bool endsWith(const ProString &sub) const { return toQStringRef().endsWith(sub.toQStringRef()); }
|
| | | bool endsWith(const QString &sub) const { return toQStringRef().endsWith(sub); }
|
| | | bool endsWith(const char *sub) const { return toQStringRef().endsWith(QLatin1String(sub)); }
|
| | | bool endsWith(QChar c) const { return toQStringRef().endsWith(c); }
|
| | | int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().indexOf(s, from, cs); }
|
| | | int indexOf(const char *s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().indexOf(QLatin1String(s), from, cs); }
|
| | | int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().indexOf(c, from, cs); }
|
| | | int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().lastIndexOf(s, from, cs); }
|
| | | int lastIndexOf(const char *s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().lastIndexOf(QLatin1String(s), from, cs); }
|
| | | int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().lastIndexOf(c, from, cs); }
|
| | | bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
|
| | | bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
|
| | | bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
|
| | | int toInt(bool *ok = 0) const { return toQString().toInt(ok); } // XXX optimize
|
| | | short toShort(bool *ok = 0) const { return toQString().toShort(ok); } // XXX optimize
|
| | |
|
| | | static uint hash(const QChar *p, int n);
|
| | |
|
| | | ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); }
|
| | |
|
| | | ALWAYS_INLINE ProKey &toKey() { return *(ProKey *)this; }
|
| | | ALWAYS_INLINE const ProKey &toKey() const { return *(const ProKey *)this; }
|
| | |
|
| | | QString toQString() const;
|
| | | QString &toQString(QString &tmp) const;
|
| | |
|
| | | QByteArray toLatin1() const { return toQStringRef().toLatin1(); }
|
| | |
|
| | | private:
|
| | | ProString(const ProKey &other);
|
| | | ProString &operator=(const ProKey &other);
|
| | |
|
| | | enum OmitPreHashing { NoHash };
|
| | | ProString(const ProString &other, OmitPreHashing);
|
| | |
|
| | | enum DoPreHashing { DoHash };
|
| | | ALWAYS_INLINE ProString(const QString &str, DoPreHashing);
|
| | | ALWAYS_INLINE ProString(const char *str, DoPreHashing);
|
| | | ALWAYS_INLINE ProString(const QString &str, int offset, int length, DoPreHashing);
|
| | | ALWAYS_INLINE ProString(const QString &str, int offset, int length, uint hash);
|
| | |
|
| | | QString m_string;
|
| | | int m_offset, m_length;
|
| | | const ProFile *m_file;
|
| | | mutable uint m_hash;
|
| | | QChar *prepareExtend(int extraLen, int thisTarget, int extraTarget);
|
| | | uint updatedHash() const;
|
| | | friend uint qHash(const ProString &str);
|
| | | friend QString operator+(const ProString &one, const ProString &two);
|
| | | friend class ProKey;
|
| | | };
|
| | | Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE);
|
| | |
|
| | | class ProKey : public ProString {
|
| | | public:
|
| | | ALWAYS_INLINE ProKey() : ProString() {}
|
| | | explicit ProKey(const QString &str);
|
| | | PROITEM_EXPLICIT ProKey(const char *str);
|
| | | ProKey(const QString &str, int off, int len);
|
| | | ProKey(const QString &str, int off, int len, uint hash);
|
| | | void setValue(const QString &str);
|
| | |
|
| | | #ifdef Q_CC_MSVC
|
| | | // Workaround strange MSVC behaviour when exporting classes with ProKey members.
|
| | | ALWAYS_INLINE ProKey(const ProKey &other) : ProString(other.toString()) {}
|
| | | ALWAYS_INLINE ProKey &operator=(const ProKey &other)
|
| | | {
|
| | | toString() = other.toString();
|
| | | return *this;
|
| | | }
|
| | | #endif
|
| | |
|
| | | ALWAYS_INLINE ProString &toString() { return *(ProString *)this; }
|
| | | ALWAYS_INLINE const ProString &toString() const { return *(const ProString *)this; }
|
| | |
|
| | | private:
|
| | | ProKey(const ProString &other);
|
| | | };
|
| | | Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE);
|
| | |
|
| | | uint qHash(const ProString &str);
|
| | | QString operator+(const ProString &one, const ProString &two);
|
| | | inline QString operator+(const ProString &one, const QString &two)
|
| | | { return one + ProString(two); }
|
| | | inline QString operator+(const QString &one, const ProString &two)
|
| | | { return ProString(one) + two; }
|
| | |
|
| | | inline QString operator+(const ProString &one, const char *two)
|
| | | { return one + ProString(two); } // XXX optimize
|
| | | inline QString operator+(const char *one, const ProString &two)
|
| | | { return ProString(one) + two; } // XXX optimize
|
| | |
|
| | | inline QString &operator+=(QString &that, const ProString &other)
|
| | | { return that += other.toQStringRef(); }
|
| | |
|
| | | inline bool operator==(const QString &that, const ProString &other)
|
| | | { return other == that; }
|
| | | inline bool operator!=(const QString &that, const ProString &other)
|
| | | { return !(other == that); }
|
| | |
|
| | | QTextStream &operator<<(QTextStream &t, const ProString &str);
|
| | |
|
| | | class ProStringList : public QVector<ProString> {
|
| | | public:
|
| | | ProStringList() {}
|
| | | ProStringList(const ProString &str) { *this << str; }
|
| | | explicit ProStringList(const QStringList &list);
|
| | | QStringList toQStringList() const;
|
| | |
|
| | | ProStringList &operator<<(const ProString &str)
|
| | | { QVector<ProString>::operator<<(str); return *this; }
|
| | |
|
| | | int length() const { return size(); }
|
| | |
|
| | | QString join(const QString &sep) const;
|
| | | QString join(QChar sep) const;
|
| | |
|
| | | void removeAll(const ProString &str);
|
| | | void removeAll(const char *str);
|
| | | void removeAt(int idx) { remove(idx); }
|
| | | void removeDuplicates();
|
| | |
|
| | | bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
| | | bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
|
| | | { return contains(ProString(str), cs); }
|
| | | bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
| | | };
|
| | | Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE);
|
| | |
|
| | | inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
|
| | | { ProStringList ret = one; ret += two; return ret; }
|
| | |
|
| | | typedef QHash<ProKey, ProStringList> ProValueMap;
|
| | |
|
| | | // These token definitions affect both ProFileEvaluator and ProWriter
|
| | | enum ProToken {
|
| | | TokTerminator = 0, // end of stream (possibly not included in length; must be zero)
|
| | | TokLine, // line marker:
|
| | | // - line (1)
|
| | | TokAssign, // variable =
|
| | | TokAppend, // variable +=
|
| | | TokAppendUnique, // variable *=
|
| | | TokRemove, // variable -=
|
| | | TokReplace, // variable ~=
|
| | | // previous literal/expansion is a variable manipulation
|
| | | // - value expression + TokValueTerminator
|
| | | TokValueTerminator, // assignment value terminator
|
| | | TokLiteral, // literal string (fully dequoted)
|
| | | // - length (1)
|
| | | // - string data (length; unterminated)
|
| | | TokHashLiteral, // literal string with hash (fully dequoted)
|
| | | // - hash (2)
|
| | | // - length (1)
|
| | | // - string data (length; unterminated)
|
| | | TokVariable, // qmake variable expansion
|
| | | // - hash (2)
|
| | | // - name length (1)
|
| | | // - name (name length; unterminated)
|
| | | TokProperty, // qmake property expansion
|
| | | // - hash (2)
|
| | | // - name length (1)
|
| | | // - name (name length; unterminated)
|
| | | TokEnvVar, // environment variable expansion
|
| | | // - name length (1)
|
| | | // - name (name length; unterminated)
|
| | | TokFuncName, // replace function expansion
|
| | | // - hash (2)
|
| | | // - name length (1)
|
| | | // - name (name length; unterminated)
|
| | | // - ((nested expansion + TokArgSeparator)* + nested expansion)?
|
| | | // - TokFuncTerminator
|
| | | TokArgSeparator, // function argument separator
|
| | | TokFuncTerminator, // function argument list terminator
|
| | | TokCondition, // previous literal/expansion is a conditional
|
| | | TokTestCall, // previous literal/expansion is a test function call
|
| | | // - ((nested expansion + TokArgSeparator)* + nested expansion)?
|
| | | // - TokFuncTerminator
|
| | | TokReturn, // previous literal/expansion is a return value
|
| | | TokBreak, // break loop
|
| | | TokNext, // shortcut to next loop iteration
|
| | | TokNot, // '!' operator
|
| | | TokAnd, // ':' operator
|
| | | TokOr, // '|' operator
|
| | | TokBranch, // branch point:
|
| | | // - then block length (2)
|
| | | // - then block + TokTerminator (then block length)
|
| | | // - else block length (2)
|
| | | // - else block + TokTerminator (else block length)
|
| | | TokForLoop, // for loop:
|
| | | // - variable name: hash (2), length (1), chars (length)
|
| | | // - expression: length (2), bytes + TokValueTerminator (length)
|
| | | // - body length (2)
|
| | | // - body + TokTerminator (body length)
|
| | | TokTestDef, // test function definition:
|
| | | TokReplaceDef, // replace function definition:
|
| | | // - function name: hash (2), length (1), chars (length)
|
| | | // - body length (2)
|
| | | // - body + TokTerminator (body length)
|
| | | TokMask = 0xff,
|
| | | TokQuoted = 0x100, // The expression is quoted => join expanded stringlist
|
| | | TokNewStr = 0x200 // Next stringlist element
|
| | | };
|
| | |
|
| | | class QMAKE_EXPORT ProFile
|
| | | {
|
| | | public:
|
| | | explicit ProFile(const QString &fileName);
|
| | | ~ProFile();
|
| | |
|
| | | QString fileName() const { return m_fileName; }
|
| | | QString directoryName() const { return m_directoryName; }
|
| | | const QString &items() const { return m_proitems; }
|
| | | QString *itemsRef() { return &m_proitems; }
|
| | | const ushort *tokPtr() const { return (const ushort *)m_proitems.constData(); }
|
| | |
|
| | | void ref() { m_refCount.ref(); }
|
| | | void deref() { if (!m_refCount.deref()) delete this; }
|
| | |
|
| | | bool isOk() const { return m_ok; }
|
| | | void setOk(bool ok) { m_ok = ok; }
|
| | |
|
| | | bool isHostBuild() const { return m_hostBuild; }
|
| | | void setHostBuild(bool host_build) { m_hostBuild = host_build; }
|
| | |
|
| | | private:
|
| | | ProItemRefCount m_refCount;
|
| | | QString m_proitems;
|
| | | QString m_fileName;
|
| | | QString m_directoryName;
|
| | | bool m_ok;
|
| | | bool m_hostBuild;
|
| | | };
|
| | |
|
| | | class ProFunctionDef {
|
| | | public:
|
| | | ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); }
|
| | | ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); }
|
| | | ~ProFunctionDef() { m_pro->deref(); }
|
| | | ProFunctionDef &operator=(const ProFunctionDef &o)
|
| | | {
|
| | | if (this != &o) {
|
| | | m_pro->deref();
|
| | | m_pro = o.m_pro;
|
| | | m_pro->ref();
|
| | | m_offset = o.m_offset;
|
| | | }
|
| | | return *this;
|
| | | }
|
| | | ProFile *pro() const { return m_pro; }
|
| | | const ushort *tokPtr() const { return m_pro->tokPtr() + m_offset; }
|
| | | private:
|
| | | ProFile *m_pro;
|
| | | int m_offset;
|
| | | };
|
| | |
|
| | | Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE);
|
| | |
|
| | | struct ProFunctionDefs {
|
| | | QHash<ProKey, ProFunctionDef> testFunctions;
|
| | | QHash<ProKey, ProFunctionDef> replaceFunctions;
|
| | | };
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // PROITEMS_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | |
|
| | | #ifndef QMAKE_GLOBAL_H
|
| | | #define QMAKE_GLOBAL_H
|
| | |
|
| | | #include <qglobal.h>
|
| | |
|
| | | #if defined(QMAKE_AS_LIBRARY)
|
| | | # if defined(QMAKE_LIBRARY)
|
| | | # define QMAKE_EXPORT Q_DECL_EXPORT
|
| | | # else
|
| | | # define QMAKE_EXPORT Q_DECL_IMPORT
|
| | | # endif
|
| | | #else
|
| | | # define QMAKE_EXPORT
|
| | | #endif
|
| | |
|
| | | // Be fast even for debug builds
|
| | | // MinGW GCC 4.5+ has a problem with always_inline putTok and putBlockLen
|
| | | #if defined(__GNUC__) && !(defined(__MINGW32__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
| | | # define ALWAYS_INLINE inline __attribute__((always_inline))
|
| | | #elif defined(_MSC_VER)
|
| | | # define ALWAYS_INLINE __forceinline
|
| | | #else
|
| | | # define ALWAYS_INLINE inline
|
| | | #endif
|
| | |
|
| | | #endif
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qmakeevaluator.h"
|
| | |
|
| | | #include "qmakeevaluator_p.h"
|
| | | #include "qmakeglobals.h"
|
| | | #include "qmakeparser.h"
|
| | | #include "ioutils.h"
|
| | |
|
| | | #include <qbytearray.h>
|
| | | #include <qdir.h>
|
| | | #include <qfile.h>
|
| | | #include <qfileinfo.h>
|
| | | #include <qlist.h>
|
| | | #include <qregexp.h>
|
| | | #include <qset.h>
|
| | | #include <qstringlist.h>
|
| | | #include <qtextstream.h>
|
| | |
|
| | | #ifdef Q_OS_UNIX
|
| | | #include <time.h>
|
| | | #include <utime.h>
|
| | | #include <errno.h>
|
| | | #include <unistd.h>
|
| | | #include <sys/stat.h>
|
| | | #include <sys/utsname.h>
|
| | | #else
|
| | | #include <windows.h>
|
| | | #endif
|
| | | #include <stdio.h>
|
| | | #include <stdlib.h>
|
| | |
|
| | | #ifdef Q_OS_WIN32
|
| | | #define QT_POPEN _popen
|
| | | #define QT_PCLOSE _pclose
|
| | | #else
|
| | | #define QT_POPEN popen
|
| | | #define QT_PCLOSE pclose
|
| | | #endif
|
| | |
|
| | | using namespace QMakeInternal;
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | #define fL1S(s) QString::fromLatin1(s)
|
| | |
|
| | | enum ExpandFunc {
|
| | | E_INVALID = 0, E_MEMBER, E_FIRST, E_LAST, E_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST,
|
| | | E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
|
| | | E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
|
| | | E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
|
| | | E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
|
| | | E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
|
| | | E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE
|
| | | };
|
| | |
|
| | | enum TestFunc {
|
| | | T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
|
| | | T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
|
| | | T_DEFINED, T_CONTAINS, T_INFILE,
|
| | | T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
|
| | | T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE
|
| | | };
|
| | |
|
| | | void QMakeEvaluator::initFunctionStatics()
|
| | | {
|
| | | static const struct {
|
| | | const char * const name;
|
| | | const ExpandFunc func;
|
| | | } expandInits[] = {
|
| | | { "member", E_MEMBER },
|
| | | { "first", E_FIRST },
|
| | | { "last", E_LAST },
|
| | | { "size", E_SIZE },
|
| | | { "cat", E_CAT },
|
| | | { "fromfile", E_FROMFILE },
|
| | | { "eval", E_EVAL },
|
| | | { "list", E_LIST },
|
| | | { "sprintf", E_SPRINTF },
|
| | | { "format_number", E_FORMAT_NUMBER },
|
| | | { "join", E_JOIN },
|
| | | { "split", E_SPLIT },
|
| | | { "basename", E_BASENAME },
|
| | | { "dirname", E_DIRNAME },
|
| | | { "section", E_SECTION },
|
| | | { "find", E_FIND },
|
| | | { "system", E_SYSTEM },
|
| | | { "unique", E_UNIQUE },
|
| | | { "reverse", E_REVERSE },
|
| | | { "quote", E_QUOTE },
|
| | | { "escape_expand", E_ESCAPE_EXPAND },
|
| | | { "upper", E_UPPER },
|
| | | { "lower", E_LOWER },
|
| | | { "re_escape", E_RE_ESCAPE },
|
| | | { "val_escape", E_VAL_ESCAPE },
|
| | | { "files", E_FILES },
|
| | | { "prompt", E_PROMPT },
|
| | | { "replace", E_REPLACE },
|
| | | { "sort_depends", E_SORT_DEPENDS },
|
| | | { "resolve_depends", E_RESOLVE_DEPENDS },
|
| | | { "enumerate_vars", E_ENUMERATE_VARS },
|
| | | { "shadowed", E_SHADOWED },
|
| | | { "absolute_path", E_ABSOLUTE_PATH },
|
| | | { "relative_path", E_RELATIVE_PATH },
|
| | | { "clean_path", E_CLEAN_PATH },
|
| | | { "system_path", E_SYSTEM_PATH },
|
| | | { "shell_path", E_SHELL_PATH },
|
| | | { "system_quote", E_SYSTEM_QUOTE },
|
| | | { "shell_quote", E_SHELL_QUOTE },
|
| | | };
|
| | | for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
|
| | | statics.expands.insert(ProKey(expandInits[i].name), expandInits[i].func);
|
| | |
|
| | | static const struct {
|
| | | const char * const name;
|
| | | const TestFunc func;
|
| | | } testInits[] = {
|
| | | { "requires", T_REQUIRES },
|
| | | { "greaterThan", T_GREATERTHAN },
|
| | | { "lessThan", T_LESSTHAN },
|
| | | { "equals", T_EQUALS },
|
| | | { "isEqual", T_EQUALS },
|
| | | { "exists", T_EXISTS },
|
| | | { "export", T_EXPORT },
|
| | | { "clear", T_CLEAR },
|
| | | { "unset", T_UNSET },
|
| | | { "eval", T_EVAL },
|
| | | { "CONFIG", T_CONFIG },
|
| | | { "if", T_IF },
|
| | | { "isActiveConfig", T_CONFIG },
|
| | | { "system", T_SYSTEM },
|
| | | { "defined", T_DEFINED },
|
| | | { "contains", T_CONTAINS },
|
| | | { "infile", T_INFILE },
|
| | | { "count", T_COUNT },
|
| | | { "isEmpty", T_ISEMPTY },
|
| | | { "load", T_LOAD },
|
| | | { "include", T_INCLUDE },
|
| | | { "debug", T_DEBUG },
|
| | | { "log", T_LOG },
|
| | | { "message", T_MESSAGE },
|
| | | { "warning", T_WARNING },
|
| | | { "error", T_ERROR },
|
| | | { "mkpath", T_MKPATH },
|
| | | { "write_file", T_WRITE_FILE },
|
| | | { "touch", T_TOUCH },
|
| | | { "cache", T_CACHE },
|
| | | };
|
| | | for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i)
|
| | | statics.functions.insert(ProKey(testInits[i].name), testInits[i].func);
|
| | | }
|
| | |
|
| | | static bool isTrue(const ProString &_str, QString &tmp)
|
| | | {
|
| | | const QString &str = _str.toQString(tmp);
|
| | | return !str.compare(statics.strtrue, Qt::CaseInsensitive) || str.toInt();
|
| | | }
|
| | |
|
| | | #ifdef Q_OS_WIN
|
| | | static QString windowsErrorCode()
|
| | | {
|
| | | wchar_t *string = 0;
|
| | | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
| | | NULL,
|
| | | GetLastError(),
|
| | | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
| | | (LPWSTR)&string,
|
| | | 0,
|
| | | NULL);
|
| | | QString ret = QString::fromWCharArray(string);
|
| | | LocalFree((HLOCAL)string);
|
| | | return ret;
|
| | | }
|
| | | #endif
|
| | |
|
| | | static QString
|
| | | quoteValue(const ProString &val)
|
| | | {
|
| | | QString ret;
|
| | | ret.reserve(val.size());
|
| | | const QChar *chars = val.constData();
|
| | | bool quote = val.isEmpty();
|
| | | bool escaping = false;
|
| | | for (int i = 0, l = val.size(); i < l; i++) {
|
| | | QChar c = chars[i];
|
| | | ushort uc = c.unicode();
|
| | | if (uc < 32) {
|
| | | if (!escaping) {
|
| | | escaping = true;
|
| | | ret += QLatin1String("$$escape_expand(");
|
| | | }
|
| | | switch (uc) {
|
| | | case '\r':
|
| | | ret += QLatin1String("\\\\r");
|
| | | break;
|
| | | case '\n':
|
| | | ret += QLatin1String("\\\\n");
|
| | | break;
|
| | | case '\t':
|
| | | ret += QLatin1String("\\\\t");
|
| | | break;
|
| | | default:
|
| | | ret += QString::fromLatin1("\\\\x%1").arg(uc, 2, 16, QLatin1Char('0'));
|
| | | break;
|
| | | }
|
| | | } else {
|
| | | if (escaping) {
|
| | | escaping = false;
|
| | | ret += QLatin1Char(')');
|
| | | }
|
| | | switch (uc) {
|
| | | case '\\':
|
| | | ret += QLatin1String("\\\\");
|
| | | break;
|
| | | case '"':
|
| | | ret += QLatin1String("\\\"");
|
| | | break;
|
| | | case '\'':
|
| | | ret += QLatin1String("\\'");
|
| | | break;
|
| | | case '$':
|
| | | ret += QLatin1String("\\$");
|
| | | break;
|
| | | case '#':
|
| | | ret += QLatin1String("$${LITERAL_HASH}");
|
| | | break;
|
| | | case 32:
|
| | | quote = true;
|
| | | // fallthrough
|
| | | default:
|
| | | ret += c;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | if (escaping)
|
| | | ret += QLatin1Char(')');
|
| | | if (quote) {
|
| | | ret.prepend(QLatin1Char('"'));
|
| | | ret.append(QLatin1Char('"'));
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | static bool
|
| | | doWriteFile(const QString &name, QIODevice::OpenMode mode, const QString &contents, QString *errStr)
|
| | | {
|
| | | QByteArray bytes = contents.toLocal8Bit();
|
| | | QFile cfile(name);
|
| | | if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
| | | if (cfile.readAll() == bytes)
|
| | | return true;
|
| | | cfile.close();
|
| | | }
|
| | | if (!cfile.open(mode | QIODevice::WriteOnly | QIODevice::Text)) {
|
| | | *errStr = cfile.errorString();
|
| | | return false;
|
| | | }
|
| | | cfile.write(bytes);
|
| | | cfile.close();
|
| | | if (cfile.error() != QFile::NoError) {
|
| | | *errStr = cfile.errorString();
|
| | | return false;
|
| | | }
|
| | | return true;
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn
|
| | | QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
| | | const QString &contents)
|
| | | {
|
| | | QFileInfo qfi(fn);
|
| | | if (!QDir::current().mkpath(qfi.path())) {
|
| | | evalError(fL1S("Cannot create %1directory %2.")
|
| | | .arg(ctx, QDir::toNativeSeparators(qfi.path())));
|
| | | return ReturnFalse;
|
| | | }
|
| | | QString errStr;
|
| | | if (!doWriteFile(qfi.filePath(), mode, contents, &errStr)) {
|
| | | evalError(fL1S("Cannot write %1file %2: %3.")
|
| | | .arg(ctx, QDir::toNativeSeparators(qfi.filePath()), errStr));
|
| | | return ReturnFalse;
|
| | | }
|
| | | m_parser->discardFileFromCache(qfi.filePath());
|
| | | return ReturnTrue;
|
| | | }
|
| | |
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const
|
| | | {
|
| | | proc->setWorkingDirectory(currentDirectory());
|
| | | # ifdef PROEVALUATOR_SETENV
|
| | | if (!m_option->environment.isEmpty())
|
| | | proc->setProcessEnvironment(m_option->environment);
|
| | | # endif
|
| | | # ifdef Q_OS_WIN
|
| | | proc->setNativeArguments(QLatin1String("/v:off /s /c \"") + command + QLatin1Char('"'));
|
| | | proc->start(m_option->getEnv(QLatin1String("COMSPEC")), QStringList());
|
| | | # else
|
| | | proc->start(QLatin1String("/bin/sh"), QStringList() << QLatin1String("-c") << command);
|
| | | # endif
|
| | | proc->waitForFinished(-1);
|
| | | }
|
| | | #endif
|
| | |
|
| | | QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const
|
| | | {
|
| | | QByteArray out;
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | QProcess proc;
|
| | | runProcess(&proc, args);
|
| | | QByteArray errout = proc.readAllStandardError();
|
| | | # ifdef PROEVALUATOR_FULL
|
| | | // FIXME: Qt really should have the option to set forwarding per channel
|
| | | fputs(errout.constData(), stderr);
|
| | | # else
|
| | | if (!errout.isEmpty()) {
|
| | | if (errout.endsWith('\n'))
|
| | | errout.chop(1);
|
| | | m_handler->message(QMakeHandler::EvalError, QString::fromLocal8Bit(errout));
|
| | | }
|
| | | # endif
|
| | | out = proc.readAllStandardOutput();
|
| | | # ifdef Q_OS_WIN
|
| | | // FIXME: Qt's line end conversion on sequential files should really be fixed
|
| | | out.replace("\r\n", "\n");
|
| | | # endif
|
| | | #else
|
| | | if (FILE *proc = QT_POPEN(QString(QLatin1String("cd ")
|
| | | + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
|
| | | + QLatin1String(" && ") + args).toLocal8Bit().constData(), "r")) {
|
| | | while (!feof(proc)) {
|
| | | char buff[10 * 1024];
|
| | | int read_in = int(fread(buff, 1, sizeof(buff), proc));
|
| | | if (!read_in)
|
| | | break;
|
| | | out += QByteArray(buff, read_in);
|
| | | }
|
| | | QT_PCLOSE(proc);
|
| | | }
|
| | | #endif
|
| | | return out;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::populateDeps(
|
| | | const ProStringList &deps, const ProString &prefix,
|
| | | QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
|
| | | ProStringList &rootSet) const
|
| | | {
|
| | | foreach (const ProString &item, deps)
|
| | | if (!dependencies.contains(item.toKey())) {
|
| | | QSet<ProKey> &dset = dependencies[item.toKey()]; // Always create entry
|
| | | ProStringList depends = values(ProKey(prefix + item + QString::fromLatin1(".depends")));
|
| | | if (depends.isEmpty()) {
|
| | | rootSet << item;
|
| | | } else {
|
| | | foreach (const ProString &dep, depends) {
|
| | | dset.insert(dep.toKey());
|
| | | dependees[dep.toKey()] << item;
|
| | | }
|
| | | populateDeps(depends, prefix, dependencies, dependees, rootSet);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | ProStringList QMakeEvaluator::evaluateBuiltinExpand(
|
| | | int func_t, const ProKey &func, const ProStringList &args)
|
| | | {
|
| | | ProStringList ret;
|
| | |
|
| | | traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args));
|
| | |
|
| | | switch (func_t) {
|
| | | case E_BASENAME:
|
| | | case E_DIRNAME:
|
| | | case E_SECTION: {
|
| | | bool regexp = false;
|
| | | QString sep;
|
| | | ProString var;
|
| | | int beg = 0;
|
| | | int end = -1;
|
| | | if (func_t == E_SECTION) {
|
| | | if (args.count() != 3 && args.count() != 4) {
|
| | | evalError(fL1S("%1(var) section(var, sep, begin, end) requires"
|
| | | " three or four arguments.").arg(func.toQString(m_tmp1)));
|
| | | } else {
|
| | | var = args[0];
|
| | | sep = args.at(1).toQString();
|
| | | beg = args.at(2).toQString(m_tmp2).toInt();
|
| | | if (args.count() == 4)
|
| | | end = args.at(3).toQString(m_tmp2).toInt();
|
| | | }
|
| | | } else {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("%1(var) requires one argument.").arg(func.toQString(m_tmp1)));
|
| | | } else {
|
| | | var = args[0];
|
| | | regexp = true;
|
| | | sep = QLatin1String("[\\\\/]");
|
| | | if (func_t == E_DIRNAME)
|
| | | end = -2;
|
| | | else
|
| | | beg = -1;
|
| | | }
|
| | | }
|
| | | if (!var.isEmpty()) {
|
| | | if (regexp) {
|
| | | QRegExp sepRx(sep);
|
| | | foreach (const ProString &str, values(map(var))) {
|
| | | const QString &rstr = str.toQString(m_tmp1).section(sepRx, beg, end);
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? str : ProString(rstr).setSource(str));
|
| | | }
|
| | | } else {
|
| | | foreach (const ProString &str, values(map(var))) {
|
| | | const QString &rstr = str.toQString(m_tmp1).section(sep, beg, end);
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? str : ProString(rstr).setSource(str));
|
| | | }
|
| | | }
|
| | | }
|
| | | break;
|
| | | }
|
| | | case E_SPRINTF:
|
| | | if (args.count() < 1) {
|
| | | evalError(fL1S("sprintf(format, ...) requires at least one argument."));
|
| | | } else {
|
| | | QString tmp = args.at(0).toQString(m_tmp1);
|
| | | for (int i = 1; i < args.count(); ++i)
|
| | | tmp = tmp.arg(args.at(i).toQString(m_tmp2));
|
| | | // Note: this depends on split_value_list() making a deep copy
|
| | | ret = split_value_list(tmp);
|
| | | }
|
| | | break;
|
| | | case E_FORMAT_NUMBER:
|
| | | if (args.count() > 2) {
|
| | | evalError(fL1S("format_number(number[, options...]) requires one or two arguments."));
|
| | | } else {
|
| | | int ibase = 10;
|
| | | int obase = 10;
|
| | | int width = 0;
|
| | | bool zeropad = false;
|
| | | bool leftalign = false;
|
| | | enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign;
|
| | | if (args.count() >= 2) {
|
| | | foreach (const ProString &opt, split_value_list(args.at(1).toQString(m_tmp2))) {
|
| | | opt.toQString(m_tmp3);
|
| | | if (m_tmp3.startsWith(QLatin1String("ibase="))) {
|
| | | ibase = m_tmp3.mid(6).toInt();
|
| | | } else if (m_tmp3.startsWith(QLatin1String("obase="))) {
|
| | | obase = m_tmp3.mid(6).toInt();
|
| | | } else if (m_tmp3.startsWith(QLatin1String("width="))) {
|
| | | width = m_tmp3.mid(6).toInt();
|
| | | } else if (m_tmp3 == QLatin1String("zeropad")) {
|
| | | zeropad = true;
|
| | | } else if (m_tmp3 == QLatin1String("padsign")) {
|
| | | sign = PadSign;
|
| | | } else if (m_tmp3 == QLatin1String("alwayssign")) {
|
| | | sign = AlwaysSign;
|
| | | } else if (m_tmp3 == QLatin1String("leftalign")) {
|
| | | leftalign = true;
|
| | | } else {
|
| | | evalError(fL1S("format_number(): invalid format option %1.").arg(m_tmp3));
|
| | | goto formfail;
|
| | | }
|
| | | }
|
| | | }
|
| | | args.at(0).toQString(m_tmp3);
|
| | | if (m_tmp3.contains(QLatin1Char('.'))) {
|
| | | evalError(fL1S("format_number(): floats are currently not supported."));
|
| | | break;
|
| | | }
|
| | | bool ok;
|
| | | qlonglong num = m_tmp3.toLongLong(&ok, ibase);
|
| | | if (!ok) {
|
| | | evalError(fL1S("format_number(): malformed number %2 for base %1.")
|
| | | .arg(ibase).arg(m_tmp3));
|
| | | break;
|
| | | }
|
| | | QString outstr;
|
| | | if (num < 0) {
|
| | | num = -num;
|
| | | outstr = QLatin1Char('-');
|
| | | } else if (sign == AlwaysSign) {
|
| | | outstr = QLatin1Char('+');
|
| | | } else if (sign == PadSign) {
|
| | | outstr = QLatin1Char(' ');
|
| | | }
|
| | | QString numstr = QString::number(num, obase);
|
| | | int space = width - outstr.length() - numstr.length();
|
| | | if (space <= 0) {
|
| | | outstr += numstr;
|
| | | } else if (leftalign) {
|
| | | outstr += numstr + QString(space, QLatin1Char(' '));
|
| | | } else if (zeropad) {
|
| | | outstr += QString(space, QLatin1Char('0')) + numstr;
|
| | | } else {
|
| | | outstr.prepend(QString(space, QLatin1Char(' ')));
|
| | | outstr += numstr;
|
| | | }
|
| | | ret += ProString(outstr);
|
| | | }
|
| | | formfail:
|
| | | break;
|
| | | case E_JOIN: {
|
| | | if (args.count() < 1 || args.count() > 4) {
|
| | | evalError(fL1S("join(var, glue, before, after) requires one to four arguments."));
|
| | | } else {
|
| | | QString glue;
|
| | | ProString before, after;
|
| | | if (args.count() >= 2)
|
| | | glue = args.at(1).toQString(m_tmp1);
|
| | | if (args.count() >= 3)
|
| | | before = args[2];
|
| | | if (args.count() == 4)
|
| | | after = args[3];
|
| | | const ProStringList &var = values(map(args.at(0)));
|
| | | if (!var.isEmpty()) {
|
| | | const ProFile *src = currentProFile();
|
| | | foreach (const ProString &v, var)
|
| | | if (const ProFile *s = v.sourceFile()) {
|
| | | src = s;
|
| | | break;
|
| | | }
|
| | | ret = split_value_list(before + var.join(glue) + after, src);
|
| | | }
|
| | | }
|
| | | break;
|
| | | }
|
| | | case E_SPLIT:
|
| | | if (args.count() < 1 || args.count() > 2) {
|
| | | evalError(fL1S("split(var, sep) requires one or two arguments."));
|
| | | } else {
|
| | | const QString &sep = (args.count() == 2) ? args.at(1).toQString(m_tmp1) : statics.field_sep;
|
| | | foreach (const ProString &var, values(map(args.at(0))))
|
| | | foreach (const QString &splt, var.toQString(m_tmp2).split(sep))
|
| | | ret << (splt.isSharedWith(m_tmp2) ? var : ProString(splt).setSource(var));
|
| | | }
|
| | | break;
|
| | | case E_MEMBER:
|
| | | if (args.count() < 1 || args.count() > 3) {
|
| | | evalError(fL1S("member(var, start, end) requires one to three arguments."));
|
| | | } else {
|
| | | bool ok = true;
|
| | | const ProStringList &var = values(map(args.at(0)));
|
| | | int start = 0, end = 0;
|
| | | if (args.count() >= 2) {
|
| | | const QString &start_str = args.at(1).toQString(m_tmp1);
|
| | | start = start_str.toInt(&ok);
|
| | | if (!ok) {
|
| | | if (args.count() == 2) {
|
| | | int dotdot = start_str.indexOf(statics.strDotDot);
|
| | | if (dotdot != -1) {
|
| | | start = start_str.left(dotdot).toInt(&ok);
|
| | | if (ok)
|
| | | end = start_str.mid(dotdot+2).toInt(&ok);
|
| | | }
|
| | | }
|
| | | if (!ok)
|
| | | evalError(fL1S("member() argument 2 (start) '%2' invalid.")
|
| | | .arg(start_str));
|
| | | } else {
|
| | | end = start;
|
| | | if (args.count() == 3)
|
| | | end = args.at(2).toQString(m_tmp1).toInt(&ok);
|
| | | if (!ok)
|
| | | evalError(fL1S("member() argument 3 (end) '%2' invalid.")
|
| | | .arg(args.at(2).toQString(m_tmp1)));
|
| | | }
|
| | | }
|
| | | if (ok) {
|
| | | if (start < 0)
|
| | | start += var.count();
|
| | | if (end < 0)
|
| | | end += var.count();
|
| | | if (start < 0 || start >= var.count() || end < 0 || end >= var.count()) {
|
| | | //nothing
|
| | | } else if (start < end) {
|
| | | for (int i = start; i <= end && var.count() >= i; i++)
|
| | | ret.append(var[i]);
|
| | | } else {
|
| | | for (int i = start; i >= end && var.count() >= i && i >= 0; i--)
|
| | | ret += var[i];
|
| | | }
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_FIRST:
|
| | | case E_LAST:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("%1(var) requires one argument.").arg(func.toQString(m_tmp1)));
|
| | | } else {
|
| | | const ProStringList &var = values(map(args.at(0)));
|
| | | if (!var.isEmpty()) {
|
| | | if (func_t == E_FIRST)
|
| | | ret.append(var[0]);
|
| | | else
|
| | | ret.append(var.last());
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_SIZE:
|
| | | if (args.count() != 1)
|
| | | evalError(fL1S("size(var) requires one argument."));
|
| | | else
|
| | | ret.append(ProString(QString::number(values(map(args.at(0))).size())));
|
| | | break;
|
| | | case E_CAT:
|
| | | if (args.count() < 1 || args.count() > 2) {
|
| | | evalError(fL1S("cat(file, singleline=true) requires one or two arguments."));
|
| | | } else {
|
| | | const QString &file = args.at(0).toQString(m_tmp1);
|
| | |
|
| | | bool blob = false;
|
| | | bool lines = false;
|
| | | bool singleLine = true;
|
| | | if (args.count() > 1) {
|
| | | args.at(1).toQString(m_tmp2);
|
| | | if (!m_tmp2.compare(QLatin1String("false"), Qt::CaseInsensitive))
|
| | | singleLine = false;
|
| | | else if (!m_tmp2.compare(QLatin1String("blob"), Qt::CaseInsensitive))
|
| | | blob = true;
|
| | | else if (!m_tmp2.compare(QLatin1String("lines"), Qt::CaseInsensitive))
|
| | | lines = true;
|
| | | }
|
| | |
|
| | | QFile qfile(resolvePath(m_option->expandEnvVars(file)));
|
| | | if (qfile.open(QIODevice::ReadOnly)) {
|
| | | QTextStream stream(&qfile);
|
| | | if (blob) {
|
| | | ret += ProString(stream.readAll());
|
| | | } else {
|
| | | while (!stream.atEnd()) {
|
| | | if (lines) {
|
| | | ret += ProString(stream.readLine());
|
| | | } else {
|
| | | ret += split_value_list(stream.readLine().trimmed());
|
| | | if (!singleLine)
|
| | | ret += ProString("\n");
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_FROMFILE:
|
| | | if (args.count() != 2) {
|
| | | evalError(fL1S("fromfile(file, variable) requires two arguments."));
|
| | | } else {
|
| | | ProValueMap vars;
|
| | | QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
|
| | | fn.detach();
|
| | | if (evaluateFileInto(fn, &vars, LoadProOnly) == ReturnTrue)
|
| | | ret = vars.value(map(args.at(1)));
|
| | | }
|
| | | break;
|
| | | case E_EVAL:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("eval(variable) requires one argument."));
|
| | | } else {
|
| | | ret += values(map(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_LIST: {
|
| | | QString tmp;
|
| | | tmp.sprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++);
|
| | | ret = ProStringList(ProString(tmp));
|
| | | ProStringList lst;
|
| | | foreach (const ProString &arg, args)
|
| | | lst += split_value_list(arg.toQString(m_tmp1), arg.sourceFile()); // Relies on deep copy
|
| | | m_valuemapStack.top()[ret.at(0).toKey()] = lst;
|
| | | break; }
|
| | | case E_FIND:
|
| | | if (args.count() != 2) {
|
| | | evalError(fL1S("find(var, str) requires two arguments."));
|
| | | } else {
|
| | | QRegExp regx(args.at(1).toQString());
|
| | | int t = 0;
|
| | | foreach (const ProString &val, values(map(args.at(0)))) {
|
| | | if (regx.indexIn(val.toQString(m_tmp[t])) != -1)
|
| | | ret += val;
|
| | | t ^= 1;
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_SYSTEM:
|
| | | if (!m_skipLevel) {
|
| | | if (args.count() < 1 || args.count() > 2) {
|
| | | evalError(fL1S("system(execute) requires one or two arguments."));
|
| | | } else {
|
| | | bool blob = false;
|
| | | bool lines = false;
|
| | | bool singleLine = true;
|
| | | if (args.count() > 1) {
|
| | | args.at(1).toQString(m_tmp2);
|
| | | if (!m_tmp2.compare(QLatin1String("false"), Qt::CaseInsensitive))
|
| | | singleLine = false;
|
| | | else if (!m_tmp2.compare(QLatin1String("blob"), Qt::CaseInsensitive))
|
| | | blob = true;
|
| | | else if (!m_tmp2.compare(QLatin1String("lines"), Qt::CaseInsensitive))
|
| | | lines = true;
|
| | | }
|
| | | QByteArray bytes = getCommandOutput(args.at(0).toQString(m_tmp2));
|
| | | if (lines) {
|
| | | QTextStream stream(bytes);
|
| | | while (!stream.atEnd())
|
| | | ret += ProString(stream.readLine());
|
| | | } else {
|
| | | QString output = QString::fromLocal8Bit(bytes);
|
| | | if (blob) {
|
| | | ret += ProString(output);
|
| | | } else {
|
| | | output.replace(QLatin1Char('\t'), QLatin1Char(' '));
|
| | | if (singleLine)
|
| | | output.replace(QLatin1Char('\n'), QLatin1Char(' '));
|
| | | ret += split_value_list(output);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_UNIQUE:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("unique(var) requires one argument."));
|
| | | } else {
|
| | | ret = values(map(args.at(0)));
|
| | | ret.removeDuplicates();
|
| | | }
|
| | | break;
|
| | | case E_REVERSE:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("reverse(var) requires one argument."));
|
| | | } else {
|
| | | ProStringList var = values(args.at(0).toKey());
|
| | | for (int i = 0; i < var.size() / 2; i++)
|
| | | qSwap(var[i], var[var.size() - i - 1]);
|
| | | ret += var;
|
| | | }
|
| | | break;
|
| | | case E_QUOTE:
|
| | | ret += args;
|
| | | break;
|
| | | case E_ESCAPE_EXPAND:
|
| | | for (int i = 0; i < args.size(); ++i) {
|
| | | QString str = args.at(i).toQString();
|
| | | QChar *i_data = str.data();
|
| | | int i_len = str.length();
|
| | | for (int x = 0; x < i_len; ++x) {
|
| | | if (*(i_data+x) == QLatin1Char('\\') && x < i_len-1) {
|
| | | if (*(i_data+x+1) == QLatin1Char('\\')) {
|
| | | ++x;
|
| | | } else {
|
| | | struct {
|
| | | char in, out;
|
| | | } mapped_quotes[] = {
|
| | | { 'n', '\n' },
|
| | | { 't', '\t' },
|
| | | { 'r', '\r' },
|
| | | { 0, 0 }
|
| | | };
|
| | | for (int i = 0; mapped_quotes[i].in; ++i) {
|
| | | if (*(i_data+x+1) == QLatin1Char(mapped_quotes[i].in)) {
|
| | | *(i_data+x) = QLatin1Char(mapped_quotes[i].out);
|
| | | if (x < i_len-2)
|
| | | memmove(i_data+x+1, i_data+x+2, (i_len-x-2)*sizeof(QChar));
|
| | | --i_len;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | ret.append(ProString(QString(i_data, i_len)).setSource(args.at(i)));
|
| | | }
|
| | | break;
|
| | | case E_RE_ESCAPE:
|
| | | for (int i = 0; i < args.size(); ++i) {
|
| | | const QString &rstr = QRegExp::escape(args.at(i).toQString(m_tmp1));
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(i) : ProString(rstr).setSource(args.at(i)));
|
| | | }
|
| | | break;
|
| | | case E_VAL_ESCAPE:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("val_escape(var) requires one argument."));
|
| | | } else {
|
| | | const ProStringList &vals = values(args.at(0).toKey());
|
| | | ret.reserve(vals.size());
|
| | | foreach (const ProString &str, vals)
|
| | | ret += ProString(quoteValue(str));
|
| | | }
|
| | | break;
|
| | | case E_UPPER:
|
| | | case E_LOWER:
|
| | | for (int i = 0; i < args.count(); ++i) {
|
| | | QString rstr = args.at(i).toQString(m_tmp1);
|
| | | rstr = (func_t == E_UPPER) ? rstr.toUpper() : rstr.toLower();
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(i) : ProString(rstr).setSource(args.at(i)));
|
| | | }
|
| | | break;
|
| | | case E_FILES:
|
| | | if (args.count() != 1 && args.count() != 2) {
|
| | | evalError(fL1S("files(pattern, recursive=false) requires one or two arguments."));
|
| | | } else {
|
| | | bool recursive = false;
|
| | | if (args.count() == 2)
|
| | | recursive = isTrue(args.at(1), m_tmp2);
|
| | | QStringList dirs;
|
| | | QString r = m_option->expandEnvVars(args.at(0).toQString(m_tmp1))
|
| | | .replace(QLatin1Char('\\'), QLatin1Char('/'));
|
| | | QString pfx;
|
| | | if (IoUtils::isRelativePath(r)) {
|
| | | pfx = currentDirectory();
|
| | | if (!pfx.endsWith(QLatin1Char('/')))
|
| | | pfx += QLatin1Char('/');
|
| | | }
|
| | | int slash = r.lastIndexOf(QLatin1Char('/'));
|
| | | if (slash != -1) {
|
| | | dirs.append(r.left(slash+1));
|
| | | r = r.mid(slash+1);
|
| | | } else {
|
| | | dirs.append(QString());
|
| | | }
|
| | |
|
| | | r.detach(); // Keep m_tmp out of QRegExp's cache
|
| | | QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
|
| | | for (int d = 0; d < dirs.count(); d++) {
|
| | | QString dir = dirs[d];
|
| | | QDir qdir(pfx + dir);
|
| | | for (int i = 0; i < (int)qdir.count(); ++i) {
|
| | | if (qdir[i] == statics.strDot || qdir[i] == statics.strDotDot)
|
| | | continue;
|
| | | QString fname = dir + qdir[i];
|
| | | if (IoUtils::fileType(pfx + fname) == IoUtils::FileIsDir) {
|
| | | if (recursive)
|
| | | dirs.append(fname + QLatin1Char('/'));
|
| | | }
|
| | | if (regex.exactMatch(qdir[i]))
|
| | | ret += ProString(fname).setSource(currentProFile());
|
| | | }
|
| | | }
|
| | | }
|
| | | break;
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | case E_PROMPT: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("prompt(question) requires one argument."));
|
| | | // } else if (currentFileName() == QLatin1String("-")) {
|
| | | // evalError(fL1S("prompt(question) cannot be used when '-o -' is used"));
|
| | | } else {
|
| | | QString msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp1));
|
| | | if (!msg.endsWith(QLatin1Char('?')))
|
| | | msg += QLatin1Char('?');
|
| | | fprintf(stderr, "Project PROMPT: %s ", qPrintable(msg));
|
| | |
|
| | | QFile qfile;
|
| | | if (qfile.open(stdin, QIODevice::ReadOnly)) {
|
| | | QTextStream t(&qfile);
|
| | | ret = split_value_list(t.readLine());
|
| | | }
|
| | | }
|
| | | break; }
|
| | | #endif
|
| | | case E_REPLACE:
|
| | | if (args.count() != 3 ) {
|
| | | evalError(fL1S("replace(var, before, after) requires three arguments."));
|
| | | } else {
|
| | | const QRegExp before(args.at(1).toQString());
|
| | | const QString &after(args.at(2).toQString(m_tmp2));
|
| | | foreach (const ProString &val, values(map(args.at(0)))) {
|
| | | QString rstr = val.toQString(m_tmp1);
|
| | | QString copy = rstr; // Force a detach on modify
|
| | | rstr.replace(before, after);
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? val : ProString(rstr).setSource(val));
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_SORT_DEPENDS:
|
| | | case E_RESOLVE_DEPENDS:
|
| | | if (args.count() < 1 || args.count() > 2) {
|
| | | evalError(fL1S("%1(var, prefix) requires one or two arguments.").arg(func.toQString(m_tmp1)));
|
| | | } else {
|
| | | QHash<ProKey, QSet<ProKey> > dependencies;
|
| | | ProValueMap dependees;
|
| | | ProStringList rootSet;
|
| | | ProStringList orgList = values(args.at(0).toKey());
|
| | | populateDeps(orgList, (args.count() < 2 ? ProString() : args.at(1)),
|
| | | dependencies, dependees, rootSet);
|
| | | for (int i = 0; i < rootSet.size(); ++i) {
|
| | | const ProString &item = rootSet.at(i);
|
| | | if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
|
| | | ret.prepend(item);
|
| | | foreach (const ProString &dep, dependees[item.toKey()]) {
|
| | | QSet<ProKey> &dset = dependencies[dep.toKey()];
|
| | | dset.remove(rootSet.at(i).toKey()); // *Don't* use 'item' - rootSet may have changed!
|
| | | if (dset.isEmpty())
|
| | | rootSet << dep;
|
| | | }
|
| | | }
|
| | | }
|
| | | break;
|
| | | case E_ENUMERATE_VARS: {
|
| | | QSet<ProString> keys;
|
| | | foreach (const ProValueMap &vmap, m_valuemapStack)
|
| | | for (ProValueMap::ConstIterator it = vmap.constBegin(); it != vmap.constEnd(); ++it)
|
| | | keys.insert(it.key());
|
| | | ret.reserve(keys.size());
|
| | | foreach (const ProString &key, keys)
|
| | | ret << key;
|
| | | break; }
|
| | | case E_SHADOWED:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("shadowed(path) requires one argument."));
|
| | | } else {
|
| | | QString rstr = m_option->shadowedPath(resolvePath(args.at(0).toQString(m_tmp1)));
|
| | | if (rstr.isEmpty())
|
| | | break;
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_ABSOLUTE_PATH:
|
| | | if (args.count() > 2) {
|
| | | evalError(fL1S("absolute_path(path[, base]) requires one or two arguments."));
|
| | | } else {
|
| | | QString rstr = QDir::cleanPath(
|
| | | QDir(args.count() > 1 ? args.at(1).toQString(m_tmp2) : currentDirectory())
|
| | | .absoluteFilePath(args.at(0).toQString(m_tmp1)));
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_RELATIVE_PATH:
|
| | | if (args.count() > 2) {
|
| | | evalError(fL1S("relative_path(path[, base]) requires one or two arguments."));
|
| | | } else {
|
| | | QDir baseDir(args.count() > 1 ? args.at(1).toQString(m_tmp2) : currentDirectory());
|
| | | QString rstr = baseDir.relativeFilePath(baseDir.absoluteFilePath(
|
| | | args.at(0).toQString(m_tmp1)));
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_CLEAN_PATH:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("clean_path(path) requires one argument."));
|
| | | } else {
|
| | | QString rstr = QDir::cleanPath(args.at(0).toQString(m_tmp1));
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_SYSTEM_PATH:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("system_path(path) requires one argument."));
|
| | | } else {
|
| | | QString rstr = args.at(0).toQString(m_tmp1);
|
| | | #ifdef Q_OS_WIN
|
| | | rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
| | | #else
|
| | | rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
|
| | | #endif
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_SHELL_PATH:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("shell_path(path) requires one argument."));
|
| | | } else {
|
| | | QString rstr = args.at(0).toQString(m_tmp1);
|
| | | if (m_dirSep.startsWith(QLatin1Char('\\')))
|
| | | rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
| | | else
|
| | | rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_SYSTEM_QUOTE:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("system_quote(arg) requires one argument."));
|
| | | } else {
|
| | | QString rstr = IoUtils::shellQuote(args.at(0).toQString(m_tmp1));
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | case E_SHELL_QUOTE:
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("shell_quote(arg) requires one argument."));
|
| | | } else {
|
| | | QString rstr = args.at(0).toQString(m_tmp1);
|
| | | if (m_dirSep.startsWith(QLatin1Char('\\')))
|
| | | rstr = IoUtils::shellQuoteWin(rstr);
|
| | | else
|
| | | rstr = IoUtils::shellQuoteUnix(rstr);
|
| | | ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
| | | }
|
| | | break;
|
| | | default:
|
| | | evalError(fL1S("Function '%1' is not implemented.").arg(func.toQString(m_tmp1)));
|
| | | break;
|
| | | }
|
| | |
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
| | | int func_t, const ProKey &function, const ProStringList &args)
|
| | | {
|
| | | traceMsg("calling built-in %s(%s)", dbgKey(function), dbgSepStrList(args));
|
| | |
|
| | | switch (func_t) {
|
| | | case T_DEFINED: {
|
| | | if (args.count() < 1 || args.count() > 2) {
|
| | | evalError(fL1S("defined(function, [\"test\"|\"replace\"])"
|
| | | " requires one or two arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const ProKey &var = args.at(0).toKey();
|
| | | if (args.count() > 1) {
|
| | | if (args[1] == QLatin1String("test")) {
|
| | | return returnBool(m_functionDefs.testFunctions.contains(var));
|
| | | } else if (args[1] == QLatin1String("replace")) {
|
| | | return returnBool(m_functionDefs.replaceFunctions.contains(var));
|
| | | } else if (args[1] == QLatin1String("var")) {
|
| | | ProValueMap::Iterator it;
|
| | | return returnBool(findValues(var, &it));
|
| | | }
|
| | | evalError(fL1S("defined(function, type): unexpected type [%1].")
|
| | | .arg(args.at(1).toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | return returnBool(m_functionDefs.replaceFunctions.contains(var)
|
| | | || m_functionDefs.testFunctions.contains(var));
|
| | | }
|
| | | case T_EXPORT: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("export(variable) requires one argument."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const ProKey &var = map(args.at(0));
|
| | | for (ProValueMapStack::Iterator vmi = m_valuemapStack.end();
|
| | | --vmi != m_valuemapStack.begin(); ) {
|
| | | ProValueMap::Iterator it = (*vmi).find(var);
|
| | | if (it != (*vmi).end()) {
|
| | | if (it->constBegin() == statics.fakeValue.constBegin()) {
|
| | | // This is stupid, but qmake doesn't propagate deletions
|
| | | m_valuemapStack.first()[var] = ProStringList();
|
| | | } else {
|
| | | m_valuemapStack.first()[var] = *it;
|
| | | }
|
| | | (*vmi).erase(it);
|
| | | while (--vmi != m_valuemapStack.begin())
|
| | | (*vmi).remove(var);
|
| | | break;
|
| | | }
|
| | | }
|
| | | return ReturnTrue;
|
| | | }
|
| | | case T_INFILE:
|
| | | if (args.count() < 2 || args.count() > 3) {
|
| | | evalError(fL1S("infile(file, var, [values]) requires two or three arguments."));
|
| | | } else {
|
| | | ProValueMap vars;
|
| | | QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
|
| | | fn.detach();
|
| | | VisitReturn ok = evaluateFileInto(fn, &vars, LoadProOnly);
|
| | | if (ok != ReturnTrue)
|
| | | return ok;
|
| | | if (args.count() == 2)
|
| | | return returnBool(vars.contains(map(args.at(1))));
|
| | | QRegExp regx;
|
| | | const QString &qry = args.at(2).toQString(m_tmp1);
|
| | | if (qry != QRegExp::escape(qry)) {
|
| | | QString copy = qry;
|
| | | copy.detach();
|
| | | regx.setPattern(copy);
|
| | | }
|
| | | int t = 0;
|
| | | foreach (const ProString &s, vars.value(map(args.at(1)))) {
|
| | | if ((!regx.isEmpty() && regx.exactMatch(s.toQString(m_tmp[t]))) || s == qry)
|
| | | return ReturnTrue;
|
| | | t ^= 1;
|
| | | }
|
| | | }
|
| | | return ReturnFalse;
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | case T_REQUIRES:
|
| | | checkRequirements(args);
|
| | | return ReturnFalse; // Another qmake breakage
|
| | | #endif
|
| | | case T_EVAL: {
|
| | | VisitReturn ret = ReturnFalse;
|
| | | ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
|
| | | m_current.pro->fileName(), m_current.line);
|
| | | if (pro) {
|
| | | if (m_cumulative || pro->isOk()) {
|
| | | m_locationStack.push(m_current);
|
| | | visitProBlock(pro, pro->tokPtr());
|
| | | ret = ReturnTrue; // This return value is not too useful, but that's qmake
|
| | | m_current = m_locationStack.pop();
|
| | | }
|
| | | pro->deref();
|
| | | }
|
| | | return ret;
|
| | | }
|
| | | case T_IF: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("if(condition) requires one argument."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | return returnBool(evaluateConditional(args.at(0).toQString(),
|
| | | m_current.pro->fileName(), m_current.line));
|
| | | }
|
| | | case T_CONFIG: {
|
| | | if (args.count() < 1 || args.count() > 2) {
|
| | | evalError(fL1S("CONFIG(config) requires one or two arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | if (args.count() == 1)
|
| | | return returnBool(isActiveConfig(args.at(0).toQString(m_tmp2)));
|
| | | const QStringList &mutuals = args.at(1).toQString(m_tmp2).split(QLatin1Char('|'));
|
| | | const ProStringList &configs = values(statics.strCONFIG);
|
| | |
|
| | | for (int i = configs.size() - 1; i >= 0; i--) {
|
| | | for (int mut = 0; mut < mutuals.count(); mut++) {
|
| | | if (configs[i] == mutuals[mut].trimmed()) {
|
| | | return returnBool(configs[i] == args[0]);
|
| | | }
|
| | | }
|
| | | }
|
| | | return ReturnFalse;
|
| | | }
|
| | | case T_CONTAINS: {
|
| | | if (args.count() < 2 || args.count() > 3) {
|
| | | evalError(fL1S("contains(var, val) requires two or three arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | |
|
| | | const QString &qry = args.at(1).toQString(m_tmp1);
|
| | | QRegExp regx;
|
| | | if (qry != QRegExp::escape(qry)) {
|
| | | QString copy = qry;
|
| | | copy.detach();
|
| | | regx.setPattern(copy);
|
| | | }
|
| | | const ProStringList &l = values(map(args.at(0)));
|
| | | if (args.count() == 2) {
|
| | | int t = 0;
|
| | | for (int i = 0; i < l.size(); ++i) {
|
| | | const ProString &val = l[i];
|
| | | if ((!regx.isEmpty() && regx.exactMatch(val.toQString(m_tmp[t]))) || val == qry)
|
| | | return ReturnTrue;
|
| | | t ^= 1;
|
| | | }
|
| | | } else {
|
| | | const QStringList &mutuals = args.at(2).toQString(m_tmp3).split(QLatin1Char('|'));
|
| | | for (int i = l.size() - 1; i >= 0; i--) {
|
| | | const ProString val = l[i];
|
| | | for (int mut = 0; mut < mutuals.count(); mut++) {
|
| | | if (val == mutuals[mut].trimmed()) {
|
| | | return returnBool((!regx.isEmpty()
|
| | | && regx.exactMatch(val.toQString(m_tmp2)))
|
| | | || val == qry);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | return ReturnFalse;
|
| | | }
|
| | | case T_COUNT: {
|
| | | if (args.count() != 2 && args.count() != 3) {
|
| | | evalError(fL1S("count(var, count, op=\"equals\") requires two or three arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | int cnt = values(map(args.at(0))).count();
|
| | | if (args.count() == 3) {
|
| | | const ProString &comp = args.at(2);
|
| | | const int val = args.at(1).toQString(m_tmp1).toInt();
|
| | | if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
|
| | | return returnBool(cnt > val);
|
| | | } else if (comp == QLatin1String(">=")) {
|
| | | return returnBool(cnt >= val);
|
| | | } else if (comp == QLatin1String("<") || comp == QLatin1String("lessThan")) {
|
| | | return returnBool(cnt < val);
|
| | | } else if (comp == QLatin1String("<=")) {
|
| | | return returnBool(cnt <= val);
|
| | | } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
|
| | | || comp == QLatin1String("=") || comp == QLatin1String("==")) {
|
| | | return returnBool(cnt == val);
|
| | | } else {
|
| | | evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | }
|
| | | return returnBool(cnt == args.at(1).toQString(m_tmp1).toInt());
|
| | | }
|
| | | case T_GREATERTHAN:
|
| | | case T_LESSTHAN: {
|
| | | if (args.count() != 2) {
|
| | | evalError(fL1S("%1(variable, value) requires two arguments.")
|
| | | .arg(function.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const QString &rhs(args.at(1).toQString(m_tmp1)),
|
| | | &lhs(values(map(args.at(0))).join(statics.field_sep));
|
| | | bool ok;
|
| | | int rhs_int = rhs.toInt(&ok);
|
| | | if (ok) { // do integer compare
|
| | | int lhs_int = lhs.toInt(&ok);
|
| | | if (ok) {
|
| | | if (func_t == T_GREATERTHAN)
|
| | | return returnBool(lhs_int > rhs_int);
|
| | | return returnBool(lhs_int < rhs_int);
|
| | | }
|
| | | }
|
| | | if (func_t == T_GREATERTHAN)
|
| | | return returnBool(lhs > rhs);
|
| | | return returnBool(lhs < rhs);
|
| | | }
|
| | | case T_EQUALS:
|
| | | if (args.count() != 2) {
|
| | | evalError(fL1S("%1(variable, value) requires two arguments.")
|
| | | .arg(function.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | return returnBool(values(map(args.at(0))).join(statics.field_sep)
|
| | | == args.at(1).toQString(m_tmp1));
|
| | | case T_CLEAR: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("%1(variable) requires one argument.")
|
| | | .arg(function.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | ProValueMap *hsh;
|
| | | ProValueMap::Iterator it;
|
| | | const ProKey &var = map(args.at(0));
|
| | | if (!(hsh = findValues(var, &it)))
|
| | | return ReturnFalse;
|
| | | if (hsh == &m_valuemapStack.top())
|
| | | it->clear();
|
| | | else
|
| | | m_valuemapStack.top()[var].clear();
|
| | | return ReturnTrue;
|
| | | }
|
| | | case T_UNSET: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("%1(variable) requires one argument.")
|
| | | .arg(function.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | ProValueMap *hsh;
|
| | | ProValueMap::Iterator it;
|
| | | const ProKey &var = map(args.at(0));
|
| | | if (!(hsh = findValues(var, &it)))
|
| | | return ReturnFalse;
|
| | | if (m_valuemapStack.size() == 1)
|
| | | hsh->erase(it);
|
| | | else if (hsh == &m_valuemapStack.top())
|
| | | *it = statics.fakeValue;
|
| | | else
|
| | | m_valuemapStack.top()[var] = statics.fakeValue;
|
| | | return ReturnTrue;
|
| | | }
|
| | | case T_INCLUDE: {
|
| | | if (args.count() < 1 || args.count() > 3) {
|
| | | evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | QString parseInto;
|
| | | LoadFlags flags = 0;
|
| | | if (args.count() >= 2) {
|
| | | parseInto = args.at(1).toQString(m_tmp2);
|
| | | if (args.count() >= 3 && isTrue(args.at(2), m_tmp3))
|
| | | flags = LoadSilent;
|
| | | }
|
| | | QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
|
| | | fn.detach();
|
| | | VisitReturn ok;
|
| | | if (parseInto.isEmpty()) {
|
| | | ok = evaluateFileChecked(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags);
|
| | | } else {
|
| | | ProValueMap symbols;
|
| | | if ((ok = evaluateFileInto(fn, &symbols, LoadAll | flags)) == ReturnTrue) {
|
| | | ProValueMap newMap;
|
| | | for (ProValueMap::ConstIterator
|
| | | it = m_valuemapStack.top().constBegin(),
|
| | | end = m_valuemapStack.top().constEnd();
|
| | | it != end; ++it) {
|
| | | const QString &ky = it.key().toQString(m_tmp1);
|
| | | if (!(ky.startsWith(parseInto) &&
|
| | | (ky.length() == parseInto.length()
|
| | | || ky.at(parseInto.length()) == QLatin1Char('.'))))
|
| | | newMap[it.key()] = it.value();
|
| | | }
|
| | | for (ProValueMap::ConstIterator it = symbols.constBegin();
|
| | | it != symbols.constEnd(); ++it) {
|
| | | const QString &ky = it.key().toQString(m_tmp1);
|
| | | if (!ky.startsWith(QLatin1Char('.')))
|
| | | newMap.insert(ProKey(parseInto + QLatin1Char('.') + ky), it.value());
|
| | | }
|
| | | m_valuemapStack.top() = newMap;
|
| | | }
|
| | | }
|
| | | if (ok == ReturnFalse && (flags & LoadSilent))
|
| | | ok = ReturnTrue;
|
| | | return ok;
|
| | | }
|
| | | case T_LOAD: {
|
| | | bool ignore_error = false;
|
| | | if (args.count() == 2) {
|
| | | ignore_error = isTrue(args.at(1), m_tmp2);
|
| | | } else if (args.count() != 1) {
|
| | | evalError(fL1S("load(feature) requires one or two arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | VisitReturn ok = evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString()),
|
| | | ignore_error);
|
| | | if (ok == ReturnFalse && ignore_error)
|
| | | ok = ReturnTrue;
|
| | | return ok;
|
| | | }
|
| | | case T_DEBUG: {
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | if (args.count() != 2) {
|
| | | evalError(fL1S("debug(level, message) requires two arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | int level = args.at(0).toInt();
|
| | | if (level <= m_debugLevel) {
|
| | | const QString &msg = m_option->expandEnvVars(args.at(1).toQString(m_tmp2));
|
| | | debugMsg(level, "Project DEBUG: %s", qPrintable(msg));
|
| | | }
|
| | | #endif
|
| | | return ReturnTrue;
|
| | | }
|
| | | case T_LOG:
|
| | | case T_ERROR:
|
| | | case T_WARNING:
|
| | | case T_MESSAGE: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("%1(message) requires one argument.")
|
| | | .arg(function.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const QString &msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp2));
|
| | | if (!m_skipLevel) {
|
| | | if (func_t == T_LOG) {
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | fputs(msg.toLatin1().constData(), stderr);
|
| | | #endif
|
| | | } else {
|
| | | m_handler->fileMessage(fL1S("Project %1: %2")
|
| | | .arg(function.toQString(m_tmp1).toUpper(), msg));
|
| | | }
|
| | | }
|
| | | return (func_t == T_ERROR && !m_cumulative) ? ReturnError : ReturnTrue;
|
| | | }
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | case T_SYSTEM: {
|
| | | if (m_cumulative) // Anything else would be insanity
|
| | | return ReturnFalse;
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("system(exec) requires one argument."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | QProcess proc;
|
| | | proc.setProcessChannelMode(QProcess::ForwardedChannels);
|
| | | runProcess(&proc, args.at(0).toQString(m_tmp2));
|
| | | return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0);
|
| | | #else
|
| | | return returnBool(system((QLatin1String("cd ")
|
| | | + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
|
| | | + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0);
|
| | | #endif
|
| | | }
|
| | | #endif
|
| | | case T_ISEMPTY: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("isEmpty(var) requires one argument."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | return returnBool(values(map(args.at(0))).isEmpty());
|
| | | }
|
| | | case T_EXISTS: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("exists(file) requires one argument."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const QString &file = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
|
| | |
|
| | | if (IoUtils::exists(file)) {
|
| | | return ReturnTrue;
|
| | | }
|
| | | int slsh = file.lastIndexOf(QLatin1Char('/'));
|
| | | QString fn = file.mid(slsh+1);
|
| | | if (fn.contains(QLatin1Char('*')) || fn.contains(QLatin1Char('?'))) {
|
| | | QString dirstr = file.left(slsh+1);
|
| | | if (!QDir(dirstr).entryList(QStringList(fn)).isEmpty())
|
| | | return ReturnTrue;
|
| | | }
|
| | |
|
| | | return ReturnFalse;
|
| | | }
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | case T_MKPATH: {
|
| | | if (args.count() != 1) {
|
| | | evalError(fL1S("mkpath(file) requires one argument."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const QString &fn = resolvePath(args.at(0).toQString(m_tmp1));
|
| | | if (!QDir::current().mkpath(fn)) {
|
| | | evalError(fL1S("Cannot create directory %1.").arg(QDir::toNativeSeparators(fn)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | return ReturnTrue;
|
| | | }
|
| | | case T_WRITE_FILE: {
|
| | | if (args.count() > 3) {
|
| | | evalError(fL1S("write_file(name, [content var, [append]]) requires one to three arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | QIODevice::OpenMode mode = QIODevice::Truncate;
|
| | | QString contents;
|
| | | if (args.count() >= 2) {
|
| | | const ProStringList &vals = values(args.at(1).toKey());
|
| | | if (!vals.isEmpty())
|
| | | contents = vals.join(fL1S("\n")) + QLatin1Char('\n');
|
| | | if (args.count() >= 3)
|
| | | if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive))
|
| | | mode = QIODevice::Append;
|
| | | }
|
| | | return writeFile(QString(), resolvePath(args.at(0).toQString(m_tmp1)), mode, contents);
|
| | | }
|
| | | case T_TOUCH: {
|
| | | if (args.count() != 2) {
|
| | | evalError(fL1S("touch(file, reffile) requires two arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | const QString &tfn = resolvePath(args.at(0).toQString(m_tmp1));
|
| | | const QString &rfn = resolvePath(args.at(1).toQString(m_tmp2));
|
| | | #ifdef Q_OS_UNIX
|
| | | struct stat st;
|
| | | if (stat(rfn.toLocal8Bit().constData(), &st)) {
|
| | | evalError(fL1S("Cannot stat() reference file %1: %2.").arg(rfn, fL1S(strerror(errno))));
|
| | | return ReturnFalse;
|
| | | }
|
| | | struct utimbuf utb;
|
| | | utb.actime = time(0);
|
| | | utb.modtime = st.st_mtime;
|
| | | if (utime(tfn.toLocal8Bit().constData(), &utb)) {
|
| | | evalError(fL1S("Cannot touch %1: %2.").arg(tfn, fL1S(strerror(errno))));
|
| | | return ReturnFalse;
|
| | | }
|
| | | #else
|
| | | HANDLE rHand = CreateFile((wchar_t*)rfn.utf16(),
|
| | | GENERIC_READ, FILE_SHARE_READ,
|
| | | NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| | | if (rHand == INVALID_HANDLE_VALUE) {
|
| | | evalError(fL1S("Cannot open() reference file %1: %2.").arg(rfn, windowsErrorCode()));
|
| | | return ReturnFalse;
|
| | | }
|
| | | FILETIME ft;
|
| | | GetFileTime(rHand, 0, 0, &ft);
|
| | | CloseHandle(rHand);
|
| | | HANDLE wHand = CreateFile((wchar_t*)tfn.utf16(),
|
| | | GENERIC_WRITE, FILE_SHARE_READ,
|
| | | NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| | | if (wHand == INVALID_HANDLE_VALUE) {
|
| | | evalError(fL1S("Cannot open() %1: %2.").arg(tfn, windowsErrorCode()));
|
| | | return ReturnFalse;
|
| | | }
|
| | | SetFileTime(wHand, 0, 0, &ft);
|
| | | CloseHandle(wHand);
|
| | | #endif
|
| | | return ReturnTrue;
|
| | | }
|
| | | case T_CACHE: {
|
| | | if (args.count() > 3) {
|
| | | evalError(fL1S("cache(var, [set|add|sub] [transient] [super], [srcvar]) requires one to three arguments."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | bool persist = true;
|
| | | bool super = false;
|
| | | enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet;
|
| | | ProKey srcvar;
|
| | | if (args.count() >= 2) {
|
| | | foreach (const ProString &opt, split_value_list(args.at(1).toQString(m_tmp2))) {
|
| | | opt.toQString(m_tmp3);
|
| | | if (m_tmp3 == QLatin1String("transient")) {
|
| | | persist = false;
|
| | | } else if (m_tmp3 == QLatin1String("super")) {
|
| | | super = true;
|
| | | } else if (m_tmp3 == QLatin1String("set")) {
|
| | | mode = CacheSet;
|
| | | } else if (m_tmp3 == QLatin1String("add")) {
|
| | | mode = CacheAdd;
|
| | | } else if (m_tmp3 == QLatin1String("sub")) {
|
| | | mode = CacheSub;
|
| | | } else {
|
| | | evalError(fL1S("cache(): invalid flag %1.").arg(m_tmp3));
|
| | | return ReturnFalse;
|
| | | }
|
| | | }
|
| | | if (args.count() >= 3) {
|
| | | srcvar = args.at(2).toKey();
|
| | | } else if (mode != CacheSet) {
|
| | | evalError(fL1S("cache(): modes other than 'set' require a source variable."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | }
|
| | | QString varstr;
|
| | | ProKey dstvar = args.at(0).toKey();
|
| | | if (!dstvar.isEmpty()) {
|
| | | if (srcvar.isEmpty())
|
| | | srcvar = dstvar;
|
| | | ProValueMap::Iterator srcvarIt;
|
| | | if (!findValues(srcvar, &srcvarIt)) {
|
| | | evalError(fL1S("Variable %1 is not defined.").arg(srcvar.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | // The caches for the host and target may differ (e.g., when we are manipulating
|
| | | // CONFIG), so we cannot compute a common new value for both.
|
| | | const ProStringList &diffval = *srcvarIt;
|
| | | ProStringList newval;
|
| | | bool changed = false;
|
| | | for (bool hostBuild = false; ; hostBuild = true) {
|
| | | if (QMakeBaseEnv *baseEnv = m_option->baseEnvs.value(
|
| | | QMakeBaseKey(m_buildRoot, hostBuild))) {
|
| | | QMakeEvaluator *baseEval = baseEnv->evaluator;
|
| | | const ProStringList &oldval = baseEval->values(dstvar);
|
| | | if (mode == CacheSet) {
|
| | | newval = diffval;
|
| | | } else {
|
| | | newval = oldval;
|
| | | if (mode == CacheAdd)
|
| | | newval += diffval;
|
| | | else
|
| | | removeEach(&newval, diffval);
|
| | | }
|
| | | if (oldval != newval) {
|
| | | baseEval->valuesRef(dstvar) = newval;
|
| | | if (super) {
|
| | | do {
|
| | | if (dstvar == QLatin1String("QMAKEPATH")) {
|
| | | baseEval->m_qmakepath = newval.toQStringList();
|
| | | baseEval->updateMkspecPaths();
|
| | | } else if (dstvar == QLatin1String("QMAKEFEATURES")) {
|
| | | baseEval->m_qmakefeatures = newval.toQStringList();
|
| | | } else {
|
| | | break;
|
| | | }
|
| | | baseEval->updateFeaturePaths();
|
| | | if (hostBuild == m_hostBuild)
|
| | | m_featureRoots = baseEval->m_featureRoots;
|
| | | } while (false);
|
| | | }
|
| | | changed = true;
|
| | | }
|
| | | }
|
| | | if (hostBuild)
|
| | | break;
|
| | | }
|
| | | // We assume that whatever got the cached value to be what it is now will do so
|
| | | // the next time as well, so we just skip the persisting if nothing changed.
|
| | | if (!persist || !changed)
|
| | | return ReturnTrue;
|
| | | varstr = dstvar.toQString();
|
| | | if (mode == CacheAdd)
|
| | | varstr += QLatin1String(" +=");
|
| | | else if (mode == CacheSub)
|
| | | varstr += QLatin1String(" -=");
|
| | | else
|
| | | varstr += QLatin1String(" =");
|
| | | if (diffval.count() == 1) {
|
| | | varstr += QLatin1Char(' ');
|
| | | varstr += quoteValue(diffval.at(0));
|
| | | } else if (!diffval.isEmpty()) {
|
| | | foreach (const ProString &vval, diffval) {
|
| | | varstr += QLatin1String(" \\\n ");
|
| | | varstr += quoteValue(vval);
|
| | | }
|
| | | }
|
| | | varstr += QLatin1Char('\n');
|
| | | }
|
| | | QString fn;
|
| | | if (super) {
|
| | | if (m_superfile.isEmpty()) {
|
| | | m_superfile = m_outputDir + QLatin1String("/.qmake.super");
|
| | | printf("Info: creating super cache file %s\n", qPrintable(m_superfile));
|
| | | valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
|
| | | }
|
| | | fn = m_superfile;
|
| | | } else {
|
| | | if (m_cachefile.isEmpty()) {
|
| | | m_cachefile = m_outputDir + QLatin1String("/.qmake.cache");
|
| | | printf("Info: creating cache file %s\n", qPrintable(m_cachefile));
|
| | | valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
|
| | | // We could update m_{source,build}Root and m_featureRoots here, or even
|
| | | // "re-home" our rootEnv, but this doesn't sound too useful - if somebody
|
| | | // wanted qmake to find something in the build directory, he could have
|
| | | // done so "from the outside".
|
| | | // The sub-projects will find the new cache all by themselves.
|
| | | }
|
| | | fn = m_cachefile;
|
| | | }
|
| | | return writeFile(fL1S("cache "), fn, QIODevice::Append, varstr);
|
| | | }
|
| | | #endif
|
| | | default:
|
| | | evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | | }
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qmakeevaluator.h"
|
| | | #include "qmakeevaluator_p.h"
|
| | |
|
| | | #include "qmakeglobals.h"
|
| | | #include "qmakeparser.h"
|
| | | #include "ioutils.h"
|
| | |
|
| | | #include <qbytearray.h>
|
| | | #include <qdatetime.h>
|
| | | #include <qdebug.h>
|
| | | #include <qdir.h>
|
| | | #include <qfile.h>
|
| | | #include <qfileinfo.h>
|
| | | #include <qlist.h>
|
| | | #include <qregexp.h>
|
| | | #include <qset.h>
|
| | | #include <qstack.h>
|
| | | #include <qstring.h>
|
| | | #include <qstringlist.h>
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | # include <qthreadpool.h>
|
| | | #endif
|
| | |
|
| | | #ifdef Q_OS_UNIX
|
| | | #include <unistd.h>
|
| | | #include <sys/utsname.h>
|
| | | #else
|
| | | #include <windows.h>
|
| | | #endif
|
| | | #include <stdio.h>
|
| | | #include <stdlib.h>
|
| | |
|
| | | using namespace QMakeInternal;
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | #define fL1S(s) QString::fromLatin1(s)
|
| | |
|
| | |
|
| | | QMakeBaseKey::QMakeBaseKey(const QString &_root, bool _hostBuild)
|
| | | : root(_root), hostBuild(_hostBuild)
|
| | | {
|
| | | }
|
| | |
|
| | | uint qHash(const QMakeBaseKey &key)
|
| | | {
|
| | | return qHash(key.root) ^ (uint)key.hostBuild;
|
| | | }
|
| | |
|
| | | bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two)
|
| | | {
|
| | | return one.root == two.root && one.hostBuild == two.hostBuild;
|
| | | }
|
| | |
|
| | | QMakeBaseEnv::QMakeBaseEnv()
|
| | | : evaluator(0)
|
| | | {
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | inProgress = false;
|
| | | isOk = false;
|
| | | #endif
|
| | | }
|
| | |
|
| | | QMakeBaseEnv::~QMakeBaseEnv()
|
| | | {
|
| | | delete evaluator;
|
| | | }
|
| | |
|
| | | namespace QMakeInternal {
|
| | | QMakeStatics statics;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::initStatics()
|
| | | {
|
| | | if (!statics.field_sep.isNull())
|
| | | return;
|
| | |
|
| | | statics.field_sep = QLatin1String(" ");
|
| | | statics.strtrue = QLatin1String("true");
|
| | | statics.strfalse = QLatin1String("false");
|
| | | statics.strCONFIG = ProKey("CONFIG");
|
| | | statics.strARGS = ProKey("ARGS");
|
| | | statics.strDot = QLatin1String(".");
|
| | | statics.strDotDot = QLatin1String("..");
|
| | | statics.strever = QLatin1String("ever");
|
| | | statics.strforever = QLatin1String("forever");
|
| | | statics.strhost_build = QLatin1String("host_build");
|
| | | statics.strTEMPLATE = ProKey("TEMPLATE");
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | statics.strREQUIRES = ProKey("REQUIRES");
|
| | | #endif
|
| | |
|
| | | statics.fakeValue = ProStringList(ProString("_FAKE_")); // It has to have a unique begin() value
|
| | |
|
| | | initFunctionStatics();
|
| | |
|
| | | static const struct {
|
| | | const char * const oldname, * const newname;
|
| | | } mapInits[] = {
|
| | | { "INTERFACES", "FORMS" },
|
| | | { "QMAKE_POST_BUILD", "QMAKE_POST_LINK" },
|
| | | { "TARGETDEPS", "POST_TARGETDEPS" },
|
| | | { "LIBPATH", "QMAKE_LIBDIR" },
|
| | | { "QMAKE_EXT_MOC", "QMAKE_EXT_CPP_MOC" },
|
| | | { "QMAKE_MOD_MOC", "QMAKE_H_MOD_MOC" },
|
| | | { "QMAKE_LFLAGS_SHAPP", "QMAKE_LFLAGS_APP" },
|
| | | { "PRECOMPH", "PRECOMPILED_HEADER" },
|
| | | { "PRECOMPCPP", "PRECOMPILED_SOURCE" },
|
| | | { "INCPATH", "INCLUDEPATH" },
|
| | | { "QMAKE_EXTRA_WIN_COMPILERS", "QMAKE_EXTRA_COMPILERS" },
|
| | | { "QMAKE_EXTRA_UNIX_COMPILERS", "QMAKE_EXTRA_COMPILERS" },
|
| | | { "QMAKE_EXTRA_WIN_TARGETS", "QMAKE_EXTRA_TARGETS" },
|
| | | { "QMAKE_EXTRA_UNIX_TARGETS", "QMAKE_EXTRA_TARGETS" },
|
| | | { "QMAKE_EXTRA_UNIX_INCLUDES", "QMAKE_EXTRA_INCLUDES" },
|
| | | { "QMAKE_EXTRA_UNIX_VARIABLES", "QMAKE_EXTRA_VARIABLES" },
|
| | | { "QMAKE_RPATH", "QMAKE_LFLAGS_RPATH" },
|
| | | { "QMAKE_FRAMEWORKDIR", "QMAKE_FRAMEWORKPATH" },
|
| | | { "QMAKE_FRAMEWORKDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS" },
|
| | | { "IN_PWD", "PWD" }
|
| | | };
|
| | | for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i)
|
| | | statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname));
|
| | | }
|
| | |
|
| | | const ProKey &QMakeEvaluator::map(const ProKey &var)
|
| | | {
|
| | | QHash<ProKey, ProKey>::ConstIterator it = statics.varMap.constFind(var);
|
| | | if (it == statics.varMap.constEnd())
|
| | | return var;
|
| | | deprecationWarning(fL1S("Variable %1 is deprecated; use %2 instead.")
|
| | | .arg(var.toQString(), it.value().toQString()));
|
| | | return it.value();
|
| | | }
|
| | |
|
| | |
|
| | | QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option,
|
| | | QMakeParser *parser, QMakeHandler *handler)
|
| | | :
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | m_debugLevel(option->debugLevel),
|
| | | #endif
|
| | | m_option(option), m_parser(parser), m_handler(handler)
|
| | | {
|
| | | // So that single-threaded apps don't have to call initialize() for now.
|
| | | initStatics();
|
| | |
|
| | | // Configuration, more or less
|
| | | m_caller = 0;
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | m_cumulative = false;
|
| | | #endif
|
| | | m_hostBuild = false;
|
| | |
|
| | | // Evaluator state
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | m_skipLevel = 0;
|
| | | #endif
|
| | | m_listCount = 0;
|
| | | m_valuemapStack.push(ProValueMap());
|
| | | m_valuemapInited = false;
|
| | | }
|
| | |
|
| | | QMakeEvaluator::~QMakeEvaluator()
|
| | | {
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::initFrom(const QMakeEvaluator &other)
|
| | | {
|
| | | Q_ASSERT_X(&other, "QMakeEvaluator::visitProFile", "Project not prepared");
|
| | | m_functionDefs = other.m_functionDefs;
|
| | | m_valuemapStack = other.m_valuemapStack;
|
| | | m_valuemapInited = true;
|
| | | m_qmakespec = other.m_qmakespec;
|
| | | m_qmakespecName = other.m_qmakespecName;
|
| | | m_mkspecPaths = other.m_mkspecPaths;
|
| | | m_featureRoots = other.m_featureRoots;
|
| | | m_dirSep = other.m_dirSep;
|
| | | }
|
| | |
|
| | | //////// Evaluator tools /////////
|
| | |
|
| | | uint QMakeEvaluator::getBlockLen(const ushort *&tokPtr)
|
| | | {
|
| | | uint len = *tokPtr++;
|
| | | len |= (uint)*tokPtr++ << 16;
|
| | | return len;
|
| | | }
|
| | |
|
| | | ProString QMakeEvaluator::getStr(const ushort *&tokPtr)
|
| | | {
|
| | | uint len = *tokPtr++;
|
| | | ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len);
|
| | | ret.setSource(m_current.pro);
|
| | | tokPtr += len;
|
| | | return ret;
|
| | | }
|
| | |
|
| | | ProKey QMakeEvaluator::getHashStr(const ushort *&tokPtr)
|
| | | {
|
| | | uint hash = getBlockLen(tokPtr);
|
| | | uint len = *tokPtr++;
|
| | | ProKey ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, hash);
|
| | | tokPtr += len;
|
| | | return ret;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::skipStr(const ushort *&tokPtr)
|
| | | {
|
| | | uint len = *tokPtr++;
|
| | | tokPtr += len;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::skipHashStr(const ushort *&tokPtr)
|
| | | {
|
| | | tokPtr += 2;
|
| | | uint len = *tokPtr++;
|
| | | tokPtr += len;
|
| | | }
|
| | |
|
| | | // FIXME: this should not build new strings for direct sections.
|
| | | // Note that the E_SPRINTF and E_LIST implementations rely on the deep copy.
|
| | | ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFile *source)
|
| | | {
|
| | | QString build;
|
| | | ProStringList ret;
|
| | | QStack<char> quote;
|
| | |
|
| | | const ushort SPACE = ' ';
|
| | | const ushort LPAREN = '(';
|
| | | const ushort RPAREN = ')';
|
| | | const ushort SINGLEQUOTE = '\'';
|
| | | const ushort DOUBLEQUOTE = '"';
|
| | | const ushort BACKSLASH = '\\';
|
| | |
|
| | | if (!source)
|
| | | source = currentProFile();
|
| | |
|
| | | ushort unicode;
|
| | | const QChar *vals_data = vals.data();
|
| | | const int vals_len = vals.length();
|
| | | int parens = 0;
|
| | | for (int x = 0; x < vals_len; x++) {
|
| | | unicode = vals_data[x].unicode();
|
| | | if (x != (int)vals_len-1 && unicode == BACKSLASH &&
|
| | | (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
|
| | | build += vals_data[x++]; //get that 'escape'
|
| | | } else if (!quote.isEmpty() && unicode == quote.top()) {
|
| | | quote.pop();
|
| | | } else if (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE) {
|
| | | quote.push(unicode);
|
| | | } else if (unicode == RPAREN) {
|
| | | --parens;
|
| | | } else if (unicode == LPAREN) {
|
| | | ++parens;
|
| | | }
|
| | |
|
| | | if (!parens && quote.isEmpty() && vals_data[x] == SPACE) {
|
| | | ret << ProString(build).setSource(source);
|
| | | build.clear();
|
| | | } else {
|
| | | build += vals_data[x];
|
| | | }
|
| | | }
|
| | | if (!build.isEmpty())
|
| | | ret << ProString(build).setSource(source);
|
| | | if (parens)
|
| | | deprecationWarning(fL1S("Unmatched parentheses are deprecated."));
|
| | | return ret;
|
| | | }
|
| | |
|
| | | static void zipEmpty(ProStringList *value)
|
| | | {
|
| | | for (int i = value->size(); --i >= 0;)
|
| | | if (value->at(i).isEmpty())
|
| | | value->remove(i);
|
| | | }
|
| | |
|
| | | static void insertUnique(ProStringList *varlist, const ProStringList &value)
|
| | | {
|
| | | foreach (const ProString &str, value)
|
| | | if (!str.isEmpty() && !varlist->contains(str))
|
| | | varlist->append(str);
|
| | | }
|
| | |
|
| | | static void removeAll(ProStringList *varlist, const ProString &value)
|
| | | {
|
| | | for (int i = varlist->size(); --i >= 0; )
|
| | | if (varlist->at(i) == value)
|
| | | varlist->remove(i);
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::removeEach(ProStringList *varlist, const ProStringList &value)
|
| | | {
|
| | | foreach (const ProString &str, value)
|
| | | if (!str.isEmpty())
|
| | | removeAll(varlist, str);
|
| | | }
|
| | |
|
| | | static void replaceInList(ProStringList *varlist,
|
| | | const QRegExp ®exp, const QString &replace, bool global, QString &tmp)
|
| | | {
|
| | | for (ProStringList::Iterator varit = varlist->begin(); varit != varlist->end(); ) {
|
| | | QString val = varit->toQString(tmp);
|
| | | QString copy = val; // Force detach and have a reference value
|
| | | val.replace(regexp, replace);
|
| | | if (!val.isSharedWith(copy) && val != copy) {
|
| | | if (val.isEmpty()) {
|
| | | varit = varlist->erase(varit);
|
| | | } else {
|
| | | (*varit).setValue(val);
|
| | | ++varit;
|
| | | }
|
| | | if (!global)
|
| | | break;
|
| | | } else {
|
| | | ++varit;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | //////// Evaluator /////////
|
| | |
|
| | | static ALWAYS_INLINE void addStr(
|
| | | const ProString &str, ProStringList *ret, bool &pending, bool joined)
|
| | | {
|
| | | if (joined) {
|
| | | ret->last().append(str, &pending);
|
| | | } else {
|
| | | if (!pending) {
|
| | | pending = true;
|
| | | *ret << str;
|
| | | } else {
|
| | | ret->last().append(str);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | static ALWAYS_INLINE void addStrList(
|
| | | const ProStringList &list, ushort tok, ProStringList *ret, bool &pending, bool joined)
|
| | | {
|
| | | if (!list.isEmpty()) {
|
| | | if (joined) {
|
| | | ret->last().append(list, &pending, !(tok & TokQuoted));
|
| | | } else {
|
| | | if (tok & TokQuoted) {
|
| | | if (!pending) {
|
| | | pending = true;
|
| | | *ret << ProString();
|
| | | }
|
| | | ret->last().append(list);
|
| | | } else {
|
| | | if (!pending) {
|
| | | // Another qmake bizzarity: if nothing is pending and the
|
| | | // first element is empty, it will be eaten
|
| | | if (!list.at(0).isEmpty()) {
|
| | | // The common case
|
| | | pending = true;
|
| | | *ret += list;
|
| | | return;
|
| | | }
|
| | | } else {
|
| | | ret->last().append(list.at(0));
|
| | | }
|
| | | // This is somewhat slow, but a corner case
|
| | | for (int j = 1; j < list.size(); ++j) {
|
| | | pending = true;
|
| | | *ret << list.at(j);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::evaluateExpression(
|
| | | const ushort *&tokPtr, ProStringList *ret, bool joined)
|
| | | {
|
| | | debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression");
|
| | | if (joined)
|
| | | *ret << ProString();
|
| | | bool pending = false;
|
| | | forever {
|
| | | ushort tok = *tokPtr++;
|
| | | if (tok & TokNewStr) {
|
| | | debugMsg(2, "new string");
|
| | | pending = false;
|
| | | }
|
| | | ushort maskedTok = tok & TokMask;
|
| | | switch (maskedTok) {
|
| | | case TokLine:
|
| | | m_current.line = *tokPtr++;
|
| | | break;
|
| | | case TokLiteral: {
|
| | | const ProString &val = getStr(tokPtr);
|
| | | debugMsg(2, "literal %s", dbgStr(val));
|
| | | addStr(val, ret, pending, joined);
|
| | | break; }
|
| | | case TokHashLiteral: {
|
| | | const ProKey &val = getHashStr(tokPtr);
|
| | | debugMsg(2, "hashed literal %s", dbgStr(val.toString()));
|
| | | addStr(val, ret, pending, joined);
|
| | | break; }
|
| | | case TokVariable: {
|
| | | const ProKey &var = getHashStr(tokPtr);
|
| | | const ProStringList &val = values(map(var));
|
| | | debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val));
|
| | | addStrList(val, tok, ret, pending, joined);
|
| | | break; }
|
| | | case TokProperty: {
|
| | | const ProKey &var = getHashStr(tokPtr);
|
| | | const ProString &val = propertyValue(var);
|
| | | debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val));
|
| | | addStr(val, ret, pending, joined);
|
| | | break; }
|
| | | case TokEnvVar: {
|
| | | const ProString &var = getStr(tokPtr);
|
| | | const ProStringList &val = split_value_list(m_option->getEnv(var.toQString(m_tmp1)));
|
| | | debugMsg(2, "env var %s => %s", dbgStr(var), dbgStrList(val));
|
| | | addStrList(val, tok, ret, pending, joined);
|
| | | break; }
|
| | | case TokFuncName: {
|
| | | const ProKey &func = getHashStr(tokPtr);
|
| | | debugMsg(2, "function %s", dbgKey(func));
|
| | | addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined);
|
| | | break; }
|
| | | default:
|
| | | debugMsg(2, "evaluated expression => %s", dbgStrList(*ret));
|
| | | tokPtr--;
|
| | | return;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::skipExpression(const ushort *&pTokPtr)
|
| | | {
|
| | | const ushort *tokPtr = pTokPtr;
|
| | | forever {
|
| | | ushort tok = *tokPtr++;
|
| | | switch (tok) {
|
| | | case TokLine:
|
| | | m_current.line = *tokPtr++;
|
| | | break;
|
| | | case TokValueTerminator:
|
| | | case TokFuncTerminator:
|
| | | pTokPtr = tokPtr;
|
| | | return;
|
| | | case TokArgSeparator:
|
| | | break;
|
| | | default:
|
| | | switch (tok & TokMask) {
|
| | | case TokLiteral:
|
| | | case TokEnvVar:
|
| | | skipStr(tokPtr);
|
| | | break;
|
| | | case TokHashLiteral:
|
| | | case TokVariable:
|
| | | case TokProperty:
|
| | | skipHashStr(tokPtr);
|
| | | break;
|
| | | case TokFuncName:
|
| | | skipHashStr(tokPtr);
|
| | | pTokPtr = tokPtr;
|
| | | skipExpression(pTokPtr);
|
| | | tokPtr = pTokPtr;
|
| | | break;
|
| | | default:
|
| | | Q_ASSERT_X(false, "skipExpression", "Unrecognized token");
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
|
| | | ProFile *pro, const ushort *tokPtr)
|
| | | {
|
| | | m_current.pro = pro;
|
| | | m_current.line = 0;
|
| | | return visitProBlock(tokPtr);
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
|
| | | const ushort *tokPtr)
|
| | | {
|
| | | traceMsg("entering block");
|
| | | ProStringList curr;
|
| | | bool okey = true, or_op = false, invert = false;
|
| | | uint blockLen;
|
| | | while (ushort tok = *tokPtr++) {
|
| | | VisitReturn ret;
|
| | | switch (tok) {
|
| | | case TokLine:
|
| | | m_current.line = *tokPtr++;
|
| | | continue;
|
| | | case TokAssign:
|
| | | case TokAppend:
|
| | | case TokAppendUnique:
|
| | | case TokRemove:
|
| | | case TokReplace:
|
| | | visitProVariable(tok, curr, tokPtr);
|
| | | curr.clear();
|
| | | continue;
|
| | | case TokBranch:
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | if (m_cumulative) {
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | if (!okey)
|
| | | m_skipLevel++;
|
| | | ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue;
|
| | | tokPtr += blockLen;
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | if (!okey)
|
| | | m_skipLevel--;
|
| | | else
|
| | | m_skipLevel++;
|
| | | if ((ret == ReturnTrue || ret == ReturnFalse) && blockLen)
|
| | | ret = visitProBlock(tokPtr);
|
| | | if (okey)
|
| | | m_skipLevel--;
|
| | | #endif
|
| | | } else {
|
| | | if (okey) {
|
| | | traceMsg("taking 'then' branch");
|
| | | ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue;
|
| | | traceMsg("finished 'then' branch");
|
| | | }
|
| | | tokPtr += blockLen;
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | if (!okey) {
|
| | | traceMsg("taking 'else' branch");
|
| | | ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue;
|
| | | traceMsg("finished 'else' branch");
|
| | | }
|
| | | }
|
| | | tokPtr += blockLen;
|
| | | okey = true, or_op = false; // force next evaluation
|
| | | break;
|
| | | case TokForLoop:
|
| | | if (m_cumulative) { // This is a no-win situation, so just pretend it's no loop
|
| | | skipHashStr(tokPtr);
|
| | | uint exprLen = getBlockLen(tokPtr);
|
| | | tokPtr += exprLen;
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | ret = visitProBlock(tokPtr);
|
| | | } else if (okey != or_op) {
|
| | | const ProKey &variable = getHashStr(tokPtr);
|
| | | uint exprLen = getBlockLen(tokPtr);
|
| | | const ushort *exprPtr = tokPtr;
|
| | | tokPtr += exprLen;
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | ret = visitProLoop(variable, exprPtr, tokPtr);
|
| | | } else {
|
| | | skipHashStr(tokPtr);
|
| | | uint exprLen = getBlockLen(tokPtr);
|
| | | tokPtr += exprLen;
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | traceMsg("skipped loop");
|
| | | ret = ReturnTrue;
|
| | | }
|
| | | tokPtr += blockLen;
|
| | | okey = true, or_op = false; // force next evaluation
|
| | | break;
|
| | | case TokTestDef:
|
| | | case TokReplaceDef:
|
| | | if (m_cumulative || okey != or_op) {
|
| | | const ProKey &name = getHashStr(tokPtr);
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | visitProFunctionDef(tok, name, tokPtr);
|
| | | traceMsg("defined %s function %s",
|
| | | tok == TokTestDef ? "test" : "replace", dbgKey(name));
|
| | | } else {
|
| | | traceMsg("skipped function definition");
|
| | | skipHashStr(tokPtr);
|
| | | blockLen = getBlockLen(tokPtr);
|
| | | }
|
| | | tokPtr += blockLen;
|
| | | okey = true, or_op = false; // force next evaluation
|
| | | continue;
|
| | | case TokNot:
|
| | | traceMsg("NOT");
|
| | | invert ^= true;
|
| | | continue;
|
| | | case TokAnd:
|
| | | traceMsg("AND");
|
| | | or_op = false;
|
| | | continue;
|
| | | case TokOr:
|
| | | traceMsg("OR");
|
| | | or_op = true;
|
| | | continue;
|
| | | case TokCondition:
|
| | | if (!m_skipLevel && okey != or_op) {
|
| | | if (curr.size() != 1) {
|
| | | if (!m_cumulative || !curr.isEmpty())
|
| | | evalError(fL1S("Conditional must expand to exactly one word."));
|
| | | okey = false;
|
| | | } else {
|
| | | okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true);
|
| | | traceMsg("condition %s is %s", dbgStr(curr.at(0)), dbgBool(okey));
|
| | | okey ^= invert;
|
| | | }
|
| | | } else {
|
| | | traceMsg("skipped condition %s", curr.size() == 1 ? dbgStr(curr.at(0)) : "<invalid>");
|
| | | }
|
| | | or_op = !okey; // tentatively force next evaluation
|
| | | invert = false;
|
| | | curr.clear();
|
| | | continue;
|
| | | case TokTestCall:
|
| | | if (!m_skipLevel && okey != or_op) {
|
| | | if (curr.size() != 1) {
|
| | | if (!m_cumulative || !curr.isEmpty())
|
| | | evalError(fL1S("Test name must expand to exactly one word."));
|
| | | skipExpression(tokPtr);
|
| | | okey = false;
|
| | | } else {
|
| | | traceMsg("evaluating test function %s", dbgStr(curr.at(0)));
|
| | | ret = evaluateConditionalFunction(curr.at(0).toKey(), tokPtr);
|
| | | switch (ret) {
|
| | | case ReturnTrue: okey = true; break;
|
| | | case ReturnFalse: okey = false; break;
|
| | | default:
|
| | | traceMsg("aborting block, function status: %s", dbgReturn(ret));
|
| | | return ret;
|
| | | }
|
| | | traceMsg("test function returned %s", dbgBool(okey));
|
| | | okey ^= invert;
|
| | | }
|
| | | } else if (m_cumulative) {
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | m_skipLevel++;
|
| | | if (curr.size() != 1)
|
| | | skipExpression(tokPtr);
|
| | | else
|
| | | evaluateConditionalFunction(curr.at(0).toKey(), tokPtr);
|
| | | m_skipLevel--;
|
| | | #endif
|
| | | } else {
|
| | | skipExpression(tokPtr);
|
| | | traceMsg("skipped test function %s", curr.size() == 1 ? dbgStr(curr.at(0)) : "<invalid>");
|
| | | }
|
| | | or_op = !okey; // tentatively force next evaluation
|
| | | invert = false;
|
| | | curr.clear();
|
| | | continue;
|
| | | case TokReturn:
|
| | | m_returnValue = curr;
|
| | | curr.clear();
|
| | | ret = ReturnReturn;
|
| | | goto ctrlstm;
|
| | | case TokBreak:
|
| | | ret = ReturnBreak;
|
| | | goto ctrlstm;
|
| | | case TokNext:
|
| | | ret = ReturnNext;
|
| | | ctrlstm:
|
| | | if (!m_skipLevel && okey != or_op) {
|
| | | traceMsg("flow control statement '%s', aborting block", dbgReturn(ret));
|
| | | return ret;
|
| | | }
|
| | | traceMsg("skipped flow control statement '%s'", dbgReturn(ret));
|
| | | okey = false, or_op = true; // force next evaluation
|
| | | continue;
|
| | | default: {
|
| | | const ushort *oTokPtr = --tokPtr;
|
| | | evaluateExpression(tokPtr, &curr, false);
|
| | | if (tokPtr != oTokPtr)
|
| | | continue;
|
| | | }
|
| | | Q_ASSERT_X(false, "visitProBlock", "unexpected item type");
|
| | | continue;
|
| | | }
|
| | | if (ret != ReturnTrue && ret != ReturnFalse) {
|
| | | traceMsg("aborting block, status: %s", dbgReturn(ret));
|
| | | return ret;
|
| | | }
|
| | | }
|
| | | traceMsg("leaving block, okey=%s", dbgBool(okey));
|
| | | return returnBool(okey);
|
| | | }
|
| | |
|
| | |
|
| | | void QMakeEvaluator::visitProFunctionDef(
|
| | | ushort tok, const ProKey &name, const ushort *tokPtr)
|
| | | {
|
| | | QHash<ProKey, ProFunctionDef> *hash =
|
| | | (tok == TokTestDef
|
| | | ? &m_functionDefs.testFunctions
|
| | | : &m_functionDefs.replaceFunctions);
|
| | | hash->insert(name, ProFunctionDef(m_current.pro, tokPtr - m_current.pro->tokPtr()));
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
|
| | | const ProKey &_variable, const ushort *exprPtr, const ushort *tokPtr)
|
| | | {
|
| | | VisitReturn ret = ReturnTrue;
|
| | | bool infinite = false;
|
| | | int index = 0;
|
| | | ProKey variable;
|
| | | ProStringList oldVarVal;
|
| | | ProString it_list = expandVariableReferences(exprPtr, 0, true).at(0);
|
| | | if (_variable.isEmpty()) {
|
| | | if (it_list != statics.strever) {
|
| | | evalError(fL1S("Invalid loop expression."));
|
| | | return ReturnFalse;
|
| | | }
|
| | | it_list = ProString(statics.strforever);
|
| | | } else {
|
| | | variable = map(_variable);
|
| | | oldVarVal = values(variable);
|
| | | }
|
| | | ProStringList list = values(it_list.toKey());
|
| | | if (list.isEmpty()) {
|
| | | if (it_list == statics.strforever) {
|
| | | infinite = true;
|
| | | } else {
|
| | | const QString &itl = it_list.toQString(m_tmp1);
|
| | | int dotdot = itl.indexOf(statics.strDotDot);
|
| | | if (dotdot != -1) {
|
| | | bool ok;
|
| | | int start = itl.left(dotdot).toInt(&ok);
|
| | | if (ok) {
|
| | | int end = itl.mid(dotdot+2).toInt(&ok);
|
| | | if (ok) {
|
| | | if (start < end) {
|
| | | for (int i = start; i <= end; i++)
|
| | | list << ProString(QString::number(i));
|
| | | } else {
|
| | | for (int i = start; i >= end; i--)
|
| | | list << ProString(QString::number(i));
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | if (infinite)
|
| | | traceMsg("entering infinite loop for %s", dbgKey(variable));
|
| | | else
|
| | | traceMsg("entering loop for %s over %s", dbgKey(variable), dbgStrList(list));
|
| | |
|
| | | forever {
|
| | | if (infinite) {
|
| | | if (!variable.isEmpty())
|
| | | m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index++)));
|
| | | if (index > 1000) {
|
| | | evalError(fL1S("Ran into infinite loop (> 1000 iterations)."));
|
| | | break;
|
| | | }
|
| | | traceMsg("loop iteration %d", index);
|
| | | } else {
|
| | | ProString val;
|
| | | do {
|
| | | if (index >= list.count())
|
| | | goto do_break;
|
| | | val = list.at(index++);
|
| | | } while (val.isEmpty()); // stupid, but qmake is like that
|
| | | traceMsg("loop iteration %s", dbgStr(val));
|
| | | m_valuemapStack.top()[variable] = ProStringList(val);
|
| | | }
|
| | |
|
| | | ret = visitProBlock(tokPtr);
|
| | | switch (ret) {
|
| | | case ReturnTrue:
|
| | | case ReturnFalse:
|
| | | break;
|
| | | case ReturnNext:
|
| | | ret = ReturnTrue;
|
| | | break;
|
| | | case ReturnBreak:
|
| | | ret = ReturnTrue;
|
| | | goto do_break;
|
| | | default:
|
| | | goto do_break;
|
| | | }
|
| | | }
|
| | | do_break:
|
| | |
|
| | | traceMsg("done looping");
|
| | |
|
| | | if (!variable.isEmpty())
|
| | | m_valuemapStack.top()[variable] = oldVarVal;
|
| | | return ret;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::visitProVariable(
|
| | | ushort tok, const ProStringList &curr, const ushort *&tokPtr)
|
| | | {
|
| | | int sizeHint = *tokPtr++;
|
| | |
|
| | | if (curr.size() != 1) {
|
| | | skipExpression(tokPtr);
|
| | | if (!m_cumulative || !curr.isEmpty())
|
| | | evalError(fL1S("Left hand side of assignment must expand to exactly one word."));
|
| | | return;
|
| | | }
|
| | | const ProKey &varName = map(curr.first());
|
| | |
|
| | | if (tok == TokReplace) { // ~=
|
| | | // DEFINES ~= s/a/b/?[gqi]
|
| | |
|
| | | const ProStringList &varVal = expandVariableReferences(tokPtr, sizeHint, true);
|
| | | const QString &val = varVal.at(0).toQString(m_tmp1);
|
| | | if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
|
| | | evalError(fL1S("The ~= operator can handle only the s/// function."));
|
| | | return;
|
| | | }
|
| | | QChar sep = val.at(1);
|
| | | QStringList func = val.split(sep);
|
| | | if (func.count() < 3 || func.count() > 4) {
|
| | | evalError(fL1S("The s/// function expects 3 or 4 arguments."));
|
| | | return;
|
| | | }
|
| | |
|
| | | bool global = false, quote = false, case_sense = false;
|
| | | if (func.count() == 4) {
|
| | | global = func[3].indexOf(QLatin1Char('g')) != -1;
|
| | | case_sense = func[3].indexOf(QLatin1Char('i')) == -1;
|
| | | quote = func[3].indexOf(QLatin1Char('q')) != -1;
|
| | | }
|
| | | QString pattern = func[1];
|
| | | QString replace = func[2];
|
| | | if (quote)
|
| | | pattern = QRegExp::escape(pattern);
|
| | |
|
| | | QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
| | |
|
| | | // We could make a union of modified and unmodified values,
|
| | | // but this will break just as much as it fixes, so leave it as is.
|
| | | replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2);
|
| | | debugMsg(2, "replaced %s with %s", dbgQStr(pattern), dbgQStr(replace));
|
| | | } else {
|
| | | ProStringList varVal = expandVariableReferences(tokPtr, sizeHint);
|
| | | switch (tok) {
|
| | | default: // whatever - cannot happen
|
| | | case TokAssign: // =
|
| | | zipEmpty(&varVal);
|
| | | if (!m_cumulative) {
|
| | | // FIXME: add check+warning about accidental value removal.
|
| | | // This may be a bit too noisy, though.
|
| | | m_valuemapStack.top()[varName] = varVal;
|
| | | } else {
|
| | | if (!varVal.isEmpty()) {
|
| | | // We are greedy for values. But avoid exponential growth.
|
| | | ProStringList &v = valuesRef(varName);
|
| | | if (v.isEmpty()) {
|
| | | v = varVal;
|
| | | } else {
|
| | | ProStringList old = v;
|
| | | v = varVal;
|
| | | QSet<ProString> has;
|
| | | has.reserve(v.size());
|
| | | foreach (const ProString &s, v)
|
| | | has.insert(s);
|
| | | v.reserve(v.size() + old.size());
|
| | | foreach (const ProString &s, old)
|
| | | if (!has.contains(s))
|
| | | v << s;
|
| | | }
|
| | | }
|
| | | }
|
| | | debugMsg(2, "assigning");
|
| | | break;
|
| | | case TokAppendUnique: // *=
|
| | | insertUnique(&valuesRef(varName), varVal);
|
| | | debugMsg(2, "appending unique");
|
| | | break;
|
| | | case TokAppend: // +=
|
| | | zipEmpty(&varVal);
|
| | | valuesRef(varName) += varVal;
|
| | | debugMsg(2, "appending");
|
| | | break;
|
| | | case TokRemove: // -=
|
| | | if (!m_cumulative) {
|
| | | removeEach(&valuesRef(varName), varVal);
|
| | | } else {
|
| | | // We are stingy with our values, too.
|
| | | }
|
| | | debugMsg(2, "removing");
|
| | | break;
|
| | | }
|
| | | }
|
| | | traceMsg("%s := %s", dbgKey(varName), dbgStrList(values(varName)));
|
| | |
|
| | | if (varName == statics.strTEMPLATE)
|
| | | setTemplate();
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | else if (varName == statics.strREQUIRES)
|
| | | checkRequirements(values(varName));
|
| | | #endif
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::setTemplate()
|
| | | {
|
| | | ProStringList &values = valuesRef(statics.strTEMPLATE);
|
| | | if (!m_option->user_template.isEmpty()) {
|
| | | // Don't allow override
|
| | | values = ProStringList(ProString(m_option->user_template));
|
| | | } else {
|
| | | if (values.isEmpty())
|
| | | values.append(ProString("app"));
|
| | | else
|
| | | values.erase(values.begin() + 1, values.end());
|
| | | }
|
| | | if (!m_option->user_template_prefix.isEmpty()) {
|
| | | QString val = values.first().toQString(m_tmp1);
|
| | | if (!val.startsWith(m_option->user_template_prefix)) {
|
| | | val.prepend(m_option->user_template_prefix);
|
| | | values = ProStringList(ProString(val));
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::loadDefaults()
|
| | | {
|
| | | ProValueMap &vars = m_valuemapStack.top();
|
| | |
|
| | | vars[ProKey("DIR_SEPARATOR")] << ProString(m_option->dir_sep);
|
| | | vars[ProKey("DIRLIST_SEPARATOR")] << ProString(m_option->dirlist_sep);
|
| | | vars[ProKey("_DATE_")] << ProString(QDateTime::currentDateTime().toString());
|
| | | if (!m_option->qmake_abslocation.isEmpty())
|
| | | vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation);
|
| | | #if defined(Q_OS_WIN32)
|
| | | vars[ProKey("QMAKE_HOST.os")] << ProString("Windows");
|
| | |
|
| | | DWORD name_length = 1024;
|
| | | wchar_t name[1024];
|
| | | if (GetComputerName(name, &name_length))
|
| | | vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromWCharArray(name));
|
| | |
|
| | | QSysInfo::WinVersion ver = QSysInfo::WindowsVersion;
|
| | | vars[ProKey("QMAKE_HOST.version")] << ProString(QString::number(ver));
|
| | | ProString verStr;
|
| | | switch (ver) {
|
| | | case QSysInfo::WV_Me: verStr = ProString("WinMe"); break;
|
| | | case QSysInfo::WV_95: verStr = ProString("Win95"); break;
|
| | | case QSysInfo::WV_98: verStr = ProString("Win98"); break;
|
| | | case QSysInfo::WV_NT: verStr = ProString("WinNT"); break;
|
| | | case QSysInfo::WV_2000: verStr = ProString("Win2000"); break;
|
| | | case QSysInfo::WV_2003: verStr = ProString("Win2003"); break;
|
| | | case QSysInfo::WV_XP: verStr = ProString("WinXP"); break;
|
| | | case QSysInfo::WV_VISTA: verStr = ProString("WinVista"); break;
|
| | | default: verStr = ProString("Unknown"); break;
|
| | | }
|
| | | vars[ProKey("QMAKE_HOST.version_string")] << verStr;
|
| | |
|
| | | SYSTEM_INFO info;
|
| | | GetSystemInfo(&info);
|
| | | ProString archStr;
|
| | | switch (info.wProcessorArchitecture) {
|
| | | # ifdef PROCESSOR_ARCHITECTURE_AMD64
|
| | | case PROCESSOR_ARCHITECTURE_AMD64:
|
| | | archStr = ProString("x86_64");
|
| | | break;
|
| | | # endif
|
| | | case PROCESSOR_ARCHITECTURE_INTEL:
|
| | | archStr = ProString("x86");
|
| | | break;
|
| | | case PROCESSOR_ARCHITECTURE_IA64:
|
| | | # ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
|
| | | case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
| | | # endif
|
| | | archStr = ProString("IA64");
|
| | | break;
|
| | | default:
|
| | | archStr = ProString("Unknown");
|
| | | break;
|
| | | }
|
| | | vars[ProKey("QMAKE_HOST.arch")] << archStr;
|
| | |
|
| | | # if defined(Q_CC_MSVC) // ### bogus condition, but nobody x-builds for msvc with a different qmake
|
| | | QLatin1Char backslash('\\');
|
| | | QString paths = m_option->getEnv(QLatin1String("PATH"));
|
| | | QString vcBin64 = m_option->getEnv(QLatin1String("VCINSTALLDIR"));
|
| | | if (!vcBin64.endsWith(backslash))
|
| | | vcBin64.append(backslash);
|
| | | vcBin64.append(QLatin1String("bin\\amd64"));
|
| | | QString vcBinX86_64 = m_option->getEnv(QLatin1String("VCINSTALLDIR"));
|
| | | if (!vcBinX86_64.endsWith(backslash))
|
| | | vcBinX86_64.append(backslash);
|
| | | vcBinX86_64.append(QLatin1String("bin\\x86_amd64"));
|
| | | if (paths.contains(vcBin64, Qt::CaseInsensitive)
|
| | | || paths.contains(vcBinX86_64, Qt::CaseInsensitive))
|
| | | vars[ProKey("QMAKE_TARGET.arch")] << ProString("x86_64");
|
| | | else
|
| | | vars[ProKey("QMAKE_TARGET.arch")] << ProString("x86");
|
| | | # endif
|
| | | #elif defined(Q_OS_UNIX)
|
| | | struct utsname name;
|
| | | if (!uname(&name)) {
|
| | | vars[ProKey("QMAKE_HOST.os")] << ProString(name.sysname);
|
| | | vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromLocal8Bit(name.nodename));
|
| | | vars[ProKey("QMAKE_HOST.version")] << ProString(name.release);
|
| | | vars[ProKey("QMAKE_HOST.version_string")] << ProString(name.version);
|
| | | vars[ProKey("QMAKE_HOST.arch")] << ProString(name.machine);
|
| | | }
|
| | | #endif
|
| | |
|
| | | m_valuemapInited = true;
|
| | | }
|
| | |
|
| | | bool QMakeEvaluator::prepareProject(const QString &inDir)
|
| | | {
|
| | | QString superdir;
|
| | | if (m_option->do_cache) {
|
| | | QString conffile;
|
| | | QString cachefile = m_option->cachefile;
|
| | | if (cachefile.isEmpty()) { //find it as it has not been specified
|
| | | if (m_outputDir.isEmpty())
|
| | | goto no_cache;
|
| | | superdir = m_outputDir;
|
| | | forever {
|
| | | QString superfile = superdir + QLatin1String("/.qmake.super");
|
| | | if (IoUtils::exists(superfile)) {
|
| | | m_superfile = superfile;
|
| | | break;
|
| | | }
|
| | | QFileInfo qdfi(superdir);
|
| | | if (qdfi.isRoot()) {
|
| | | superdir.clear();
|
| | | break;
|
| | | }
|
| | | superdir = qdfi.path();
|
| | | }
|
| | | QString sdir = inDir;
|
| | | QString dir = m_outputDir;
|
| | | forever {
|
| | | conffile = sdir + QLatin1String("/.qmake.conf");
|
| | | if (!IoUtils::exists(conffile))
|
| | | conffile.clear();
|
| | | cachefile = dir + QLatin1String("/.qmake.cache");
|
| | | if (!IoUtils::exists(cachefile))
|
| | | cachefile.clear();
|
| | | if (!conffile.isEmpty() || !cachefile.isEmpty()) {
|
| | | if (dir != sdir)
|
| | | m_sourceRoot = sdir;
|
| | | m_buildRoot = dir;
|
| | | break;
|
| | | }
|
| | | if (dir == superdir)
|
| | | goto no_cache;
|
| | | QFileInfo qsdfi(sdir);
|
| | | QFileInfo qdfi(dir);
|
| | | if (qsdfi.isRoot() || qdfi.isRoot())
|
| | | goto no_cache;
|
| | | sdir = qsdfi.path();
|
| | | dir = qdfi.path();
|
| | | }
|
| | | } else {
|
| | | m_buildRoot = QFileInfo(cachefile).path();
|
| | | }
|
| | | m_conffile = conffile;
|
| | | m_cachefile = cachefile;
|
| | | }
|
| | | no_cache:
|
| | |
|
| | | // Look for mkspecs/ in source and build. First to win determines the root.
|
| | | QString sdir = inDir;
|
| | | QString dir = m_outputDir;
|
| | | while (dir != m_buildRoot) {
|
| | | if ((dir != sdir && QFileInfo(sdir, QLatin1String("mkspecs")).isDir())
|
| | | || QFileInfo(dir, QLatin1String("mkspecs")).isDir()) {
|
| | | if (dir != sdir)
|
| | | m_sourceRoot = sdir;
|
| | | m_buildRoot = dir;
|
| | | break;
|
| | | }
|
| | | if (dir == superdir)
|
| | | break;
|
| | | QFileInfo qsdfi(sdir);
|
| | | QFileInfo qdfi(dir);
|
| | | if (qsdfi.isRoot() || qdfi.isRoot())
|
| | | break;
|
| | | sdir = qsdfi.path();
|
| | | dir = qdfi.path();
|
| | | }
|
| | |
|
| | | return true;
|
| | | }
|
| | |
|
| | | bool QMakeEvaluator::loadSpecInternal()
|
| | | {
|
| | | if (evaluateFeatureFile(QLatin1String("spec_pre.prf")) != ReturnTrue)
|
| | | return false;
|
| | | QString spec = m_qmakespec + QLatin1String("/qmake.conf");
|
| | | if (evaluateFile(spec, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
|
| | | evalError(fL1S("Could not read qmake configuration file %1.").arg(spec));
|
| | | return false;
|
| | | }
|
| | | #ifndef QT_BUILD_QMAKE
|
| | | // Legacy support for Qt4 default specs
|
| | | # ifdef Q_OS_UNIX
|
| | | if (m_qmakespec.endsWith(QLatin1String("/default-host"))
|
| | | || m_qmakespec.endsWith(QLatin1String("/default"))) {
|
| | | QString rspec = QFileInfo(m_qmakespec).readLink();
|
| | | if (!rspec.isEmpty())
|
| | | m_qmakespec = QDir::cleanPath(QDir(m_qmakespec).absoluteFilePath(rspec));
|
| | | }
|
| | | # else
|
| | | // We can't resolve symlinks as they do on Unix, so configure.exe puts
|
| | | // the source of the qmake.conf at the end of the default/qmake.conf in
|
| | | // the QMAKESPEC_ORIGINAL variable.
|
| | | const ProString &orig_spec = first(ProKey("QMAKESPEC_ORIGINAL"));
|
| | | if (!orig_spec.isEmpty())
|
| | | m_qmakespec = orig_spec.toQString();
|
| | | # endif
|
| | | #endif
|
| | | valuesRef(ProKey("QMAKESPEC")) << ProString(m_qmakespec);
|
| | | m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
|
| | | if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue)
|
| | | return false;
|
| | | // The MinGW and x-build specs may change the separator; $$shell_{path,quote}() need it
|
| | | m_dirSep = first(ProKey("QMAKE_DIR_SEP"));
|
| | | return true;
|
| | | }
|
| | |
|
| | | bool QMakeEvaluator::loadSpec()
|
| | | {
|
| | | QString qmakespec = m_option->expandEnvVars(
|
| | | m_hostBuild ? m_option->qmakespec : m_option->xqmakespec);
|
| | |
|
| | | {
|
| | | QMakeEvaluator evaluator(m_option, m_parser, m_handler);
|
| | | if (!m_superfile.isEmpty()) {
|
| | | valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
|
| | | if (evaluator.evaluateFile(
|
| | | m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
| | | return false;
|
| | | }
|
| | | if (!m_conffile.isEmpty()) {
|
| | | valuesRef(ProKey("_QMAKE_CONF_")) << ProString(m_conffile);
|
| | | if (evaluator.evaluateFile(
|
| | | m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
| | | return false;
|
| | | }
|
| | | if (!m_cachefile.isEmpty()) {
|
| | | valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
|
| | | if (evaluator.evaluateFile(
|
| | | m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
| | | return false;
|
| | | }
|
| | | if (qmakespec.isEmpty()) {
|
| | | if (!m_hostBuild)
|
| | | qmakespec = evaluator.first(ProKey("XQMAKESPEC")).toQString();
|
| | | if (qmakespec.isEmpty())
|
| | | qmakespec = evaluator.first(ProKey("QMAKESPEC")).toQString();
|
| | | }
|
| | | m_qmakepath = evaluator.values(ProKey("QMAKEPATH")).toQStringList();
|
| | | m_qmakefeatures = evaluator.values(ProKey("QMAKEFEATURES")).toQStringList();
|
| | | }
|
| | |
|
| | | updateMkspecPaths();
|
| | | if (qmakespec.isEmpty())
|
| | | qmakespec = propertyValue(ProKey(m_hostBuild ? "QMAKE_SPEC" : "QMAKE_XSPEC")).toQString();
|
| | | #ifndef QT_BUILD_QMAKE
|
| | | // Legacy support for Qt4 qmake in Qt Creator, etc.
|
| | | if (qmakespec.isEmpty())
|
| | | qmakespec = m_hostBuild ? QLatin1String("default-host") : QLatin1String("default");
|
| | | #endif
|
| | | if (IoUtils::isRelativePath(qmakespec)) {
|
| | | foreach (const QString &root, m_mkspecPaths) {
|
| | | QString mkspec = root + QLatin1Char('/') + qmakespec;
|
| | | if (IoUtils::exists(mkspec)) {
|
| | | qmakespec = mkspec;
|
| | | goto cool;
|
| | | }
|
| | | }
|
| | | evalError(fL1S("Could not find qmake configuration file %1.").arg(qmakespec));
|
| | | return false;
|
| | | }
|
| | | cool:
|
| | | m_qmakespec = QDir::cleanPath(qmakespec);
|
| | |
|
| | | if (!m_superfile.isEmpty()
|
| | | && evaluateFile(m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
|
| | | return false;
|
| | | }
|
| | | if (!loadSpecInternal())
|
| | | return false;
|
| | | updateFeaturePaths(); // The spec extends the feature search path, so rebuild the cache.
|
| | | if (!m_conffile.isEmpty()
|
| | | && evaluateFile(m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
|
| | | return false;
|
| | | }
|
| | | if (!m_cachefile.isEmpty()
|
| | | && evaluateFile(m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
|
| | | return false;
|
| | | }
|
| | | return true;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::setupProject()
|
| | | {
|
| | | setTemplate();
|
| | | ProValueMap &vars = m_valuemapStack.top();
|
| | | vars[ProKey("TARGET")] << ProString(QFileInfo(currentFileName()).baseName());
|
| | | vars[ProKey("_PRO_FILE_")] << ProString(currentFileName());
|
| | | vars[ProKey("_PRO_FILE_PWD_")] << ProString(currentDirectory());
|
| | | vars[ProKey("OUT_PWD")] << ProString(m_outputDir);
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
|
| | | {
|
| | | if (!cmds.isEmpty()) {
|
| | | if (ProFile *pro = m_parser->parsedProBlock(cmds, where, -1)) {
|
| | | if (pro->isOk()) {
|
| | | m_locationStack.push(m_current);
|
| | | visitProBlock(pro, pro->tokPtr());
|
| | | m_current = m_locationStack.pop();
|
| | | }
|
| | | pro->deref();
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures()
|
| | | {
|
| | | QSet<QString> processed;
|
| | | forever {
|
| | | bool finished = true;
|
| | | ProStringList configs = values(statics.strCONFIG);
|
| | | for (int i = configs.size() - 1; i >= 0; --i) {
|
| | | QString config = configs.at(i).toQString(m_tmp1).toLower();
|
| | | if (!processed.contains(config)) {
|
| | | config.detach();
|
| | | processed.insert(config);
|
| | | VisitReturn vr = evaluateFeatureFile(config, true);
|
| | | if (vr == ReturnError)
|
| | | return vr;
|
| | | if (vr == ReturnTrue) {
|
| | | finished = false;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | if (finished)
|
| | | break;
|
| | | }
|
| | | return ReturnTrue;
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
|
| | | ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags)
|
| | | {
|
| | | if (!m_cumulative && !pro->isOk())
|
| | | return ReturnFalse;
|
| | |
|
| | | if (flags & LoadPreFiles) {
|
| | | if (!prepareProject(pro->directoryName()))
|
| | | return ReturnFalse;
|
| | |
|
| | | m_hostBuild = pro->isHostBuild();
|
| | |
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | m_option->mutex.lock();
|
| | | #endif
|
| | | QMakeBaseEnv **baseEnvPtr = &m_option->baseEnvs[QMakeBaseKey(m_buildRoot, m_hostBuild)];
|
| | | if (!*baseEnvPtr)
|
| | | *baseEnvPtr = new QMakeBaseEnv;
|
| | | QMakeBaseEnv *baseEnv = *baseEnvPtr;
|
| | |
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | {
|
| | | QMutexLocker locker(&baseEnv->mutex);
|
| | | m_option->mutex.unlock();
|
| | | if (baseEnv->inProgress) {
|
| | | QThreadPool::globalInstance()->releaseThread();
|
| | | baseEnv->cond.wait(&baseEnv->mutex);
|
| | | QThreadPool::globalInstance()->reserveThread();
|
| | | if (!baseEnv->isOk)
|
| | | return ReturnFalse;
|
| | | } else
|
| | | #endif
|
| | | if (!baseEnv->evaluator) {
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | baseEnv->inProgress = true;
|
| | | locker.unlock();
|
| | | #endif
|
| | |
|
| | | QMakeEvaluator *baseEval = new QMakeEvaluator(m_option, m_parser, m_handler);
|
| | | baseEnv->evaluator = baseEval;
|
| | | baseEval->m_superfile = m_superfile;
|
| | | baseEval->m_conffile = m_conffile;
|
| | | baseEval->m_cachefile = m_cachefile;
|
| | | baseEval->m_sourceRoot = m_sourceRoot;
|
| | | baseEval->m_buildRoot = m_buildRoot;
|
| | | baseEval->m_hostBuild = m_hostBuild;
|
| | | bool ok = baseEval->loadSpec();
|
| | |
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | locker.relock();
|
| | | baseEnv->isOk = ok;
|
| | | baseEnv->inProgress = false;
|
| | | baseEnv->cond.wakeAll();
|
| | | #endif
|
| | |
|
| | | if (!ok)
|
| | | return ReturnFalse;
|
| | | }
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | }
|
| | | #endif
|
| | |
|
| | | initFrom(*baseEnv->evaluator);
|
| | | } else {
|
| | | if (!m_valuemapInited)
|
| | | loadDefaults();
|
| | | }
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
|
| | | it != m_extraVars.constEnd(); ++it)
|
| | | m_valuemapStack.first().insert(it.key(), it.value());
|
| | | #endif
|
| | |
|
| | | VisitReturn vr;
|
| | |
|
| | | m_handler->aboutToEval(currentProFile(), pro, type);
|
| | | m_profileStack.push(pro);
|
| | | valuesRef(ProKey("PWD")) = ProStringList(ProString(currentDirectory()));
|
| | | if (flags & LoadPreFiles) {
|
| | | setupProject();
|
| | |
|
| | | if ((vr = evaluateFeatureFile(QLatin1String("default_pre.prf"))) == ReturnError)
|
| | | goto failed;
|
| | |
|
| | | evaluateCommand(m_option->precmds, fL1S("(command line)"));
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | // After user configs, to override them
|
| | | if (!m_extraConfigs.isEmpty())
|
| | | evaluateCommand("CONFIG += " + m_extraConfigs.join(' '), fL1S("(extra configs)"));
|
| | | #endif
|
| | | }
|
| | |
|
| | | debugMsg(1, "visiting file %s", qPrintable(pro->fileName()));
|
| | | if ((vr = visitProBlock(pro, pro->tokPtr())) == ReturnError)
|
| | | goto failed;
|
| | | debugMsg(1, "done visiting file %s", qPrintable(pro->fileName()));
|
| | |
|
| | | if (flags & LoadPostFiles) {
|
| | | evaluateCommand(m_option->postcmds, fL1S("(command line -after)"));
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | // Again, to ensure the project does not mess with us.
|
| | | // Specifically, do not allow a project to override debug/release within a
|
| | | // debug_and_release build pass - it's too late for that at this point anyway.
|
| | | if (!m_extraConfigs.isEmpty())
|
| | | evaluateCommand("CONFIG += " + m_extraConfigs.join(' '), fL1S("(extra configs)"));
|
| | | #endif
|
| | |
|
| | | if ((vr = evaluateFeatureFile(QLatin1String("default_post.prf"))) == ReturnError)
|
| | | goto failed;
|
| | |
|
| | | if ((vr = evaluateConfigFeatures()) == ReturnError)
|
| | | goto failed;
|
| | | }
|
| | | vr = ReturnTrue;
|
| | | failed:
|
| | | m_profileStack.pop();
|
| | | valuesRef(ProKey("PWD")) = ProStringList(ProString(currentDirectory()));
|
| | | m_handler->doneWithEval(currentProFile());
|
| | |
|
| | | return vr;
|
| | | }
|
| | |
|
| | |
|
| | | void QMakeEvaluator::updateMkspecPaths()
|
| | | {
|
| | | QStringList ret;
|
| | | const QString concat = QLatin1String("/mkspecs");
|
| | |
|
| | | foreach (const QString &it, m_option->getPathListEnv(QLatin1String("QMAKEPATH")))
|
| | | ret << it + concat;
|
| | |
|
| | | foreach (const QString &it, m_qmakepath)
|
| | | ret << it + concat;
|
| | |
|
| | | if (!m_buildRoot.isEmpty())
|
| | | ret << m_buildRoot + concat;
|
| | | if (!m_sourceRoot.isEmpty())
|
| | | ret << m_sourceRoot + concat;
|
| | |
|
| | | ret << m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + concat;
|
| | |
|
| | | ret.removeDuplicates();
|
| | | m_mkspecPaths = ret;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::updateFeaturePaths()
|
| | | {
|
| | | QString mkspecs_concat = QLatin1String("/mkspecs");
|
| | | QString features_concat = QLatin1String("/features/");
|
| | |
|
| | | QStringList feature_roots;
|
| | |
|
| | | foreach (const QString &f, m_option->getPathListEnv(QLatin1String("QMAKEFEATURES")))
|
| | | feature_roots += f;
|
| | |
|
| | | feature_roots += m_qmakefeatures;
|
| | |
|
| | | feature_roots += m_option->propertyValue(ProKey("QMAKEFEATURES")).toQString(m_mtmp).split(
|
| | | m_option->dirlist_sep, QString::SkipEmptyParts);
|
| | |
|
| | | QStringList feature_bases;
|
| | | if (!m_buildRoot.isEmpty())
|
| | | feature_bases << m_buildRoot;
|
| | | if (!m_sourceRoot.isEmpty())
|
| | | feature_bases << m_sourceRoot;
|
| | |
|
| | | foreach (const QString &item, m_option->getPathListEnv(QLatin1String("QMAKEPATH")))
|
| | | feature_bases << (item + mkspecs_concat);
|
| | |
|
| | | foreach (const QString &item, m_qmakepath)
|
| | | feature_bases << (item + mkspecs_concat);
|
| | |
|
| | | if (!m_qmakespec.isEmpty()) {
|
| | | // The spec is already platform-dependent, so no subdirs here.
|
| | | feature_roots << (m_qmakespec + features_concat);
|
| | |
|
| | | // Also check directly under the root directory of the mkspecs collection
|
| | | QDir specdir(m_qmakespec);
|
| | | while (!specdir.isRoot() && specdir.cdUp()) {
|
| | | const QString specpath = specdir.path();
|
| | | if (specpath.endsWith(mkspecs_concat)) {
|
| | | if (IoUtils::exists(specpath + features_concat))
|
| | | feature_bases << specpath;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")).toQString(m_mtmp)
|
| | | + mkspecs_concat);
|
| | |
|
| | | foreach (const QString &fb, feature_bases) {
|
| | | foreach (const ProString &sfx, values(ProKey("QMAKE_PLATFORM")))
|
| | | feature_roots << (fb + features_concat + sfx + QLatin1Char('/'));
|
| | | feature_roots << (fb + features_concat);
|
| | | }
|
| | |
|
| | | for (int i = 0; i < feature_roots.count(); ++i)
|
| | | if (!feature_roots.at(i).endsWith((ushort)'/'))
|
| | | feature_roots[i].append((ushort)'/');
|
| | |
|
| | | feature_roots.removeDuplicates();
|
| | |
|
| | | QStringList ret;
|
| | | foreach (const QString &root, feature_roots)
|
| | | if (IoUtils::exists(root))
|
| | | ret << root;
|
| | | m_featureRoots = ret;
|
| | | }
|
| | |
|
| | | ProString QMakeEvaluator::propertyValue(const ProKey &name) const
|
| | | {
|
| | | if (name == QLatin1String("QMAKE_MKSPECS"))
|
| | | return ProString(m_mkspecPaths.join(m_option->dirlist_sep));
|
| | | ProString ret = m_option->propertyValue(name);
|
| | | // if (ret.isNull())
|
| | | // evalError(fL1S("Querying unknown property %1").arg(name.toQString(m_mtmp)));
|
| | | return ret;
|
| | | }
|
| | |
|
| | | ProFile *QMakeEvaluator::currentProFile() const
|
| | | {
|
| | | if (m_profileStack.count() > 0)
|
| | | return m_profileStack.top();
|
| | | return 0;
|
| | | }
|
| | |
|
| | | QString QMakeEvaluator::currentFileName() const
|
| | | {
|
| | | ProFile *pro = currentProFile();
|
| | | if (pro)
|
| | | return pro->fileName();
|
| | | return QString();
|
| | | }
|
| | |
|
| | | QString QMakeEvaluator::currentDirectory() const
|
| | | {
|
| | | ProFile *pro = currentProFile();
|
| | | if (pro)
|
| | | return pro->directoryName();
|
| | | return QString();
|
| | | }
|
| | |
|
| | | bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex)
|
| | | {
|
| | | // magic types for easy flipping
|
| | | if (config == statics.strtrue)
|
| | | return true;
|
| | | if (config == statics.strfalse)
|
| | | return false;
|
| | |
|
| | | if (config == statics.strhost_build)
|
| | | return m_hostBuild;
|
| | |
|
| | | if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) {
|
| | | QString cfg = config;
|
| | | cfg.detach(); // Keep m_tmp out of QRegExp's cache
|
| | | QRegExp re(cfg, Qt::CaseSensitive, QRegExp::Wildcard);
|
| | |
|
| | | // mkspecs
|
| | | if (re.exactMatch(m_qmakespecName))
|
| | | return true;
|
| | |
|
| | | // CONFIG variable
|
| | | int t = 0;
|
| | | foreach (const ProString &configValue, values(statics.strCONFIG)) {
|
| | | if (re.exactMatch(configValue.toQString(m_tmp[t])))
|
| | | return true;
|
| | | t ^= 1;
|
| | | }
|
| | | } else {
|
| | | // mkspecs
|
| | | if (m_qmakespecName == config)
|
| | | return true;
|
| | |
|
| | | // CONFIG variable
|
| | | if (values(statics.strCONFIG).contains(ProString(config)))
|
| | | return true;
|
| | | }
|
| | |
|
| | | return false;
|
| | | }
|
| | |
|
| | | ProStringList QMakeEvaluator::expandVariableReferences(
|
| | | const ushort *&tokPtr, int sizeHint, bool joined)
|
| | | {
|
| | | ProStringList ret;
|
| | | ret.reserve(sizeHint);
|
| | | forever {
|
| | | evaluateExpression(tokPtr, &ret, joined);
|
| | | switch (*tokPtr) {
|
| | | case TokValueTerminator:
|
| | | case TokFuncTerminator:
|
| | | tokPtr++;
|
| | | return ret;
|
| | | case TokArgSeparator:
|
| | | if (joined) {
|
| | | tokPtr++;
|
| | | continue;
|
| | | }
|
| | | // fallthrough
|
| | | default:
|
| | | Q_ASSERT_X(false, "expandVariableReferences", "Unrecognized token");
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | QList<ProStringList> QMakeEvaluator::prepareFunctionArgs(const ushort *&tokPtr)
|
| | | {
|
| | | QList<ProStringList> args_list;
|
| | | if (*tokPtr != TokFuncTerminator) {
|
| | | for (;; tokPtr++) {
|
| | | ProStringList arg;
|
| | | evaluateExpression(tokPtr, &arg, false);
|
| | | args_list << arg;
|
| | | if (*tokPtr == TokFuncTerminator)
|
| | | break;
|
| | | Q_ASSERT(*tokPtr == TokArgSeparator);
|
| | | }
|
| | | }
|
| | | tokPtr++;
|
| | | return args_list;
|
| | | }
|
| | |
|
| | | ProStringList QMakeEvaluator::evaluateFunction(
|
| | | const ProFunctionDef &func, const QList<ProStringList> &argumentsList, VisitReturn *ok)
|
| | | {
|
| | | VisitReturn vr;
|
| | | ProStringList ret;
|
| | |
|
| | | if (m_valuemapStack.count() >= 100) {
|
| | | evalError(fL1S("Ran into infinite recursion (depth > 100)."));
|
| | | vr = ReturnFalse;
|
| | | } else {
|
| | | m_valuemapStack.push(ProValueMap());
|
| | | m_locationStack.push(m_current);
|
| | |
|
| | | ProStringList args;
|
| | | for (int i = 0; i < argumentsList.count(); ++i) {
|
| | | args += argumentsList[i];
|
| | | m_valuemapStack.top()[ProKey(QString::number(i+1))] = argumentsList[i];
|
| | | }
|
| | | m_valuemapStack.top()[statics.strARGS] = args;
|
| | | vr = visitProBlock(func.pro(), func.tokPtr());
|
| | | if (vr == ReturnReturn)
|
| | | vr = ReturnTrue;
|
| | | ret = m_returnValue;
|
| | | m_returnValue.clear();
|
| | |
|
| | | m_current = m_locationStack.pop();
|
| | | m_valuemapStack.pop();
|
| | | }
|
| | | if (ok)
|
| | | *ok = vr;
|
| | | if (vr == ReturnTrue)
|
| | | return ret;
|
| | | return ProStringList();
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction(
|
| | | const ProFunctionDef &func, const QList<ProStringList> &argumentsList,
|
| | | const ProString &function)
|
| | | {
|
| | | VisitReturn vr;
|
| | | ProStringList ret = evaluateFunction(func, argumentsList, &vr);
|
| | | if (vr == ReturnTrue) {
|
| | | if (ret.isEmpty())
|
| | | return ReturnTrue;
|
| | | if (ret.at(0) != statics.strfalse) {
|
| | | if (ret.at(0) == statics.strtrue)
|
| | | return ReturnTrue;
|
| | | bool ok;
|
| | | int val = ret.at(0).toQString(m_tmp1).toInt(&ok);
|
| | | if (ok) {
|
| | | if (val)
|
| | | return ReturnTrue;
|
| | | } else {
|
| | | evalError(fL1S("Unexpected return value from test '%1': %2.")
|
| | | .arg(function.toQString(m_tmp1))
|
| | | .arg(ret.join(QLatin1String(" :: "))));
|
| | | }
|
| | | }
|
| | | return ReturnFalse;
|
| | | }
|
| | | return vr;
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
|
| | | const ProKey &func, const ushort *&tokPtr)
|
| | | {
|
| | | if (int func_t = statics.functions.value(func)) {
|
| | | //why don't the builtin functions just use args_list? --Sam
|
| | | return evaluateBuiltinConditional(func_t, func, expandVariableReferences(tokPtr, 5, true));
|
| | | }
|
| | |
|
| | | QHash<ProKey, ProFunctionDef>::ConstIterator it =
|
| | | m_functionDefs.testFunctions.constFind(func);
|
| | | if (it != m_functionDefs.testFunctions.constEnd()) {
|
| | | const QList<ProStringList> args = prepareFunctionArgs(tokPtr);
|
| | | traceMsg("calling %s(%s)", dbgKey(func), dbgStrListList(args));
|
| | | return evaluateBoolFunction(*it, args, func);
|
| | | }
|
| | |
|
| | | skipExpression(tokPtr);
|
| | | evalError(fL1S("'%1' is not a recognized test function.").arg(func.toQString(m_tmp1)));
|
| | | return ReturnFalse;
|
| | | }
|
| | |
|
| | | ProStringList QMakeEvaluator::evaluateExpandFunction(
|
| | | const ProKey &func, const ushort *&tokPtr)
|
| | | {
|
| | | if (int func_t = statics.expands.value(func)) {
|
| | | //why don't the builtin functions just use args_list? --Sam
|
| | | return evaluateBuiltinExpand(func_t, func, expandVariableReferences(tokPtr, 5, true));
|
| | | }
|
| | |
|
| | | QHash<ProKey, ProFunctionDef>::ConstIterator it =
|
| | | m_functionDefs.replaceFunctions.constFind(func);
|
| | | if (it != m_functionDefs.replaceFunctions.constEnd()) {
|
| | | const QList<ProStringList> args = prepareFunctionArgs(tokPtr);
|
| | | traceMsg("calling $$%s(%s)", dbgKey(func), dbgStrListList(args));
|
| | | return evaluateFunction(*it, args, 0);
|
| | | }
|
| | |
|
| | | skipExpression(tokPtr);
|
| | | evalError(fL1S("'%1' is not a recognized replace function.").arg(func.toQString(m_tmp1)));
|
| | | return ProStringList();
|
| | | }
|
| | |
|
| | | bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &where, int line)
|
| | | {
|
| | | bool ret = false;
|
| | | ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
|
| | | if (pro) {
|
| | | if (pro->isOk()) {
|
| | | m_locationStack.push(m_current);
|
| | | ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue;
|
| | | m_current = m_locationStack.pop();
|
| | | }
|
| | | pro->deref();
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | void QMakeEvaluator::checkRequirements(const ProStringList &deps)
|
| | | {
|
| | | ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS"));
|
| | | foreach (const ProString &dep, deps)
|
| | | if (!evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line))
|
| | | failed << dep;
|
| | | }
|
| | | #endif
|
| | |
|
| | | ProValueMap *QMakeEvaluator::findValues(const ProKey &variableName, ProValueMap::Iterator *rit)
|
| | | {
|
| | | ProValueMapStack::Iterator vmi = m_valuemapStack.end();
|
| | | do {
|
| | | --vmi;
|
| | | ProValueMap::Iterator it = (*vmi).find(variableName);
|
| | | if (it != (*vmi).end()) {
|
| | | if (it->constBegin() == statics.fakeValue.constBegin())
|
| | | return 0;
|
| | | *rit = it;
|
| | | return &(*vmi);
|
| | | }
|
| | | } while (vmi != m_valuemapStack.begin());
|
| | | return 0;
|
| | | }
|
| | |
|
| | | ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName)
|
| | | {
|
| | | ProValueMap::Iterator it = m_valuemapStack.top().find(variableName);
|
| | | if (it != m_valuemapStack.top().end()) {
|
| | | if (it->constBegin() == statics.fakeValue.constBegin())
|
| | | it->clear();
|
| | | return *it;
|
| | | }
|
| | | ProValueMapStack::Iterator vmi = m_valuemapStack.end();
|
| | | if (--vmi != m_valuemapStack.begin()) {
|
| | | do {
|
| | | --vmi;
|
| | | ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
|
| | | if (it != (*vmi).constEnd()) {
|
| | | ProStringList &ret = m_valuemapStack.top()[variableName];
|
| | | if (it->constBegin() != statics.fakeValue.constBegin())
|
| | | ret = *it;
|
| | | return ret;
|
| | | }
|
| | | } while (vmi != m_valuemapStack.begin());
|
| | | }
|
| | | return m_valuemapStack.top()[variableName];
|
| | | }
|
| | |
|
| | | ProStringList QMakeEvaluator::values(const ProKey &variableName) const
|
| | | {
|
| | | ProValueMapStack::ConstIterator vmi = m_valuemapStack.constEnd();
|
| | | do {
|
| | | --vmi;
|
| | | ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
|
| | | if (it != (*vmi).constEnd()) {
|
| | | if (it->constBegin() == statics.fakeValue.constBegin())
|
| | | break;
|
| | | return *it;
|
| | | }
|
| | | } while (vmi != m_valuemapStack.constBegin());
|
| | | return ProStringList();
|
| | | }
|
| | |
|
| | | ProString QMakeEvaluator::first(const ProKey &variableName) const
|
| | | {
|
| | | const ProStringList &vals = values(variableName);
|
| | | if (!vals.isEmpty())
|
| | | return vals.first();
|
| | | return ProString();
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFile(
|
| | | const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags)
|
| | | {
|
| | | if (ProFile *pro = m_parser->parsedProFile(fileName, true)) {
|
| | | m_locationStack.push(m_current);
|
| | | VisitReturn ok = visitProFile(pro, type, flags);
|
| | | m_current = m_locationStack.pop();
|
| | | pro->deref();
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | if (ok == ReturnTrue) {
|
| | | ProStringList &iif = m_valuemapStack.first()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")];
|
| | | ProString ifn(fileName);
|
| | | if (!iif.contains(ifn))
|
| | | iif << ifn;
|
| | | }
|
| | | #endif
|
| | | return ok;
|
| | | } else {
|
| | | if (!(flags & LoadSilent) && !IoUtils::exists(fileName))
|
| | | evalError(fL1S("WARNING: Include file %1 not found").arg(fileName));
|
| | | return ReturnFalse;
|
| | | }
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileChecked(
|
| | | const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags)
|
| | | {
|
| | | if (fileName.isEmpty())
|
| | | return ReturnFalse;
|
| | | QMakeEvaluator *ref = this;
|
| | | do {
|
| | | foreach (const ProFile *pf, ref->m_profileStack)
|
| | | if (pf->fileName() == fileName) {
|
| | | evalError(fL1S("Circular inclusion of %1.").arg(fileName));
|
| | | return ReturnFalse;
|
| | | }
|
| | | } while ((ref = ref->m_caller));
|
| | | return evaluateFile(fileName, type, flags);
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
|
| | | const QString &fileName, bool silent)
|
| | | {
|
| | | QString fn = fileName;
|
| | | if (!fn.endsWith(QLatin1String(".prf")))
|
| | | fn += QLatin1String(".prf");
|
| | |
|
| | | if (m_featureRoots.isEmpty())
|
| | | updateFeaturePaths();
|
| | | int start_root = 0;
|
| | | QString currFn = currentFileName();
|
| | | if (IoUtils::fileName(currFn) == IoUtils::fileName(fn)) {
|
| | | for (int root = 0; root < m_featureRoots.size(); ++root)
|
| | | if (currFn == m_featureRoots.at(root) + fn) {
|
| | | start_root = root + 1;
|
| | | break;
|
| | | }
|
| | | }
|
| | | for (int root = start_root; root < m_featureRoots.size(); ++root) {
|
| | | QString fname = m_featureRoots.at(root) + fn;
|
| | | if (IoUtils::exists(fname)) {
|
| | | fn = fname;
|
| | | goto cool;
|
| | | }
|
| | | }
|
| | | #ifdef QMAKE_BUILTIN_PRFS
|
| | | fn.prepend(QLatin1String(":/qmake/features/"));
|
| | | if (QFileInfo(fn).exists())
|
| | | goto cool;
|
| | | #endif
|
| | | if (!silent)
|
| | | evalError(fL1S("Cannot find feature %1").arg(fileName));
|
| | | return ReturnFalse;
|
| | |
|
| | | cool:
|
| | | ProStringList &already = valuesRef(ProKey("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
| | | ProString afn(fn);
|
| | | if (already.contains(afn)) {
|
| | | if (!silent)
|
| | | languageWarning(fL1S("Feature %1 already included").arg(fileName));
|
| | | return ReturnTrue;
|
| | | }
|
| | | already.append(afn);
|
| | |
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | bool cumulative = m_cumulative;
|
| | | m_cumulative = false;
|
| | | #endif
|
| | |
|
| | | // The path is fully normalized already.
|
| | | VisitReturn ok = evaluateFile(fn, QMakeHandler::EvalFeatureFile, LoadProOnly);
|
| | |
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | m_cumulative = cumulative;
|
| | | #endif
|
| | | return ok;
|
| | | }
|
| | |
|
| | | QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileInto(
|
| | | const QString &fileName, ProValueMap *values, LoadFlags flags)
|
| | | {
|
| | | QMakeEvaluator visitor(m_option, m_parser, m_handler);
|
| | | visitor.m_caller = this;
|
| | | visitor.m_outputDir = m_outputDir;
|
| | | visitor.m_featureRoots = m_featureRoots;
|
| | | VisitReturn ret = visitor.evaluateFileChecked(fileName, QMakeHandler::EvalAuxFile, flags);
|
| | | if (ret != ReturnTrue)
|
| | | return ret;
|
| | | *values = visitor.m_valuemapStack.top();
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | ProKey qiif("QMAKE_INTERNAL_INCLUDED_FILES");
|
| | | ProStringList &iif = m_valuemapStack.first()[qiif];
|
| | | foreach (const ProString &ifn, values->value(qiif))
|
| | | if (!iif.contains(ifn))
|
| | | iif << ifn;
|
| | | #endif
|
| | | return ReturnTrue;
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::message(int type, const QString &msg) const
|
| | | {
|
| | | if (!m_skipLevel)
|
| | | m_handler->message(type, msg,
|
| | | m_current.line ? m_current.pro->fileName() : QString(),
|
| | | m_current.line != 0xffff ? m_current.line : -1);
|
| | | }
|
| | |
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | void QMakeEvaluator::debugMsgInternal(int level, const char *fmt, ...) const
|
| | | {
|
| | | va_list ap;
|
| | |
|
| | | if (level <= m_debugLevel) {
|
| | | fprintf(stderr, "DEBUG %d: ", level);
|
| | | va_start(ap, fmt);
|
| | | vfprintf(stderr, fmt, ap);
|
| | | va_end(ap);
|
| | | fputc('\n', stderr);
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeEvaluator::traceMsgInternal(const char *fmt, ...) const
|
| | | {
|
| | | va_list ap;
|
| | |
|
| | | if (!m_current.pro)
|
| | | fprintf(stderr, "DEBUG 1: ");
|
| | | else if (m_current.line <= 0)
|
| | | fprintf(stderr, "DEBUG 1: %s: ", qPrintable(m_current.pro->fileName()));
|
| | | else
|
| | | fprintf(stderr, "DEBUG 1: %s:%d: ", qPrintable(m_current.pro->fileName()), m_current.line);
|
| | | va_start(ap, fmt);
|
| | | vfprintf(stderr, fmt, ap);
|
| | | va_end(ap);
|
| | | fputc('\n', stderr);
|
| | | }
|
| | |
|
| | | QString QMakeEvaluator::formatValue(const ProString &val, bool forceQuote)
|
| | | {
|
| | | QString ret;
|
| | | ret.reserve(val.size() + 2);
|
| | | const QChar *chars = val.constData();
|
| | | bool quote = forceQuote || val.isEmpty();
|
| | | for (int i = 0, l = val.size(); i < l; i++) {
|
| | | QChar c = chars[i];
|
| | | ushort uc = c.unicode();
|
| | | if (uc < 32) {
|
| | | switch (uc) {
|
| | | case '\r':
|
| | | ret += QLatin1String("\\r");
|
| | | break;
|
| | | case '\n':
|
| | | ret += QLatin1String("\\n");
|
| | | break;
|
| | | case '\t':
|
| | | ret += QLatin1String("\\t");
|
| | | break;
|
| | | default:
|
| | | ret += QString::fromLatin1("\\x%1").arg(uc, 2, 16, QLatin1Char('0'));
|
| | | break;
|
| | | }
|
| | | } else {
|
| | | switch (uc) {
|
| | | case '\\':
|
| | | ret += QLatin1String("\\\\");
|
| | | break;
|
| | | case '"':
|
| | | ret += QLatin1String("\\\"");
|
| | | break;
|
| | | case '\'':
|
| | | ret += QLatin1String("\\'");
|
| | | break;
|
| | | case 32:
|
| | | quote = true;
|
| | | // fallthrough
|
| | | default:
|
| | | ret += c;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | if (quote) {
|
| | | ret.prepend(QLatin1Char('"'));
|
| | | ret.append(QLatin1Char('"'));
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QString QMakeEvaluator::formatValueList(const ProStringList &vals, bool commas)
|
| | | {
|
| | | QString ret;
|
| | |
|
| | | foreach (const ProString &str, vals) {
|
| | | if (!ret.isEmpty()) {
|
| | | if (commas)
|
| | | ret += QLatin1Char(',');
|
| | | ret += QLatin1Char(' ');
|
| | | }
|
| | | ret += formatValue(str);
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QString QMakeEvaluator::formatValueListList(const QList<ProStringList> &lists)
|
| | | {
|
| | | QString ret;
|
| | |
|
| | | foreach (const ProStringList &list, lists) {
|
| | | if (!ret.isEmpty())
|
| | | ret += QLatin1String(", ");
|
| | | ret += formatValueList(list);
|
| | | }
|
| | | return ret;
|
| | | }
|
| | | #endif
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef QMAKEEVALUATOR_H
|
| | | #define QMAKEEVALUATOR_H
|
| | |
|
| | | #if defined(PROEVALUATOR_FULL) && defined(PROEVALUATOR_THREAD_SAFE)
|
| | | # error PROEVALUATOR_FULL is incompatible with PROEVALUATOR_THREAD_SAFE due to cache() implementation
|
| | | #endif
|
| | |
|
| | | #include "qmakeparser.h"
|
| | | #include "ioutils.h"
|
| | |
|
| | | #include <qlist.h>
|
| | | #include <qlinkedlist.h>
|
| | | #include <qset.h>
|
| | | #include <qstack.h>
|
| | | #include <qstring.h>
|
| | | #include <qstringlist.h>
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | # include <qprocess.h>
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | class QMakeGlobals;
|
| | |
|
| | | class QMAKE_EXPORT QMakeHandler : public QMakeParserHandler
|
| | | {
|
| | | public:
|
| | | enum {
|
| | | SourceEvaluator = 0x10,
|
| | |
|
| | | EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage,
|
| | | EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated,
|
| | |
|
| | | EvalError = ErrorMessage | SourceEvaluator
|
| | | };
|
| | |
|
| | | // error(), warning() and message() from .pro file
|
| | | virtual void fileMessage(const QString &msg) = 0;
|
| | |
|
| | | enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile };
|
| | | virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type) = 0;
|
| | | virtual void doneWithEval(ProFile *parent) = 0;
|
| | | };
|
| | |
|
| | | // We use a QLinkedList based stack instead of a QVector based one (QStack), so that
|
| | | // the addresses of value maps stay constant. The qmake generators rely on that.
|
| | | class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap>
|
| | | {
|
| | | public:
|
| | | inline void push(const ProValueMap &t) { append(t); }
|
| | | inline ProValueMap pop() { return takeLast(); }
|
| | | ProValueMap &top() { return last(); }
|
| | | const ProValueMap &top() const { return last(); }
|
| | | };
|
| | |
|
| | | class QMAKE_EXPORT QMakeEvaluator
|
| | | {
|
| | | public:
|
| | | enum LoadFlag {
|
| | | LoadProOnly = 0,
|
| | | LoadPreFiles = 1,
|
| | | LoadPostFiles = 2,
|
| | | LoadAll = LoadPreFiles|LoadPostFiles,
|
| | | LoadSilent = 0x10
|
| | | };
|
| | | Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
|
| | |
|
| | | static void initStatics();
|
| | | static void initFunctionStatics();
|
| | | QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser,
|
| | | QMakeHandler *handler);
|
| | | ~QMakeEvaluator();
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; }
|
| | | void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; }
|
| | | #endif
|
| | | void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; }
|
| | |
|
| | | ProStringList values(const ProKey &variableName) const;
|
| | | ProStringList &valuesRef(const ProKey &variableName);
|
| | | ProString first(const ProKey &variableName) const;
|
| | | ProString propertyValue(const ProKey &val) const;
|
| | |
|
| | | ProString dirSep() const { return m_dirSep; }
|
| | | bool isHostBuild() const { return m_hostBuild; }
|
| | |
|
| | | enum VisitReturn {
|
| | | ReturnFalse,
|
| | | ReturnTrue,
|
| | | ReturnError,
|
| | | ReturnBreak,
|
| | | ReturnNext,
|
| | | ReturnReturn
|
| | | };
|
| | |
|
| | | static ALWAYS_INLINE VisitReturn returnBool(bool b)
|
| | | { return b ? ReturnTrue : ReturnFalse; }
|
| | |
|
| | | static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
|
| | | ProString getStr(const ushort *&tokPtr);
|
| | | ProKey getHashStr(const ushort *&tokPtr);
|
| | | void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
|
| | | static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
|
| | | static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
|
| | | void skipExpression(const ushort *&tokPtr);
|
| | |
|
| | | void loadDefaults();
|
| | | bool prepareProject(const QString &inDir);
|
| | | bool loadSpecInternal();
|
| | | bool loadSpec();
|
| | | void initFrom(const QMakeEvaluator &other);
|
| | | void setupProject();
|
| | | void evaluateCommand(const QString &cmds, const QString &where);
|
| | | VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type,
|
| | | LoadFlags flags);
|
| | | VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
|
| | | VisitReturn visitProBlock(const ushort *tokPtr);
|
| | | VisitReturn visitProLoop(const ProKey &variable, const ushort *exprPtr,
|
| | | const ushort *tokPtr);
|
| | | void visitProFunctionDef(ushort tok, const ProKey &name, const ushort *tokPtr);
|
| | | void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
|
| | |
|
| | | ALWAYS_INLINE const ProKey &map(const ProString &var) { return map(var.toKey()); }
|
| | | const ProKey &map(const ProKey &var);
|
| | | ProValueMap *findValues(const ProKey &variableName, ProValueMap::Iterator *it);
|
| | |
|
| | | void setTemplate();
|
| | |
|
| | | ProStringList split_value_list(const QString &vals, const ProFile *source = 0);
|
| | | ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
|
| | | ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
|
| | |
|
| | | QString currentFileName() const;
|
| | | QString currentDirectory() const;
|
| | | ProFile *currentProFile() const;
|
| | | QString resolvePath(const QString &fileName) const
|
| | | { return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
|
| | |
|
| | | VisitReturn evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
|
| | | LoadFlags flags);
|
| | | VisitReturn evaluateFileChecked(const QString &fileName, QMakeHandler::EvalFileType type,
|
| | | LoadFlags flags);
|
| | | VisitReturn evaluateFeatureFile(const QString &fileName, bool silent = false);
|
| | | VisitReturn evaluateFileInto(const QString &fileName,
|
| | | ProValueMap *values, // output-only
|
| | | LoadFlags flags);
|
| | | VisitReturn evaluateConfigFeatures();
|
| | | void message(int type, const QString &msg) const;
|
| | | void evalError(const QString &msg) const
|
| | | { message(QMakeHandler::EvalError, msg); }
|
| | | void languageWarning(const QString &msg) const
|
| | | { message(QMakeHandler::EvalWarnLanguage, msg); }
|
| | | void deprecationWarning(const QString &msg) const
|
| | | { message(QMakeHandler::EvalWarnDeprecated, msg); }
|
| | |
|
| | | QList<ProStringList> prepareFunctionArgs(const ushort *&tokPtr);
|
| | | ProStringList evaluateFunction(const ProFunctionDef &func,
|
| | | const QList<ProStringList> &argumentsList, VisitReturn *ok);
|
| | | VisitReturn evaluateBoolFunction(const ProFunctionDef &func,
|
| | | const QList<ProStringList> &argumentsList,
|
| | | const ProString &function);
|
| | |
|
| | | ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr);
|
| | | VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr);
|
| | |
|
| | | ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args);
|
| | | VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
|
| | |
|
| | | bool evaluateConditional(const QString &cond, const QString &where, int line = -1);
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | void checkRequirements(const ProStringList &deps);
|
| | | #endif
|
| | |
|
| | | void updateMkspecPaths();
|
| | | void updateFeaturePaths();
|
| | |
|
| | | bool isActiveConfig(const QString &config, bool regex = false);
|
| | |
|
| | | void populateDeps(
|
| | | const ProStringList &deps, const ProString &prefix,
|
| | | QHash<ProKey, QSet<ProKey> > &dependencies,
|
| | | ProValueMap &dependees, ProStringList &rootSet) const;
|
| | |
|
| | | VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
| | | const QString &contents);
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | void runProcess(QProcess *proc, const QString &command) const;
|
| | | #endif
|
| | | QByteArray getCommandOutput(const QString &args) const;
|
| | |
|
| | | static void removeEach(ProStringList *varlist, const ProStringList &value);
|
| | |
|
| | | QMakeEvaluator *m_caller;
|
| | | #ifdef PROEVALUATOR_CUMULATIVE
|
| | | bool m_cumulative;
|
| | | int m_skipLevel;
|
| | | #else
|
| | | enum { m_cumulative = 0 };
|
| | | enum { m_skipLevel = 0 };
|
| | | #endif
|
| | |
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | void debugMsgInternal(int level, const char *fmt, ...) const;
|
| | | void traceMsgInternal(const char *fmt, ...) const;
|
| | | static QString formatValue(const ProString &val, bool forceQuote = false);
|
| | | static QString formatValueList(const ProStringList &vals, bool commas = false);
|
| | | static QString formatValueListList(const QList<ProStringList> &vals);
|
| | |
|
| | | const int m_debugLevel;
|
| | | #else
|
| | | ALWAYS_INLINE void debugMsgInternal(int, const char *, ...) const {}
|
| | | ALWAYS_INLINE void traceMsgInternal(const char *, ...) const {}
|
| | |
|
| | | enum { m_debugLevel = 0 };
|
| | | #endif
|
| | |
|
| | | struct Location {
|
| | | Location() : pro(0), line(0) {}
|
| | | Location(ProFile *_pro, ushort _line) : pro(_pro), line(_line) {}
|
| | | void clear() { pro = 0; line = 0; }
|
| | | ProFile *pro;
|
| | | ushort line;
|
| | | };
|
| | |
|
| | | Location m_current; // Currently evaluated location
|
| | | QStack<Location> m_locationStack; // All execution location changes
|
| | | QStack<ProFile *> m_profileStack; // Includes only
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | ProValueMap m_extraVars;
|
| | | ProStringList m_extraConfigs;
|
| | | #endif
|
| | | QString m_outputDir;
|
| | |
|
| | | int m_listCount;
|
| | | bool m_valuemapInited;
|
| | | bool m_hostBuild;
|
| | | QString m_qmakespec;
|
| | | QString m_qmakespecName;
|
| | | QString m_superfile;
|
| | | QString m_conffile;
|
| | | QString m_cachefile;
|
| | | QString m_sourceRoot;
|
| | | QString m_buildRoot;
|
| | | QStringList m_qmakepath;
|
| | | QStringList m_qmakefeatures;
|
| | | QStringList m_mkspecPaths;
|
| | | QStringList m_featureRoots;
|
| | | ProString m_dirSep;
|
| | | ProFunctionDefs m_functionDefs;
|
| | | ProStringList m_returnValue;
|
| | | ProValueMapStack m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.
|
| | | QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString
|
| | | mutable QString m_mtmp;
|
| | |
|
| | | QMakeGlobals *m_option;
|
| | | QMakeParser *m_parser;
|
| | | QMakeHandler *m_handler;
|
| | | };
|
| | |
|
| | | Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // QMAKEEVALUATOR_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef QMAKEEVALUATOR_P_H
|
| | | #define QMAKEEVALUATOR_P_H
|
| | |
|
| | | #include "proitems.h"
|
| | |
|
| | | #include <qregexp.h>
|
| | |
|
| | | #define debugMsg if (!m_debugLevel) {} else debugMsgInternal
|
| | | #define traceMsg if (!m_debugLevel) {} else traceMsgInternal
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | # define dbgBool(b) (b ? "true" : "false")
|
| | | # define dbgReturn(r) \
|
| | | (r == ReturnError ? "error" : \
|
| | | r == ReturnBreak ? "break" : \
|
| | | r == ReturnNext ? "next" : \
|
| | | r == ReturnReturn ? "return" : \
|
| | | "<invalid>")
|
| | | # define dbgKey(s) qPrintable(s.toString().toQString())
|
| | | # define dbgStr(s) qPrintable(formatValue(s, true))
|
| | | # define dbgStrList(s) qPrintable(formatValueList(s))
|
| | | # define dbgSepStrList(s) qPrintable(formatValueList(s, true))
|
| | | # define dbgStrListList(s) qPrintable(formatValueListList(s))
|
| | | # define dbgQStr(s) dbgStr(ProString(s))
|
| | | #else
|
| | | # define dbgBool(b) 0
|
| | | # define dbgReturn(r) 0
|
| | | # define dbgKey(s) 0
|
| | | # define dbgStr(s) 0
|
| | | # define dbgStrList(s) 0
|
| | | # define dbgSepStrList(s) 0
|
| | | # define dbgStrListList(s) 0
|
| | | # define dbgQStr(s) 0
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | namespace QMakeInternal {
|
| | |
|
| | | struct QMakeStatics {
|
| | | QString field_sep;
|
| | | QString strtrue;
|
| | | QString strfalse;
|
| | | ProKey strCONFIG;
|
| | | ProKey strARGS;
|
| | | QString strDot;
|
| | | QString strDotDot;
|
| | | QString strever;
|
| | | QString strforever;
|
| | | QString strhost_build;
|
| | | ProKey strTEMPLATE;
|
| | | #ifdef PROEVALUATOR_FULL
|
| | | ProKey strREQUIRES;
|
| | | #endif
|
| | | QHash<ProKey, int> expands;
|
| | | QHash<ProKey, int> functions;
|
| | | QHash<ProKey, ProKey> varMap;
|
| | | ProStringList fakeValue;
|
| | | };
|
| | |
|
| | | extern QMakeStatics statics;
|
| | |
|
| | | }
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // QMAKEEVALUATOR_P_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qmakeglobals.h"
|
| | |
|
| | | #include "qmakeevaluator.h"
|
| | | #include "ioutils.h"
|
| | |
|
| | | #include <qbytearray.h>
|
| | | #include <qdatetime.h>
|
| | | #include <qdebug.h>
|
| | | #include <qdir.h>
|
| | | #include <qfile.h>
|
| | | #include <qfileinfo.h>
|
| | | #include <qlist.h>
|
| | | #include <qregexp.h>
|
| | | #include <qset.h>
|
| | | #include <qstack.h>
|
| | | #include <qstring.h>
|
| | | #include <qstringlist.h>
|
| | | #include <qtextstream.h>
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | # include <qthreadpool.h>
|
| | | #endif
|
| | |
|
| | | #ifdef Q_OS_UNIX
|
| | | #include <unistd.h>
|
| | | #include <sys/utsname.h>
|
| | | #else
|
| | | #include <windows.h>
|
| | | #endif
|
| | | #include <stdio.h>
|
| | | #include <stdlib.h>
|
| | |
|
| | | #ifdef Q_OS_WIN32
|
| | | #define QT_POPEN _popen
|
| | | #define QT_PCLOSE _pclose
|
| | | #else
|
| | | #define QT_POPEN popen
|
| | | #define QT_PCLOSE pclose
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | #define fL1S(s) QString::fromLatin1(s)
|
| | |
|
| | | namespace { // MSVC doesn't seem to know the semantics of "static" ...
|
| | |
|
| | | static struct {
|
| | | QRegExp reg_variableName;
|
| | | } statics;
|
| | |
|
| | | }
|
| | |
|
| | | static void initStatics()
|
| | | {
|
| | | if (!statics.reg_variableName.isEmpty())
|
| | | return;
|
| | |
|
| | | statics.reg_variableName.setPattern(QLatin1String("\\$\\(.*\\)"));
|
| | | statics.reg_variableName.setMinimal(true);
|
| | | }
|
| | |
|
| | | QMakeGlobals::QMakeGlobals()
|
| | | {
|
| | | initStatics();
|
| | |
|
| | | do_cache = true;
|
| | |
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | debugLevel = 0;
|
| | | #endif
|
| | | #ifdef Q_OS_WIN
|
| | | dirlist_sep = QLatin1Char(';');
|
| | | dir_sep = QLatin1Char('\\');
|
| | | #else
|
| | | dirlist_sep = QLatin1Char(':');
|
| | | dir_sep = QLatin1Char('/');
|
| | | #endif
|
| | | qmakespec = getEnv(QLatin1String("QMAKESPEC"));
|
| | | }
|
| | |
|
| | | QMakeGlobals::~QMakeGlobals()
|
| | | {
|
| | | qDeleteAll(baseEnvs);
|
| | | }
|
| | |
|
| | | QString QMakeGlobals::cleanSpec(QMakeCmdLineParserState &state, const QString &spec)
|
| | | {
|
| | | QString ret = QDir::cleanPath(spec);
|
| | | if (ret.contains(QLatin1Char('/'))) {
|
| | | QString absRet = QDir(state.pwd).absoluteFilePath(ret);
|
| | | if (QFile::exists(absRet))
|
| | | ret = QDir::cleanPath(absRet);
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments(
|
| | | QMakeCmdLineParserState &state, QStringList &args, int *pos)
|
| | | {
|
| | | enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache } argState = ArgNone;
|
| | | for (; *pos < args.count(); (*pos)++) {
|
| | | QString arg = args.at(*pos);
|
| | | switch (argState) {
|
| | | case ArgConfig:
|
| | | if (state.after)
|
| | | state.postconfigs << arg;
|
| | | else
|
| | | state.preconfigs << arg;
|
| | | break;
|
| | | case ArgSpec:
|
| | | qmakespec = args[*pos] = cleanSpec(state, arg);
|
| | | break;
|
| | | case ArgXSpec:
|
| | | xqmakespec = args[*pos] = cleanSpec(state, arg);
|
| | | break;
|
| | | case ArgTmpl:
|
| | | user_template = arg;
|
| | | break;
|
| | | case ArgTmplPfx:
|
| | | user_template_prefix = arg;
|
| | | break;
|
| | | case ArgCache:
|
| | | cachefile = args[*pos] = QDir::cleanPath(QDir(state.pwd).absoluteFilePath(arg));
|
| | | break;
|
| | | default:
|
| | | if (arg.startsWith(QLatin1Char('-'))) {
|
| | | if (arg == QLatin1String("-after")) {
|
| | | state.after = true;
|
| | | } else if (arg == QLatin1String("-config")) {
|
| | | argState = ArgConfig;
|
| | | } else if (arg == QLatin1String("-nocache")) {
|
| | | do_cache = false;
|
| | | } else if (arg == QLatin1String("-cache")) {
|
| | | argState = ArgCache;
|
| | | } else if (arg == QLatin1String("-platform") || arg == QLatin1String("-spec")) {
|
| | | argState = ArgSpec;
|
| | | } else if (arg == QLatin1String("-xplatform") || arg == QLatin1String("-xspec")) {
|
| | | argState = ArgXSpec;
|
| | | } else if (arg == QLatin1String("-template") || arg == QLatin1String("-t")) {
|
| | | argState = ArgTmpl;
|
| | | } else if (arg == QLatin1String("-template_prefix") || arg == QLatin1String("-tp")) {
|
| | | argState = ArgTmplPfx;
|
| | | } else if (arg == QLatin1String("-win32")) {
|
| | | dir_sep = QLatin1Char('\\');
|
| | | } else if (arg == QLatin1String("-unix")) {
|
| | | dir_sep = QLatin1Char('/');
|
| | | } else {
|
| | | return ArgumentUnknown;
|
| | | }
|
| | | } else if (arg.contains(QLatin1Char('='))) {
|
| | | if (state.after)
|
| | | state.postcmds << arg;
|
| | | else
|
| | | state.precmds << arg;
|
| | | } else {
|
| | | return ArgumentUnknown;
|
| | | }
|
| | | continue;
|
| | | }
|
| | | argState = ArgNone;
|
| | | }
|
| | | if (argState != ArgNone)
|
| | | return ArgumentMalformed;
|
| | | return ArgumentsOk;
|
| | | }
|
| | |
|
| | | void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state)
|
| | | {
|
| | | if (!state.preconfigs.isEmpty())
|
| | | state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" ")));
|
| | | precmds = state.precmds.join(fL1S("\n"));
|
| | | if (!state.postconfigs.isEmpty())
|
| | | state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(fL1S(" ")));
|
| | | postcmds = state.postcmds.join(fL1S("\n"));
|
| | |
|
| | | if (xqmakespec.isEmpty())
|
| | | xqmakespec = qmakespec;
|
| | | }
|
| | |
|
| | | void QMakeGlobals::useEnvironment()
|
| | | {
|
| | | if (xqmakespec.isEmpty())
|
| | | xqmakespec = getEnv(QLatin1String("XQMAKESPEC"));
|
| | | if (qmakespec.isEmpty()) {
|
| | | qmakespec = getEnv(QLatin1String("QMAKESPEC"));
|
| | | if (xqmakespec.isEmpty())
|
| | | xqmakespec = qmakespec;
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeGlobals::setCommandLineArguments(const QString &pwd, const QStringList &_args)
|
| | | {
|
| | | QStringList args = _args;
|
| | |
|
| | | QMakeCmdLineParserState state(pwd);
|
| | | for (int pos = 0; pos < args.size(); pos++)
|
| | | addCommandLineArguments(state, args, &pos);
|
| | | commitCommandLineArguments(state);
|
| | | useEnvironment();
|
| | | }
|
| | |
|
| | | void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir)
|
| | | {
|
| | | if (input_dir != output_dir && !output_dir.isEmpty()) {
|
| | | QString srcpath = input_dir;
|
| | | if (!srcpath.endsWith(QLatin1Char('/')))
|
| | | srcpath += QLatin1Char('/');
|
| | | QString dstpath = output_dir;
|
| | | if (!dstpath.endsWith(QLatin1Char('/')))
|
| | | dstpath += QLatin1Char('/');
|
| | | int srcLen = srcpath.length();
|
| | | int dstLen = dstpath.length();
|
| | | int lastSl = -1;
|
| | | while (++lastSl, srcpath.at(--srcLen) == dstpath.at(--dstLen))
|
| | | if (srcpath.at(srcLen) == QLatin1Char('/'))
|
| | | lastSl = 0;
|
| | | source_root = srcpath.left(srcLen + lastSl);
|
| | | build_root = dstpath.left(dstLen + lastSl);
|
| | | }
|
| | | }
|
| | |
|
| | | QString QMakeGlobals::shadowedPath(const QString &fileName) const
|
| | | {
|
| | | if (source_root.isEmpty())
|
| | | return fileName;
|
| | | if (fileName.startsWith(source_root)
|
| | | && (fileName.length() == source_root.length()
|
| | | || fileName.at(source_root.length()) == QLatin1Char('/'))) {
|
| | | return build_root + fileName.mid(source_root.length());
|
| | | }
|
| | | return QString();
|
| | | }
|
| | |
|
| | | QString QMakeGlobals::getEnv(const QString &var) const
|
| | | {
|
| | | #ifdef PROEVALUATOR_SETENV
|
| | | return environment.value(var);
|
| | | #else
|
| | | return QString::fromLocal8Bit(qgetenv(var.toLocal8Bit().constData()));
|
| | | #endif
|
| | | }
|
| | |
|
| | | QStringList QMakeGlobals::getPathListEnv(const QString &var) const
|
| | | {
|
| | | QStringList ret;
|
| | | QString val = getEnv(var);
|
| | | if (!val.isEmpty()) {
|
| | | QDir bdir;
|
| | | QStringList vals = val.split(dirlist_sep);
|
| | | ret.reserve(vals.length());
|
| | | foreach (const QString &it, vals)
|
| | | ret << QDir::cleanPath(bdir.absoluteFilePath(it));
|
| | | }
|
| | | return ret;
|
| | | }
|
| | |
|
| | | QString QMakeGlobals::expandEnvVars(const QString &str) const
|
| | | {
|
| | | QString string = str;
|
| | | int rep;
|
| | | QRegExp reg_variableName = statics.reg_variableName; // Copy for thread safety
|
| | | while ((rep = reg_variableName.indexIn(string)) != -1)
|
| | | string.replace(rep, reg_variableName.matchedLength(),
|
| | | getEnv(string.mid(rep + 2, reg_variableName.matchedLength() - 3)));
|
| | | return string;
|
| | | }
|
| | |
|
| | | #ifndef QT_BUILD_QMAKE
|
| | | #ifdef PROEVALUATOR_INIT_PROPS
|
| | | bool QMakeGlobals::initProperties()
|
| | | {
|
| | | QByteArray data;
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | QProcess proc;
|
| | | proc.start(qmake_abslocation, QStringList() << QLatin1String("-query"));
|
| | | if (!proc.waitForFinished())
|
| | | return false;
|
| | | data = proc.readAll();
|
| | | #else
|
| | | if (FILE *proc = QT_POPEN(QString(QMakeInternal::IoUtils::shellQuote(qmake_abslocation)
|
| | | + QLatin1String(" -query")).toLocal8Bit(), "r")) {
|
| | | char buff[1024];
|
| | | while (!feof(proc))
|
| | | data.append(buff, int(fread(buff, 1, 1023, proc)));
|
| | | QT_PCLOSE(proc);
|
| | | }
|
| | | #endif
|
| | | foreach (QByteArray line, data.split('\n'))
|
| | | if (!line.startsWith("QMAKE_")) {
|
| | | int off = line.indexOf(':');
|
| | | if (off < 0) // huh?
|
| | | continue;
|
| | | if (line.endsWith('\r'))
|
| | | line.chop(1);
|
| | | QString name = QString::fromLatin1(line.left(off));
|
| | | ProString value = ProString(QDir::fromNativeSeparators(
|
| | | QString::fromLocal8Bit(line.mid(off + 1))));
|
| | | properties.insert(ProKey(name), value);
|
| | | if (name.startsWith(QLatin1String("QT_")) && !name.contains(QLatin1Char('/'))) {
|
| | | if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
|
| | | properties.insert(ProKey(name + QLatin1String("/raw")), value);
|
| | | properties.insert(ProKey(name + QLatin1String("/get")), value);
|
| | | if (name == QLatin1String("QT_INSTALL_PREFIX")
|
| | | || name == QLatin1String("QT_INSTALL_DATA")
|
| | | || name == QLatin1String("QT_INSTALL_BINS")) {
|
| | | name.replace(3, 7, QLatin1String("HOST"));
|
| | | properties.insert(ProKey(name), value);
|
| | | properties.insert(ProKey(name + QLatin1String("/get")), value);
|
| | | }
|
| | | } else if (name.startsWith(QLatin1String("QT_HOST_"))) {
|
| | | properties.insert(ProKey(name + QLatin1String("/get")), value);
|
| | | }
|
| | | }
|
| | | }
|
| | | properties.insert(ProKey("QMAKE_VERSION"), ProString("2.01a"));
|
| | | return true;
|
| | | }
|
| | | #else
|
| | | void QMakeGlobals::setProperties(const QHash<QString, QString> &props)
|
| | | {
|
| | | QHash<QString, QString>::ConstIterator it = props.constBegin(), eit = props.constEnd();
|
| | | for (; it != eit; ++it)
|
| | | properties.insert(ProKey(it.key()), ProString(it.value()));
|
| | | }
|
| | | #endif
|
| | | #endif // QT_BUILD_QMAKE
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef QMAKEGLOBALS_H
|
| | | #define QMAKEGLOBALS_H
|
| | |
|
| | | #include "qmake_global.h"
|
| | | #include "proitems.h"
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | # include <property.h>
|
| | | #endif
|
| | |
|
| | | #include <qhash.h>
|
| | | #include <qstringlist.h>
|
| | | #ifndef QT_BOOTSTRAPPED
|
| | | # include <qprocess.h>
|
| | | #endif
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | # include <qmutex.h>
|
| | | # include <qwaitcondition.h>
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | class QMakeEvaluator;
|
| | |
|
| | | class QMakeBaseKey
|
| | | {
|
| | | public:
|
| | | QMakeBaseKey(const QString &_root, bool _hostBuild);
|
| | |
|
| | | QString root;
|
| | | bool hostBuild;
|
| | | };
|
| | |
|
| | | uint qHash(const QMakeBaseKey &key);
|
| | | bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two);
|
| | |
|
| | | class QMakeBaseEnv
|
| | | {
|
| | | public:
|
| | | QMakeBaseEnv();
|
| | | ~QMakeBaseEnv();
|
| | |
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | QMutex mutex;
|
| | | QWaitCondition cond;
|
| | | bool inProgress;
|
| | | // The coupling of this flag to thread safety exists because for other
|
| | | // use cases failure is immediately fatal anyway.
|
| | | bool isOk;
|
| | | #endif
|
| | | QMakeEvaluator *evaluator;
|
| | | };
|
| | |
|
| | | class QMAKE_EXPORT QMakeCmdLineParserState
|
| | | {
|
| | | public:
|
| | | QMakeCmdLineParserState(const QString &_pwd) : pwd(_pwd), after(false) {}
|
| | | QString pwd;
|
| | | QStringList precmds, preconfigs, postcmds, postconfigs;
|
| | | bool after;
|
| | | };
|
| | |
|
| | | class QMAKE_EXPORT QMakeGlobals
|
| | | {
|
| | | public:
|
| | | QMakeGlobals();
|
| | | ~QMakeGlobals();
|
| | |
|
| | | bool do_cache;
|
| | | QString dir_sep;
|
| | | QString dirlist_sep;
|
| | | QString cachefile;
|
| | | #ifdef PROEVALUATOR_SETENV
|
| | | QProcessEnvironment environment;
|
| | | #endif
|
| | | QString qmake_abslocation;
|
| | |
|
| | | QString qmakespec, xqmakespec;
|
| | | QString user_template, user_template_prefix;
|
| | | QString precmds, postcmds;
|
| | |
|
| | | #ifdef PROEVALUATOR_DEBUG
|
| | | int debugLevel;
|
| | | #endif
|
| | |
|
| | | enum ArgumentReturn { ArgumentUnknown, ArgumentMalformed, ArgumentsOk };
|
| | | ArgumentReturn addCommandLineArguments(QMakeCmdLineParserState &state,
|
| | | QStringList &args, int *pos);
|
| | | void commitCommandLineArguments(QMakeCmdLineParserState &state);
|
| | | void setCommandLineArguments(const QString &pwd, const QStringList &args);
|
| | | void useEnvironment();
|
| | | void setDirectories(const QString &input_dir, const QString &output_dir);
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | void setQMakeProperty(QMakeProperty *prop) { property = prop; }
|
| | | ProString propertyValue(const ProKey &name) const { return property->value(name); }
|
| | | #else
|
| | | # ifdef PROEVALUATOR_INIT_PROPS
|
| | | bool initProperties();
|
| | | # else
|
| | | void setProperties(const QHash<QString, QString> &props);
|
| | | # endif
|
| | | ProString propertyValue(const ProKey &name) const { return properties.value(name); }
|
| | | #endif
|
| | |
|
| | | QString expandEnvVars(const QString &str) const;
|
| | | QString shadowedPath(const QString &fileName) const;
|
| | |
|
| | | private:
|
| | | QString getEnv(const QString &) const;
|
| | | QStringList getPathListEnv(const QString &var) const;
|
| | |
|
| | | QString cleanSpec(QMakeCmdLineParserState &state, const QString &spec);
|
| | |
|
| | | QString source_root, build_root;
|
| | |
|
| | | #ifdef QT_BUILD_QMAKE
|
| | | QMakeProperty *property;
|
| | | #else
|
| | | QHash<ProKey, ProString> properties;
|
| | | #endif
|
| | |
|
| | | #ifdef PROEVALUATOR_THREAD_SAFE
|
| | | QMutex mutex;
|
| | | #endif
|
| | | QHash<QMakeBaseKey, QMakeBaseEnv *> baseEnvs;
|
| | |
|
| | | friend class QMakeEvaluator;
|
| | | };
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // QMAKEGLOBALS_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qmakeparser.h"
|
| | |
|
| | | #include "ioutils.h"
|
| | | using namespace QMakeInternal;
|
| | |
|
| | | #include <qfile.h>
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | # include <qthreadpool.h>
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | ///////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // ProFileCache
|
| | | //
|
| | | ///////////////////////////////////////////////////////////////////////
|
| | |
|
| | | ProFileCache::~ProFileCache()
|
| | | {
|
| | | foreach (const Entry &ent, parsed_files)
|
| | | if (ent.pro)
|
| | | ent.pro->deref();
|
| | | }
|
| | |
|
| | | void ProFileCache::discardFile(const QString &fileName)
|
| | | {
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | QMutexLocker lck(&mutex);
|
| | | #endif
|
| | | QHash<QString, Entry>::Iterator it = parsed_files.find(fileName);
|
| | | if (it != parsed_files.end()) {
|
| | | if (it->pro)
|
| | | it->pro->deref();
|
| | | parsed_files.erase(it);
|
| | | }
|
| | | }
|
| | |
|
| | | void ProFileCache::discardFiles(const QString &prefix)
|
| | | {
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | QMutexLocker lck(&mutex);
|
| | | #endif
|
| | | QHash<QString, Entry>::Iterator
|
| | | it = parsed_files.begin(),
|
| | | end = parsed_files.end();
|
| | | while (it != end)
|
| | | if (it.key().startsWith(prefix)) {
|
| | | if (it->pro)
|
| | | it->pro->deref();
|
| | | it = parsed_files.erase(it);
|
| | | } else {
|
| | | ++it;
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | ////////// Parser ///////////
|
| | |
|
| | | #define fL1S(s) QString::fromLatin1(s)
|
| | |
|
| | | namespace { // MSVC2010 doesn't seem to know the semantics of "static" ...
|
| | |
|
| | | static struct {
|
| | | QString strelse;
|
| | | QString strfor;
|
| | | QString strdefineTest;
|
| | | QString strdefineReplace;
|
| | | QString stroption;
|
| | | QString strreturn;
|
| | | QString strnext;
|
| | | QString strbreak;
|
| | | QString strhost_build;
|
| | | QString strLINE;
|
| | | QString strFILE;
|
| | | QString strLITERAL_HASH;
|
| | | QString strLITERAL_DOLLAR;
|
| | | QString strLITERAL_WHITESPACE;
|
| | | } statics;
|
| | |
|
| | | }
|
| | |
|
| | | void QMakeParser::initialize()
|
| | | {
|
| | | if (!statics.strelse.isNull())
|
| | | return;
|
| | |
|
| | | statics.strelse = QLatin1String("else");
|
| | | statics.strfor = QLatin1String("for");
|
| | | statics.strdefineTest = QLatin1String("defineTest");
|
| | | statics.strdefineReplace = QLatin1String("defineReplace");
|
| | | statics.stroption = QLatin1String("option");
|
| | | statics.strreturn = QLatin1String("return");
|
| | | statics.strnext = QLatin1String("next");
|
| | | statics.strbreak = QLatin1String("break");
|
| | | statics.strhost_build = QLatin1String("host_build");
|
| | | statics.strLINE = QLatin1String("_LINE_");
|
| | | statics.strFILE = QLatin1String("_FILE_");
|
| | | statics.strLITERAL_HASH = QLatin1String("LITERAL_HASH");
|
| | | statics.strLITERAL_DOLLAR = QLatin1String("LITERAL_DOLLAR");
|
| | | statics.strLITERAL_WHITESPACE = QLatin1String("LITERAL_WHITESPACE");
|
| | | }
|
| | |
|
| | | QMakeParser::QMakeParser(ProFileCache *cache, QMakeParserHandler *handler)
|
| | | : m_cache(cache)
|
| | | , m_handler(handler)
|
| | | {
|
| | | // So that single-threaded apps don't have to call initialize() for now.
|
| | | initialize();
|
| | | }
|
| | |
|
| | | ProFile *QMakeParser::parsedProFile(const QString &fileName, bool cache)
|
| | | {
|
| | | ProFile *pro;
|
| | | if (cache && m_cache) {
|
| | | ProFileCache::Entry *ent;
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | QMutexLocker locker(&m_cache->mutex);
|
| | | #endif
|
| | | QHash<QString, ProFileCache::Entry>::Iterator it = m_cache->parsed_files.find(fileName);
|
| | | if (it != m_cache->parsed_files.end()) {
|
| | | ent = &*it;
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | if (ent->locker && !ent->locker->done) {
|
| | | ++ent->locker->waiters;
|
| | | QThreadPool::globalInstance()->releaseThread();
|
| | | ent->locker->cond.wait(locker.mutex());
|
| | | QThreadPool::globalInstance()->reserveThread();
|
| | | if (!--ent->locker->waiters) {
|
| | | delete ent->locker;
|
| | | ent->locker = 0;
|
| | | }
|
| | | }
|
| | | #endif
|
| | | if ((pro = ent->pro))
|
| | | pro->ref();
|
| | | } else {
|
| | | ent = &m_cache->parsed_files[fileName];
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | ent->locker = new ProFileCache::Entry::Locker;
|
| | | locker.unlock();
|
| | | #endif
|
| | | pro = new ProFile(fileName);
|
| | | if (!read(pro)) {
|
| | | delete pro;
|
| | | pro = 0;
|
| | | } else {
|
| | | pro->itemsRef()->squeeze();
|
| | | pro->ref();
|
| | | }
|
| | | ent->pro = pro;
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | locker.relock();
|
| | | if (ent->locker->waiters) {
|
| | | ent->locker->done = true;
|
| | | ent->locker->cond.wakeAll();
|
| | | } else {
|
| | | delete ent->locker;
|
| | | ent->locker = 0;
|
| | | }
|
| | | #endif
|
| | | }
|
| | | } else {
|
| | | pro = new ProFile(fileName);
|
| | | if (!read(pro)) {
|
| | | delete pro;
|
| | | pro = 0;
|
| | | }
|
| | | }
|
| | | return pro;
|
| | | }
|
| | |
|
| | | ProFile *QMakeParser::parsedProBlock(
|
| | | const QString &contents, const QString &name, int line, SubGrammar grammar)
|
| | | {
|
| | | ProFile *pro = new ProFile(name);
|
| | | if (!read(pro, contents, line, grammar)) {
|
| | | delete pro;
|
| | | pro = 0;
|
| | | }
|
| | | return pro;
|
| | | }
|
| | |
|
| | | void QMakeParser::discardFileFromCache(const QString &fileName)
|
| | | {
|
| | | if (m_cache)
|
| | | m_cache->discardFile(fileName);
|
| | | }
|
| | |
|
| | | bool QMakeParser::read(ProFile *pro)
|
| | | {
|
| | | QFile file(pro->fileName());
|
| | | if (!file.open(QIODevice::ReadOnly)) {
|
| | | if (m_handler && IoUtils::exists(pro->fileName()))
|
| | | m_handler->message(QMakeParserHandler::ParserIoError,
|
| | | fL1S("Cannot read %1: %2").arg(pro->fileName(), file.errorString()));
|
| | | return false;
|
| | | }
|
| | |
|
| | | QByteArray bcont = file.readAll();
|
| | | if (bcont.startsWith(QByteArray("\xef\xbb\xbf"))) {
|
| | | // UTF-8 BOM will cause subtle errors
|
| | | m_handler->message(QMakeParserHandler::ParserIoError,
|
| | | fL1S("Unexpected UTF-8 BOM in %1").arg(pro->fileName()));
|
| | | return false;
|
| | | }
|
| | | QString content(QString::fromLocal8Bit(bcont));
|
| | | bcont.clear();
|
| | | file.close();
|
| | | return read(pro, content, 1, FullGrammar);
|
| | | }
|
| | |
|
| | | void QMakeParser::putTok(ushort *&tokPtr, ushort tok)
|
| | | {
|
| | | *tokPtr++ = tok;
|
| | | }
|
| | |
|
| | | void QMakeParser::putBlockLen(ushort *&tokPtr, uint len)
|
| | | {
|
| | | *tokPtr++ = (ushort)len;
|
| | | *tokPtr++ = (ushort)(len >> 16);
|
| | | }
|
| | |
|
| | | void QMakeParser::putBlock(ushort *&tokPtr, const ushort *buf, uint len)
|
| | | {
|
| | | memcpy(tokPtr, buf, len * 2);
|
| | | tokPtr += len;
|
| | | }
|
| | |
|
| | | void QMakeParser::putHashStr(ushort *&pTokPtr, const ushort *buf, uint len)
|
| | | {
|
| | | uint hash = ProString::hash((const QChar *)buf, len);
|
| | | ushort *tokPtr = pTokPtr;
|
| | | *tokPtr++ = (ushort)hash;
|
| | | *tokPtr++ = (ushort)(hash >> 16);
|
| | | *tokPtr++ = (ushort)len;
|
| | | memcpy(tokPtr, buf, len * 2);
|
| | | pTokPtr = tokPtr + len;
|
| | | }
|
| | |
|
| | | void QMakeParser::finalizeHashStr(ushort *buf, uint len)
|
| | | {
|
| | | buf[-4] = TokHashLiteral;
|
| | | buf[-1] = len;
|
| | | uint hash = ProString::hash((const QChar *)buf, len);
|
| | | buf[-3] = (ushort)hash;
|
| | | buf[-2] = (ushort)(hash >> 16);
|
| | | }
|
| | |
|
| | | bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
|
| | | {
|
| | | m_proFile = pro;
|
| | | m_lineNo = line;
|
| | |
|
| | | // Final precompiled token stream buffer
|
| | | QString tokBuff;
|
| | | // Worst-case size calculations:
|
| | | // - line marker adds 1 (2-nl) to 1st token of each line
|
| | | // - empty assignment "A=":2 =>
|
| | | // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) +
|
| | | // TokValueTerminator(1) == 7 (8)
|
| | | // - non-empty assignment "A=B C":5 =>
|
| | | // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) +
|
| | | // TokLiteral(1) + len(1) + "B"(1) +
|
| | | // TokLiteral(1) + len(1) + "C"(1) + TokValueTerminator(1) == 13 (14)
|
| | | // - variable expansion: "$$f":3 =>
|
| | | // TokVariable(1) + hash(2) + len(1) + "f"(1) = 5
|
| | | // - function expansion: "$$f()":5 =>
|
| | | // TokFuncName(1) + hash(2) + len(1) + "f"(1) + TokFuncTerminator(1) = 6
|
| | | // - scope: "X:":2 =>
|
| | | // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) +
|
| | | // TokBranch(1) + len(2) + ... + len(2) + ... == 10
|
| | | // - test: "X():":4 =>
|
| | | // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokTestCall(1) + TokFuncTerminator(1) +
|
| | | // TokBranch(1) + len(2) + ... + len(2) + ... == 11
|
| | | // - "for(A,B):":9 =>
|
| | | // TokForLoop(1) + hash(2) + len(1) + "A"(1) +
|
| | | // len(2) + TokLiteral(1) + len(1) + "B"(1) + TokValueTerminator(1) +
|
| | | // len(2) + ... + TokTerminator(1) == 14 (15)
|
| | | tokBuff.reserve((in.size() + 1) * 5);
|
| | | ushort *tokPtr = (ushort *)tokBuff.constData(); // Current writing position
|
| | |
|
| | | // Expression precompiler buffer.
|
| | | QString xprBuff;
|
| | | xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple
|
| | | ushort *buf = (ushort *)xprBuff.constData();
|
| | |
|
| | | // Parser state
|
| | | m_blockstack.clear();
|
| | | m_blockstack.resize(1);
|
| | |
|
| | | QStack<ParseCtx> xprStack;
|
| | | xprStack.reserve(10);
|
| | |
|
| | | // We rely on QStrings being null-terminated, so don't maintain a global end pointer.
|
| | | const ushort *cur = (const ushort *)in.unicode();
|
| | | m_canElse = false;
|
| | | freshLine:
|
| | | m_state = StNew;
|
| | | m_invert = false;
|
| | | m_operator = NoOperator;
|
| | | m_markLine = m_lineNo;
|
| | | m_inError = false;
|
| | | int parens = 0; // Braces in value context
|
| | | int argc = 0;
|
| | | int wordCount = 0; // Number of words in currently accumulated expression
|
| | | int lastIndent = 0; // Previous line's indentation, to detect accidental continuation abuse
|
| | | bool lineMarked = true; // For in-expression markers
|
| | | ushort needSep = TokNewStr; // Met unquoted whitespace
|
| | | ushort quote = 0;
|
| | | ushort term = 0;
|
| | |
|
| | | Context context;
|
| | | ushort *ptr;
|
| | | if (grammar == ValueGrammar) {
|
| | | context = CtxPureValue;
|
| | | ptr = tokPtr + 2;
|
| | | } else {
|
| | | context = CtxTest;
|
| | | ptr = buf + 4;
|
| | | }
|
| | | ushort *xprPtr = ptr;
|
| | |
|
| | | #define FLUSH_LHS_LITERAL() \
|
| | | do { \
|
| | | if ((tlen = ptr - xprPtr)) { \
|
| | | finalizeHashStr(xprPtr, tlen); \
|
| | | if (needSep) { \
|
| | | wordCount++; \
|
| | | needSep = 0; \
|
| | | } \
|
| | | } else { \
|
| | | ptr -= 4; \
|
| | | } \
|
| | | } while (0)
|
| | |
|
| | | #define FLUSH_RHS_LITERAL() \
|
| | | do { \
|
| | | if ((tlen = ptr - xprPtr)) { \
|
| | | xprPtr[-2] = TokLiteral | needSep; \
|
| | | xprPtr[-1] = tlen; \
|
| | | if (needSep) { \
|
| | | wordCount++; \
|
| | | needSep = 0; \
|
| | | } \
|
| | | } else { \
|
| | | ptr -= 2; \
|
| | | } \
|
| | | } while (0)
|
| | |
|
| | | #define FLUSH_LITERAL() \
|
| | | do { \
|
| | | if (context == CtxTest) \
|
| | | FLUSH_LHS_LITERAL(); \
|
| | | else \
|
| | | FLUSH_RHS_LITERAL(); \
|
| | | } while (0)
|
| | |
|
| | | #define FLUSH_VALUE_LIST() \
|
| | | do { \
|
| | | if (wordCount > 1) { \
|
| | | xprPtr = tokPtr; \
|
| | | if (*xprPtr == TokLine) \
|
| | | xprPtr += 2; \
|
| | | tokPtr[-1] = ((*xprPtr & TokMask) == TokLiteral) ? wordCount : 0; \
|
| | | } else { \
|
| | | tokPtr[-1] = 0; \
|
| | | } \
|
| | | tokPtr = ptr; \
|
| | | putTok(tokPtr, TokValueTerminator); \
|
| | | } while (0)
|
| | |
|
| | | const ushort *end; // End of this line
|
| | | const ushort *cptr; // Start of next line
|
| | | bool lineCont;
|
| | | int indent;
|
| | |
|
| | | if (context == CtxPureValue) {
|
| | | end = (const ushort *)in.unicode() + in.length();
|
| | | cptr = 0;
|
| | | lineCont = false;
|
| | | indent = 0; // just gcc being stupid
|
| | | goto nextChr;
|
| | | }
|
| | |
|
| | | forever {
|
| | | ushort c;
|
| | |
|
| | | // First, skip leading whitespace
|
| | | for (indent = 0; ; ++cur, ++indent) {
|
| | | c = *cur;
|
| | | if (c == '\n') {
|
| | | ++cur;
|
| | | goto flushLine;
|
| | | } else if (!c) {
|
| | | cur = 0;
|
| | | goto flushLine;
|
| | | } else if (c != ' ' && c != '\t' && c != '\r') {
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | // Then strip comments. Yep - no escaping is possible.
|
| | | for (cptr = cur;; ++cptr) {
|
| | | c = *cptr;
|
| | | if (c == '#') {
|
| | | for (end = cptr; (c = *++cptr);) {
|
| | | if (c == '\n') {
|
| | | ++cptr;
|
| | | break;
|
| | | }
|
| | | }
|
| | | if (end == cur) { // Line with only a comment (sans whitespace)
|
| | | if (m_markLine == m_lineNo)
|
| | | m_markLine++;
|
| | | // Qmake bizarreness: such lines do not affect line continuations
|
| | | goto ignore;
|
| | | }
|
| | | break;
|
| | | }
|
| | | if (!c) {
|
| | | end = cptr;
|
| | | break;
|
| | | }
|
| | | if (c == '\n') {
|
| | | end = cptr++;
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | // Then look for line continuations. Yep - no escaping here as well.
|
| | | forever {
|
| | | // We don't have to check for underrun here, as we already determined
|
| | | // that the line is non-empty.
|
| | | ushort ec = *(end - 1);
|
| | | if (ec == '\\') {
|
| | | --end;
|
| | | lineCont = true;
|
| | | break;
|
| | | }
|
| | | if (ec != ' ' && ec != '\t' && ec != '\r') {
|
| | | lineCont = false;
|
| | | break;
|
| | | }
|
| | | --end;
|
| | | }
|
| | |
|
| | | // Finally, do the tokenization
|
| | | ushort tok, rtok;
|
| | | int tlen;
|
| | | newWord:
|
| | | do {
|
| | | if (cur == end)
|
| | | goto lineEnd;
|
| | | c = *cur++;
|
| | | } while (c == ' ' || c == '\t');
|
| | | forever {
|
| | | if (c == '$') {
|
| | | if (*cur == '$') { // may be EOF, EOL, WS, '#' or '\\' if past end
|
| | | cur++;
|
| | | FLUSH_LITERAL();
|
| | | if (!lineMarked) {
|
| | | lineMarked = true;
|
| | | *ptr++ = TokLine;
|
| | | *ptr++ = (ushort)m_lineNo;
|
| | | }
|
| | | term = 0;
|
| | | tok = TokVariable;
|
| | | c = *cur;
|
| | | if (c == '[') {
|
| | | ptr += 4;
|
| | | tok = TokProperty;
|
| | | term = ']';
|
| | | c = *++cur;
|
| | | } else if (c == '{') {
|
| | | ptr += 4;
|
| | | term = '}';
|
| | | c = *++cur;
|
| | | } else if (c == '(') {
|
| | | ptr += 2;
|
| | | tok = TokEnvVar;
|
| | | term = ')';
|
| | | c = *++cur;
|
| | | } else {
|
| | | ptr += 4;
|
| | | }
|
| | | xprPtr = ptr;
|
| | | rtok = tok;
|
| | | while ((c & 0xFF00) || c == '.' || c == '_' ||
|
| | | (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
| | | (c >= '0' && c <= '9') || (c == '/' && term)) {
|
| | | *ptr++ = c;
|
| | | if (++cur == end) {
|
| | | c = 0;
|
| | | goto notfunc;
|
| | | }
|
| | | c = *cur;
|
| | | }
|
| | | if (tok == TokVariable && c == '(')
|
| | | tok = TokFuncName;
|
| | | notfunc:
|
| | | if (ptr == xprPtr)
|
| | | languageWarning(fL1S("Missing name in expansion"));
|
| | | if (quote)
|
| | | tok |= TokQuoted;
|
| | | if (needSep) {
|
| | | tok |= needSep;
|
| | | wordCount++;
|
| | | }
|
| | | tlen = ptr - xprPtr;
|
| | | if (rtok != TokVariable
|
| | | || !resolveVariable(xprPtr, tlen, needSep, &ptr,
|
| | | &buf, &xprBuff, &tokPtr, &tokBuff, cur, in)) {
|
| | | if (rtok == TokVariable || rtok == TokProperty) {
|
| | | xprPtr[-4] = tok;
|
| | | uint hash = ProString::hash((const QChar *)xprPtr, tlen);
|
| | | xprPtr[-3] = (ushort)hash;
|
| | | xprPtr[-2] = (ushort)(hash >> 16);
|
| | | xprPtr[-1] = tlen;
|
| | | } else {
|
| | | xprPtr[-2] = tok;
|
| | | xprPtr[-1] = tlen;
|
| | | }
|
| | | }
|
| | | if ((tok & TokMask) == TokFuncName) {
|
| | | cur++;
|
| | | funcCall:
|
| | | {
|
| | | xprStack.resize(xprStack.size() + 1);
|
| | | ParseCtx &top = xprStack.top();
|
| | | top.parens = parens;
|
| | | top.quote = quote;
|
| | | top.terminator = term;
|
| | | top.context = context;
|
| | | top.argc = argc;
|
| | | top.wordCount = wordCount;
|
| | | }
|
| | | parens = 0;
|
| | | quote = 0;
|
| | | term = 0;
|
| | | argc = 1;
|
| | | context = CtxArgs;
|
| | | nextToken:
|
| | | wordCount = 0;
|
| | | nextWord:
|
| | | ptr += (context == CtxTest) ? 4 : 2;
|
| | | xprPtr = ptr;
|
| | | needSep = TokNewStr;
|
| | | goto newWord;
|
| | | }
|
| | | if (term) {
|
| | | checkTerm:
|
| | | if (c != term) {
|
| | | parseError(fL1S("Missing %1 terminator [found %2]")
|
| | | .arg(QChar(term))
|
| | | .arg(c ? QString(c) : QString::fromLatin1("end-of-line")));
|
| | | pro->setOk(false);
|
| | | m_inError = true;
|
| | | // Just parse on, as if there was a terminator ...
|
| | | } else {
|
| | | cur++;
|
| | | }
|
| | | }
|
| | | joinToken:
|
| | | ptr += (context == CtxTest) ? 4 : 2;
|
| | | xprPtr = ptr;
|
| | | needSep = 0;
|
| | | goto nextChr;
|
| | | }
|
| | | } else if (c == '\\') {
|
| | | static const char symbols[] = "[]{}()$\\'\"";
|
| | | ushort c2;
|
| | | if (cur != end && !((c2 = *cur) & 0xff00) && strchr(symbols, c2)) {
|
| | | c = c2;
|
| | | cur++;
|
| | | } else {
|
| | | deprecationWarning(fL1S("Unescaped backslashes are deprecated"));
|
| | | }
|
| | | } else if (quote) {
|
| | | if (c == quote) {
|
| | | quote = 0;
|
| | | goto nextChr;
|
| | | } else if (c == '!' && ptr == xprPtr && context == CtxTest) {
|
| | | m_invert ^= true;
|
| | | goto nextChr;
|
| | | }
|
| | | } else if (c == '\'' || c == '"') {
|
| | | quote = c;
|
| | | goto nextChr;
|
| | | } else if (context == CtxArgs) {
|
| | | // Function arg context
|
| | | if (c == ' ' || c == '\t') {
|
| | | FLUSH_RHS_LITERAL();
|
| | | goto nextWord;
|
| | | } else if (c == '(') {
|
| | | ++parens;
|
| | | } else if (c == ')') {
|
| | | if (--parens < 0) {
|
| | | FLUSH_RHS_LITERAL();
|
| | | *ptr++ = TokFuncTerminator;
|
| | | int theargc = argc;
|
| | | {
|
| | | ParseCtx &top = xprStack.top();
|
| | | parens = top.parens;
|
| | | quote = top.quote;
|
| | | term = top.terminator;
|
| | | context = top.context;
|
| | | argc = top.argc;
|
| | | wordCount = top.wordCount;
|
| | | xprStack.resize(xprStack.size() - 1);
|
| | | }
|
| | | if (term == ':') {
|
| | | finalizeCall(tokPtr, buf, ptr, theargc);
|
| | | goto nextItem;
|
| | | } else if (term == '}') {
|
| | | c = (cur == end) ? 0 : *cur;
|
| | | goto checkTerm;
|
| | | } else {
|
| | | Q_ASSERT(!term);
|
| | | goto joinToken;
|
| | | }
|
| | | }
|
| | | } else if (!parens && c == ',') {
|
| | | FLUSH_RHS_LITERAL();
|
| | | *ptr++ = TokArgSeparator;
|
| | | argc++;
|
| | | goto nextToken;
|
| | | }
|
| | | } else if (context == CtxTest) {
|
| | | // Test or LHS context
|
| | | if (c == ' ' || c == '\t') {
|
| | | FLUSH_LHS_LITERAL();
|
| | | goto nextWord;
|
| | | } else if (c == '(') {
|
| | | FLUSH_LHS_LITERAL();
|
| | | if (wordCount != 1) {
|
| | | if (wordCount)
|
| | | parseError(fL1S("Extra characters after test expression."));
|
| | | else
|
| | | parseError(fL1S("Opening parenthesis without prior test name."));
|
| | | pro->setOk(false);
|
| | | ptr = buf; // Put empty function name
|
| | | }
|
| | | *ptr++ = TokTestCall;
|
| | | term = ':';
|
| | | goto funcCall;
|
| | | } else if (c == '!' && ptr == xprPtr) {
|
| | | m_invert ^= true;
|
| | | goto nextChr;
|
| | | } else if (c == ':') {
|
| | | FLUSH_LHS_LITERAL();
|
| | | finalizeCond(tokPtr, buf, ptr, wordCount);
|
| | | if (m_state == StNew)
|
| | | parseError(fL1S("And operator without prior condition."));
|
| | | else
|
| | | m_operator = AndOperator;
|
| | | nextItem:
|
| | | ptr = buf;
|
| | | goto nextToken;
|
| | | } else if (c == '|') {
|
| | | FLUSH_LHS_LITERAL();
|
| | | finalizeCond(tokPtr, buf, ptr, wordCount);
|
| | | if (m_state != StCond)
|
| | | parseError(fL1S("Or operator without prior condition."));
|
| | | else
|
| | | m_operator = OrOperator;
|
| | | goto nextItem;
|
| | | } else if (c == '{') {
|
| | | FLUSH_LHS_LITERAL();
|
| | | finalizeCond(tokPtr, buf, ptr, wordCount);
|
| | | flushCond(tokPtr);
|
| | | ++m_blockstack.top().braceLevel;
|
| | | if (grammar == TestGrammar) {
|
| | | parseError(fL1S("Opening scope not permitted in this context."));
|
| | | pro->setOk(false);
|
| | | }
|
| | | goto nextItem;
|
| | | } else if (c == '}') {
|
| | | FLUSH_LHS_LITERAL();
|
| | | finalizeCond(tokPtr, buf, ptr, wordCount);
|
| | | flushScopes(tokPtr);
|
| | | closeScope:
|
| | | if (!m_blockstack.top().braceLevel) {
|
| | | parseError(fL1S("Excess closing brace."));
|
| | | } else if (!--m_blockstack.top().braceLevel
|
| | | && m_blockstack.count() != 1) {
|
| | | leaveScope(tokPtr);
|
| | | m_state = StNew;
|
| | | m_canElse = false;
|
| | | m_markLine = m_lineNo;
|
| | | }
|
| | | goto nextItem;
|
| | | } else if (c == '+') {
|
| | | tok = TokAppend;
|
| | | goto do2Op;
|
| | | } else if (c == '-') {
|
| | | tok = TokRemove;
|
| | | goto do2Op;
|
| | | } else if (c == '*') {
|
| | | tok = TokAppendUnique;
|
| | | goto do2Op;
|
| | | } else if (c == '~') {
|
| | | tok = TokReplace;
|
| | | do2Op:
|
| | | if (*cur == '=') {
|
| | | cur++;
|
| | | goto doOp;
|
| | | }
|
| | | } else if (c == '=') {
|
| | | tok = TokAssign;
|
| | | doOp:
|
| | | FLUSH_LHS_LITERAL();
|
| | | flushCond(tokPtr);
|
| | | putLineMarker(tokPtr);
|
| | | if (grammar == TestGrammar) {
|
| | | parseError(fL1S("Assignment not permitted in this context."));
|
| | | pro->setOk(false);
|
| | | } else if (wordCount != 1) {
|
| | | parseError(fL1S("Assignment needs exactly one word on the left hand side."));
|
| | | pro->setOk(false);
|
| | | // Put empty variable name.
|
| | | } else {
|
| | | putBlock(tokPtr, buf, ptr - buf);
|
| | | }
|
| | | putTok(tokPtr, tok);
|
| | | context = CtxValue;
|
| | | ptr = ++tokPtr;
|
| | | goto nextToken;
|
| | | }
|
| | | } else if (context == CtxValue) {
|
| | | if (c == ' ' || c == '\t') {
|
| | | FLUSH_RHS_LITERAL();
|
| | | goto nextWord;
|
| | | } else if (c == '{') {
|
| | | ++parens;
|
| | | } else if (c == '}') {
|
| | | if (!parens) {
|
| | | FLUSH_RHS_LITERAL();
|
| | | FLUSH_VALUE_LIST();
|
| | | context = CtxTest;
|
| | | goto closeScope;
|
| | | }
|
| | | --parens;
|
| | | } else if (c == '=') {
|
| | | if (indent < lastIndent)
|
| | | languageWarning(fL1S("Possible accidental line continuation"));
|
| | | }
|
| | | }
|
| | | *ptr++ = c;
|
| | | nextChr:
|
| | | if (cur == end)
|
| | | goto lineEnd;
|
| | | c = *cur++;
|
| | | }
|
| | |
|
| | | lineEnd:
|
| | | if (lineCont) {
|
| | | if (quote) {
|
| | | *ptr++ = ' ';
|
| | | } else {
|
| | | FLUSH_LITERAL();
|
| | | needSep = TokNewStr;
|
| | | ptr += (context == CtxTest) ? 4 : 2;
|
| | | xprPtr = ptr;
|
| | | }
|
| | | } else {
|
| | | cur = cptr;
|
| | | flushLine:
|
| | | FLUSH_LITERAL();
|
| | | if (quote) {
|
| | | parseError(fL1S("Missing closing %1 quote").arg(QChar(quote)));
|
| | | if (!xprStack.isEmpty()) {
|
| | | context = xprStack.at(0).context;
|
| | | xprStack.clear();
|
| | | }
|
| | | goto flErr;
|
| | | } else if (!xprStack.isEmpty()) {
|
| | | parseError(fL1S("Missing closing parenthesis in function call"));
|
| | | context = xprStack.at(0).context;
|
| | | xprStack.clear();
|
| | | flErr:
|
| | | pro->setOk(false);
|
| | | if (context == CtxValue) {
|
| | | tokPtr[-1] = 0; // sizehint
|
| | | putTok(tokPtr, TokValueTerminator);
|
| | | } else if (context == CtxPureValue) {
|
| | | putTok(tokPtr, TokValueTerminator);
|
| | | } else {
|
| | | bogusTest(tokPtr);
|
| | | }
|
| | | } else if (context == CtxValue) {
|
| | | FLUSH_VALUE_LIST();
|
| | | if (parens)
|
| | | languageWarning(fL1S("Possible braces mismatch"));
|
| | | } else if (context == CtxPureValue) {
|
| | | tokPtr = ptr;
|
| | | putTok(tokPtr, TokValueTerminator);
|
| | | } else {
|
| | | finalizeCond(tokPtr, buf, ptr, wordCount);
|
| | | }
|
| | | if (!cur)
|
| | | break;
|
| | | ++m_lineNo;
|
| | | goto freshLine;
|
| | | }
|
| | |
|
| | | lastIndent = indent;
|
| | | lineMarked = false;
|
| | | ignore:
|
| | | cur = cptr;
|
| | | ++m_lineNo;
|
| | | }
|
| | |
|
| | | flushScopes(tokPtr);
|
| | | if (m_blockstack.size() > 1) {
|
| | | parseError(fL1S("Missing closing brace(s)."));
|
| | | pro->setOk(false);
|
| | | }
|
| | | while (m_blockstack.size())
|
| | | leaveScope(tokPtr);
|
| | | tokBuff.resize(tokPtr - (ushort *)tokBuff.constData()); // Reserved capacity stays
|
| | | *pro->itemsRef() = tokBuff;
|
| | | return true;
|
| | |
|
| | | #undef FLUSH_VALUE_LIST
|
| | | #undef FLUSH_LITERAL
|
| | | #undef FLUSH_LHS_LITERAL
|
| | | #undef FLUSH_RHS_LITERAL
|
| | | }
|
| | |
|
| | | void QMakeParser::putLineMarker(ushort *&tokPtr)
|
| | | {
|
| | | if (m_markLine) {
|
| | | *tokPtr++ = TokLine;
|
| | | *tokPtr++ = (ushort)m_markLine;
|
| | | m_markLine = 0;
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeParser::enterScope(ushort *&tokPtr, bool special, ScopeState state)
|
| | | {
|
| | | uchar nest = m_blockstack.top().nest;
|
| | | m_blockstack.resize(m_blockstack.size() + 1);
|
| | | m_blockstack.top().special = special;
|
| | | m_blockstack.top().start = tokPtr;
|
| | | m_blockstack.top().nest = nest;
|
| | | tokPtr += 2;
|
| | | m_state = state;
|
| | | m_canElse = false;
|
| | | if (special)
|
| | | m_markLine = m_lineNo;
|
| | | }
|
| | |
|
| | | void QMakeParser::leaveScope(ushort *&tokPtr)
|
| | | {
|
| | | if (m_blockstack.top().inBranch) {
|
| | | // Put empty else block
|
| | | putBlockLen(tokPtr, 0);
|
| | | }
|
| | | if (ushort *start = m_blockstack.top().start) {
|
| | | putTok(tokPtr, TokTerminator);
|
| | | uint len = tokPtr - start - 2;
|
| | | start[0] = (ushort)len;
|
| | | start[1] = (ushort)(len >> 16);
|
| | | }
|
| | | m_blockstack.resize(m_blockstack.size() - 1);
|
| | | }
|
| | |
|
| | | // If we are on a fresh line, close all open one-line scopes.
|
| | | void QMakeParser::flushScopes(ushort *&tokPtr)
|
| | | {
|
| | | if (m_state == StNew) {
|
| | | while (!m_blockstack.top().braceLevel && m_blockstack.size() > 1)
|
| | | leaveScope(tokPtr);
|
| | | if (m_blockstack.top().inBranch) {
|
| | | m_blockstack.top().inBranch = false;
|
| | | // Put empty else block
|
| | | putBlockLen(tokPtr, 0);
|
| | | }
|
| | | m_canElse = false;
|
| | | }
|
| | | }
|
| | |
|
| | | // If there is a pending conditional, enter a new scope, otherwise flush scopes.
|
| | | void QMakeParser::flushCond(ushort *&tokPtr)
|
| | | {
|
| | | if (m_state == StCond) {
|
| | | putTok(tokPtr, TokBranch);
|
| | | m_blockstack.top().inBranch = true;
|
| | | enterScope(tokPtr, false, StNew);
|
| | | } else {
|
| | | flushScopes(tokPtr);
|
| | | }
|
| | | }
|
| | |
|
| | | void QMakeParser::finalizeTest(ushort *&tokPtr)
|
| | | {
|
| | | flushScopes(tokPtr);
|
| | | putLineMarker(tokPtr);
|
| | | if (m_operator != NoOperator) {
|
| | | putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr);
|
| | | m_operator = NoOperator;
|
| | | }
|
| | | if (m_invert) {
|
| | | putTok(tokPtr, TokNot);
|
| | | m_invert = false;
|
| | | }
|
| | | m_state = StCond;
|
| | | m_canElse = true;
|
| | | }
|
| | |
|
| | | void QMakeParser::bogusTest(ushort *&tokPtr)
|
| | | {
|
| | | flushScopes(tokPtr);
|
| | | m_operator = NoOperator;
|
| | | m_invert = false;
|
| | | m_state = StCond;
|
| | | m_canElse = true;
|
| | | m_proFile->setOk(false);
|
| | | }
|
| | |
|
| | | void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount)
|
| | | {
|
| | | if (wordCount != 1) {
|
| | | if (wordCount) {
|
| | | parseError(fL1S("Extra characters after test expression."));
|
| | | bogusTest(tokPtr);
|
| | | }
|
| | | return;
|
| | | }
|
| | |
|
| | | // Check for magic tokens
|
| | | if (*uc == TokHashLiteral) {
|
| | | uint nlen = uc[3];
|
| | | ushort *uce = uc + 4 + nlen;
|
| | | if (uce == ptr) {
|
| | | m_tmp.setRawData((QChar *)uc + 4, nlen);
|
| | | if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
|
| | | if (m_invert || m_operator != NoOperator) {
|
| | | parseError(fL1S("Unexpected operator in front of else."));
|
| | | return;
|
| | | }
|
| | | BlockScope &top = m_blockstack.top();
|
| | | if (m_canElse && (!top.special || top.braceLevel)) {
|
| | | // A list of tests (the last one likely with side effects),
|
| | | // but no assignment, scope, etc.
|
| | | putTok(tokPtr, TokBranch);
|
| | | // Put empty then block
|
| | | putBlockLen(tokPtr, 0);
|
| | | enterScope(tokPtr, false, StCtrl);
|
| | | return;
|
| | | }
|
| | | forever {
|
| | | BlockScope &top = m_blockstack.top();
|
| | | if (top.inBranch && (!top.special || top.braceLevel)) {
|
| | | top.inBranch = false;
|
| | | enterScope(tokPtr, false, StCtrl);
|
| | | return;
|
| | | }
|
| | | if (top.braceLevel || m_blockstack.size() == 1)
|
| | | break;
|
| | | leaveScope(tokPtr);
|
| | | }
|
| | | parseError(fL1S("Unexpected 'else'."));
|
| | | return;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | finalizeTest(tokPtr);
|
| | | putBlock(tokPtr, uc, ptr - uc);
|
| | | putTok(tokPtr, TokCondition);
|
| | | }
|
| | |
|
| | | void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc)
|
| | | {
|
| | | // Check for magic tokens
|
| | | if (*uc == TokHashLiteral) {
|
| | | uint nlen = uc[3];
|
| | | ushort *uce = uc + 4 + nlen;
|
| | | if (*uce == TokTestCall) {
|
| | | uce++;
|
| | | m_tmp.setRawData((QChar *)uc + 4, nlen);
|
| | | const QString *defName;
|
| | | ushort defType;
|
| | | uchar nest;
|
| | | if (m_tmp == statics.strfor) {
|
| | | if (m_invert || m_operator == OrOperator) {
|
| | | // '|' could actually work reasonably, but qmake does nonsense here.
|
| | | parseError(fL1S("Unexpected operator in front of for()."));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | flushCond(tokPtr);
|
| | | putLineMarker(tokPtr);
|
| | | if (*uce == (TokLiteral|TokNewStr)) {
|
| | | nlen = uce[1];
|
| | | uc = uce + 2 + nlen;
|
| | | if (*uc == TokFuncTerminator) {
|
| | | // for(literal) (only "ever" would be legal if qmake was sane)
|
| | | putTok(tokPtr, TokForLoop);
|
| | | putHashStr(tokPtr, (ushort *)0, (uint)0);
|
| | | putBlockLen(tokPtr, 1 + 3 + nlen + 1);
|
| | | putTok(tokPtr, TokHashLiteral);
|
| | | putHashStr(tokPtr, uce + 2, nlen);
|
| | | didFor:
|
| | | putTok(tokPtr, TokValueTerminator);
|
| | | enterScope(tokPtr, true, StCtrl);
|
| | | m_blockstack.top().nest |= NestLoop;
|
| | | return;
|
| | | } else if (*uc == TokArgSeparator && argc == 2) {
|
| | | // for(var, something)
|
| | | uc++;
|
| | | putTok(tokPtr, TokForLoop);
|
| | | putHashStr(tokPtr, uce + 2, nlen);
|
| | | doFor:
|
| | | nlen = ptr - uc;
|
| | | putBlockLen(tokPtr, nlen + 1);
|
| | | putBlock(tokPtr, uc, nlen);
|
| | | goto didFor;
|
| | | }
|
| | | } else if (argc == 1) {
|
| | | // for(non-literal) (this wouldn't be here if qmake was sane)
|
| | | putTok(tokPtr, TokForLoop);
|
| | | putHashStr(tokPtr, (ushort *)0, (uint)0);
|
| | | uc = uce;
|
| | | goto doFor;
|
| | | }
|
| | | parseError(fL1S("Syntax is for(var, list), for(var, forever) or for(ever)."));
|
| | | return;
|
| | | } else if (m_tmp == statics.strdefineReplace) {
|
| | | defName = &statics.strdefineReplace;
|
| | | defType = TokReplaceDef;
|
| | | goto deffunc;
|
| | | } else if (m_tmp == statics.strdefineTest) {
|
| | | defName = &statics.strdefineTest;
|
| | | defType = TokTestDef;
|
| | | deffunc:
|
| | | if (m_invert) {
|
| | | parseError(fL1S("Unexpected operator in front of function definition."));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | flushScopes(tokPtr);
|
| | | putLineMarker(tokPtr);
|
| | | if (*uce == (TokLiteral|TokNewStr)) {
|
| | | uint nlen = uce[1];
|
| | | if (uce[nlen + 2] == TokFuncTerminator) {
|
| | | if (m_operator != NoOperator) {
|
| | | putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr);
|
| | | m_operator = NoOperator;
|
| | | }
|
| | | putTok(tokPtr, defType);
|
| | | putHashStr(tokPtr, uce + 2, nlen);
|
| | | enterScope(tokPtr, true, StCtrl);
|
| | | m_blockstack.top().nest = NestFunction;
|
| | | return;
|
| | | }
|
| | | }
|
| | | parseError(fL1S("%1(function) requires one literal argument.").arg(*defName));
|
| | | return;
|
| | | } else if (m_tmp == statics.strreturn) {
|
| | | if (argc > 1) {
|
| | | parseError(fL1S("return() requires zero or one argument."));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | defType = TokReturn;
|
| | | nest = NestFunction;
|
| | | goto ctrlstm2;
|
| | | } else if (m_tmp == statics.strnext) {
|
| | | defType = TokNext;
|
| | | goto ctrlstm;
|
| | | } else if (m_tmp == statics.strbreak) {
|
| | | defType = TokBreak;
|
| | | ctrlstm:
|
| | | if (*uce != TokFuncTerminator) {
|
| | | parseError(fL1S("%1() requires zero arguments.").arg(m_tmp));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | nest = NestLoop;
|
| | | ctrlstm2:
|
| | | if (m_invert) {
|
| | | parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | if (!(m_blockstack.top().nest & nest)) {
|
| | | parseError(fL1S("Unexpected %1().").arg(m_tmp));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | finalizeTest(tokPtr);
|
| | | putBlock(tokPtr, uce, ptr - uce - 1); // Only for TokReturn
|
| | | putTok(tokPtr, defType);
|
| | | return;
|
| | | } else if (m_tmp == statics.stroption) {
|
| | | if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1
|
| | | || m_invert || m_operator != NoOperator) {
|
| | | parseError(fL1S("option() must appear outside any control structures."));
|
| | | bogusTest(tokPtr);
|
| | | return;
|
| | | }
|
| | | if (*uce == (TokLiteral|TokNewStr)) {
|
| | | uint nlen = uce[1];
|
| | | if (uce[nlen + 2] == TokFuncTerminator) {
|
| | | m_tmp.setRawData((QChar *)uce + 2, nlen);
|
| | | if (m_tmp == statics.strhost_build) {
|
| | | m_proFile->setHostBuild(true);
|
| | | } else {
|
| | | parseError(fL1S("Unknown option() %1.").arg(m_tmp));
|
| | | }
|
| | | return;
|
| | | }
|
| | | }
|
| | | parseError(fL1S("option() requires one literal argument."));
|
| | | return;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | finalizeTest(tokPtr);
|
| | | putBlock(tokPtr, uc, ptr - uc);
|
| | | }
|
| | |
|
| | | bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
|
| | | ushort **buf, QString *xprBuff,
|
| | | ushort **tokPtr, QString *tokBuff,
|
| | | const ushort *cur, const QString &in)
|
| | | {
|
| | | QString out;
|
| | | m_tmp.setRawData((const QChar *)xprPtr, tlen);
|
| | | if (m_tmp == statics.strLINE) {
|
| | | out.setNum(m_lineNo);
|
| | | } else if (m_tmp == statics.strFILE) {
|
| | | out = m_proFile->fileName();
|
| | | // The string is typically longer than the variable reference, so we need
|
| | | // to ensure that there is enough space in the output buffer - as unlikely
|
| | | // as an overflow is to actually happen in practice.
|
| | | int need = (in.length() - (cur - (const ushort *)in.constData()) + 2) * 5 + out.length();
|
| | | int tused = *tokPtr - (ushort *)tokBuff->constData();
|
| | | int xused;
|
| | | int total;
|
| | | bool ptrFinal = xprPtr >= (ushort *)tokBuff->constData()
|
| | | && xprPtr < (ushort *)tokBuff->constData() + tokBuff->capacity();
|
| | | if (ptrFinal) {
|
| | | xused = xprPtr - (ushort *)tokBuff->constData();
|
| | | total = xused + need;
|
| | | } else {
|
| | | xused = xprPtr - *buf;
|
| | | total = tused + xused + need;
|
| | | }
|
| | | if (tokBuff->capacity() < total) {
|
| | | tokBuff->reserve(total);
|
| | | *tokPtr = (ushort *)tokBuff->constData() + tused;
|
| | | xprBuff->reserve(total);
|
| | | *buf = (ushort *)xprBuff->constData();
|
| | | xprPtr = (ptrFinal ? (ushort *)tokBuff->constData() : *buf) + xused;
|
| | | }
|
| | | } else if (m_tmp == statics.strLITERAL_HASH) {
|
| | | out = QLatin1String("#");
|
| | | } else if (m_tmp == statics.strLITERAL_DOLLAR) {
|
| | | out = QLatin1String("$");
|
| | | } else if (m_tmp == statics.strLITERAL_WHITESPACE) {
|
| | | out = QLatin1String("\t");
|
| | | } else {
|
| | | return false;
|
| | | }
|
| | | xprPtr -= 2; // Was set up for variable reference
|
| | | xprPtr[-2] = TokLiteral | needSep;
|
| | | xprPtr[-1] = out.length();
|
| | | memcpy(xprPtr, out.constData(), out.length() * 2);
|
| | | *ptr = xprPtr + out.length();
|
| | | return true;
|
| | | }
|
| | |
|
| | | void QMakeParser::message(int type, const QString &msg) const
|
| | | {
|
| | | if (!m_inError && m_handler)
|
| | | m_handler->message(type, msg, m_proFile->fileName(), m_lineNo);
|
| | | }
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef QMAKEPARSER_H
|
| | | #define QMAKEPARSER_H
|
| | |
|
| | | #include "qmake_global.h"
|
| | | #include "proitems.h"
|
| | |
|
| | | #include <qhash.h>
|
| | | #include <qstack.h>
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | # include <qmutex.h>
|
| | | # include <qwaitcondition.h>
|
| | | #endif
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | | class QMAKE_EXPORT QMakeParserHandler
|
| | | {
|
| | | public:
|
| | | enum {
|
| | | CategoryMask = 0xf00,
|
| | | WarningMessage = 0x000,
|
| | | ErrorMessage = 0x100,
|
| | |
|
| | | SourceMask = 0xf0,
|
| | | SourceParser = 0,
|
| | |
|
| | | CodeMask = 0xf,
|
| | | WarnLanguage = 0,
|
| | | WarnDeprecated,
|
| | |
|
| | | ParserWarnLanguage = SourceParser | WarningMessage | WarnLanguage,
|
| | | ParserWarnDeprecated = SourceParser | WarningMessage | WarnDeprecated,
|
| | |
|
| | | ParserIoError = ErrorMessage | SourceParser,
|
| | | ParserError
|
| | | };
|
| | | virtual void message(int type, const QString &msg,
|
| | | const QString &fileName = QString(), int lineNo = 0) = 0;
|
| | | };
|
| | |
|
| | | class ProFileCache;
|
| | |
|
| | | class QMAKE_EXPORT QMakeParser
|
| | | {
|
| | | public:
|
| | | // Call this from a concurrency-free context
|
| | | static void initialize();
|
| | |
|
| | | QMakeParser(ProFileCache *cache, QMakeParserHandler *handler);
|
| | |
|
| | | enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
|
| | | // fileName is expected to be absolute and cleanPath()ed.
|
| | | ProFile *parsedProFile(const QString &fileName, bool cache = false);
|
| | | ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
|
| | | SubGrammar grammar = FullGrammar);
|
| | |
|
| | | void discardFileFromCache(const QString &fileName);
|
| | |
|
| | | private:
|
| | | enum ScopeNesting {
|
| | | NestNone = 0,
|
| | | NestLoop = 1,
|
| | | NestFunction = 2
|
| | | };
|
| | |
|
| | | struct BlockScope {
|
| | | BlockScope() : start(0), braceLevel(0), special(false), inBranch(false), nest(NestNone) {}
|
| | | BlockScope(const BlockScope &other) { *this = other; }
|
| | | ushort *start; // Where this block started; store length here
|
| | | int braceLevel; // Nesting of braces in scope
|
| | | bool special; // Single-line conditionals inside loops, etc. cannot have else branches
|
| | | bool inBranch; // The 'else' branch of the previous TokBranch is still open
|
| | | uchar nest; // Into what control structures we are nested
|
| | | };
|
| | |
|
| | | enum ScopeState {
|
| | | StNew, // Fresh scope
|
| | | StCtrl, // Control statement (for or else) met on current line
|
| | | StCond // Conditionals met on current line
|
| | | };
|
| | |
|
| | | enum Context { CtxTest, CtxValue, CtxPureValue, CtxArgs };
|
| | | struct ParseCtx {
|
| | | int parens; // Nesting of non-functional parentheses
|
| | | int argc; // Number of arguments in current function call
|
| | | int wordCount; // Number of words in current expression
|
| | | Context context;
|
| | | ushort quote; // Enclosing quote type
|
| | | ushort terminator; // '}' if replace function call is braced, ':' if test function
|
| | | };
|
| | |
|
| | | bool read(ProFile *pro);
|
| | | bool read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
|
| | |
|
| | | ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
|
| | | ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
|
| | | ALWAYS_INLINE void putBlock(ushort *&tokPtr, const ushort *buf, uint len);
|
| | | void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len);
|
| | | void finalizeHashStr(ushort *buf, uint len);
|
| | | void putLineMarker(ushort *&tokPtr);
|
| | | ALWAYS_INLINE bool resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
|
| | | ushort **buf, QString *xprBuff,
|
| | | ushort **tokPtr, QString *tokBuff,
|
| | | const ushort *cur, const QString &in);
|
| | | void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
| | | void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
| | | void finalizeTest(ushort *&tokPtr);
|
| | | void bogusTest(ushort *&tokPtr);
|
| | | void enterScope(ushort *&tokPtr, bool special, ScopeState state);
|
| | | void leaveScope(ushort *&tokPtr);
|
| | | void flushCond(ushort *&tokPtr);
|
| | | void flushScopes(ushort *&tokPtr);
|
| | |
|
| | | void message(int type, const QString &msg) const;
|
| | | void parseError(const QString &msg) const
|
| | | { message(QMakeParserHandler::ParserError, msg); }
|
| | | void languageWarning(const QString &msg) const
|
| | | { message(QMakeParserHandler::ParserWarnLanguage, msg); }
|
| | | void deprecationWarning(const QString &msg) const
|
| | | { message(QMakeParserHandler::ParserWarnDeprecated, msg); }
|
| | |
|
| | | // Current location
|
| | | ProFile *m_proFile;
|
| | | int m_lineNo;
|
| | |
|
| | | QStack<BlockScope> m_blockstack;
|
| | | ScopeState m_state;
|
| | | int m_markLine; // Put marker for this line
|
| | | bool m_inError; // Current line had a parsing error; suppress followup error messages
|
| | | bool m_canElse; // Conditionals met on previous line, but no scope was opened
|
| | | bool m_invert; // Pending conditional is negated
|
| | | enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed
|
| | |
|
| | | QString m_tmp; // Temporary for efficient toQString
|
| | |
|
| | | ProFileCache *m_cache;
|
| | | QMakeParserHandler *m_handler;
|
| | |
|
| | | // This doesn't help gcc 3.3 ...
|
| | | template<typename T> friend class QTypeInfo;
|
| | |
|
| | | friend class ProFileCache;
|
| | | };
|
| | |
|
| | | class QMAKE_EXPORT ProFileCache
|
| | | {
|
| | | public:
|
| | | ProFileCache() {}
|
| | | ~ProFileCache();
|
| | |
|
| | | void discardFile(const QString &fileName);
|
| | | void discardFiles(const QString &prefix);
|
| | |
|
| | | private:
|
| | | struct Entry {
|
| | | ProFile *pro;
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | struct Locker {
|
| | | Locker() : waiters(0), done(false) {}
|
| | | QWaitCondition cond;
|
| | | int waiters;
|
| | | bool done;
|
| | | };
|
| | | Locker *locker;
|
| | | #endif
|
| | | };
|
| | |
|
| | | QHash<QString, Entry> parsed_files;
|
| | | #ifdef PROPARSER_THREAD_SAFE
|
| | | QMutex mutex;
|
| | | #endif
|
| | |
|
| | | friend class QMakeParser;
|
| | | };
|
| | |
|
| | | #if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
|
| | | Q_DECLARE_TYPEINFO(QMakeParser::BlockScope, Q_MOVABLE_TYPE);
|
| | | Q_DECLARE_TYPEINFO(QMakeParser::Context, Q_PRIMITIVE_TYPE);
|
| | | #endif
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // PROFILEPARSER_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qmakedataprovider.h"
|
| | | #include <QCoreApplication>
|
| | | #include <QStringList>
|
| | | #include <QFileInfo>
|
| | | #include <QXmlStreamWriter>
|
| | |
|
| | | QString toString(bool b)
|
| | | {
|
| | | return b ? QStringLiteral("true") : QStringLiteral("false");
|
| | | }
|
| | |
|
| | | int main(int argc, char *argv[])
|
| | | {
|
| | | if (argc < 3) {
|
| | | fputs("Usage: qmakefilereader <QtDir> <filePath>\n", stderr);
|
| | | return -1;
|
| | | }
|
| | |
|
| | | QCoreApplication app(argc, argv);
|
| | | const QStringList args = app.arguments();
|
| | | const QString qtDir = args.at(1);
|
| | | const QString filePath = QFileInfo(args.at(2)).absoluteFilePath();
|
| | |
|
| | | QMakeDataProvider dataProvider;
|
| | | dataProvider.setQtDir(qtDir);
|
| | | if (!dataProvider.readFile(filePath))
|
| | | return 1;
|
| | |
|
| | | QFile fout;
|
| | | if (!fout.open(stdout, QFile::WriteOnly))
|
| | | return 2;
|
| | |
|
| | | QXmlStreamWriter stream(&fout);
|
| | | stream.setAutoFormatting(true);
|
| | | stream.writeStartDocument();
|
| | | stream.writeStartElement("content");
|
| | | stream.writeAttribute("valid", toString(dataProvider.isValid()));
|
| | | stream.writeAttribute("flat", toString(dataProvider.isFlat()));
|
| | | stream.writeStartElement("SOURCES");
|
| | | foreach (const QString &str, dataProvider.getSourceFiles())
|
| | | stream.writeTextElement("file", str);
|
| | | stream.writeEndElement();
|
| | | stream.writeStartElement("HEADERS");
|
| | | foreach (const QString &str, dataProvider.getHeaderFiles())
|
| | | stream.writeTextElement("file", str);
|
| | | stream.writeEndElement();
|
| | | stream.writeStartElement("RESOURCES");
|
| | | foreach (const QString &str, dataProvider.getResourceFiles())
|
| | | stream.writeTextElement("file", str);
|
| | | stream.writeEndElement();
|
| | | stream.writeStartElement("FORMS");
|
| | | foreach (const QString &str, dataProvider.getFormFiles())
|
| | | stream.writeTextElement("file", str);
|
| | | stream.writeEndElement();
|
| | | stream.writeEndElement(); // content
|
| | | stream.writeEndDocument();
|
| | | return 0;
|
| | | }
|
| | |
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qmakedataprovider.h"
|
| | | #include "evalhandler.h"
|
| | | #include <qmakeevaluator.h>
|
| | | #include <qmakeglobals.h>
|
| | | #include <QtCore/QFileInfo>
|
| | | #include <QtCore/QList>
|
| | | #include <QtCore/QPair>
|
| | |
|
| | | class QMakeDataProviderPrivate
|
| | | {
|
| | | public:
|
| | | QStringList m_headerFiles;
|
| | | QStringList m_sourceFiles;
|
| | | QStringList m_resourceFiles;
|
| | | QStringList m_formFiles;
|
| | | typedef QPair<QStringList *, ProKey> Mapping;
|
| | | QList<Mapping> m_variableMappings;
|
| | | bool m_valid;
|
| | | bool m_flat;
|
| | | QString m_qtdir;
|
| | |
|
| | | QMakeDataProviderPrivate()
|
| | | {
|
| | | m_variableMappings
|
| | | << qMakePair(&m_headerFiles, ProKey("HEADERS"))
|
| | | << qMakePair(&m_sourceFiles, ProKey("SOURCES"))
|
| | | << qMakePair(&m_resourceFiles, ProKey("RESOURCES"))
|
| | | << qMakePair(&m_formFiles, ProKey("FORMS"));
|
| | | }
|
| | |
|
| | | bool readFile(const QString &fileName)
|
| | | {
|
| | | QFileInfo fi(fileName);
|
| | | if (fi.isRelative())
|
| | | qWarning("qmakewrapper: expecting an absolute filename.");
|
| | |
|
| | | m_headerFiles.clear();
|
| | | m_sourceFiles.clear();
|
| | | m_resourceFiles.clear();
|
| | | m_formFiles.clear();
|
| | | m_valid = false;
|
| | | m_flat = true;
|
| | |
|
| | | QMakeGlobals globals;
|
| | | ProFileCache proFileCache;
|
| | | EvalHandler handler;
|
| | | QMakeParser parser(&proFileCache, &handler);
|
| | | QMakeEvaluator evaluator(&globals, &parser, &handler);
|
| | | if (evaluator.evaluateFile(fileName, QMakeHandler::EvalProjectFile,
|
| | | QMakeEvaluator::LoadProOnly) != QMakeEvaluator::ReturnTrue)
|
| | | {
|
| | | qWarning("qmakewrapper: failed to parse %s", qPrintable(fileName));
|
| | | return false;
|
| | | }
|
| | |
|
| | | m_valid = true;
|
| | | m_flat = evaluator.isActiveConfig(QStringLiteral("flat"));
|
| | |
|
| | | foreach (const Mapping &mapping, m_variableMappings)
|
| | | *mapping.first = evaluator.values(mapping.second).toQStringList();
|
| | |
|
| | | return true;
|
| | | }
|
| | | };
|
| | |
|
| | | QMakeDataProvider::QMakeDataProvider()
|
| | | : d(new QMakeDataProviderPrivate())
|
| | | {
|
| | | }
|
| | |
|
| | | QMakeDataProvider::~QMakeDataProvider()
|
| | | {
|
| | | delete d;
|
| | | }
|
| | |
|
| | | bool QMakeDataProvider::readFile(const QString &fileName)
|
| | | {
|
| | | return d->readFile(fileName);
|
| | | }
|
| | |
|
| | | void QMakeDataProvider::setQtDir(const QString &qtdir)
|
| | | {
|
| | | d->m_qtdir = qtdir;
|
| | | }
|
| | |
|
| | | QStringList QMakeDataProvider::getFormFiles() const
|
| | | {
|
| | | return d->m_formFiles;
|
| | | }
|
| | |
|
| | | QStringList QMakeDataProvider::getHeaderFiles() const
|
| | | {
|
| | | return d->m_headerFiles;
|
| | | }
|
| | |
|
| | | QStringList QMakeDataProvider::getResourceFiles() const
|
| | | {
|
| | | return d->m_resourceFiles;
|
| | | }
|
| | |
|
| | | QStringList QMakeDataProvider::getSourceFiles() const
|
| | | {
|
| | | return d->m_sourceFiles;
|
| | | }
|
| | |
|
| | | bool QMakeDataProvider::isFlat() const
|
| | | {
|
| | | return d->m_flat;
|
| | | }
|
| | |
|
| | | bool QMakeDataProvider::isValid() const
|
| | | {
|
| | | return d->m_valid;
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef QMAKEDATAPROVIDER_H
|
| | | #define QMAKEDATAPROVIDER_H
|
| | |
|
| | | #include <QtCore/QString>
|
| | | #include <QtCore/QStringList>
|
| | |
|
| | | class QMakeDataProviderPrivate;
|
| | |
|
| | | class QMakeDataProvider {
|
| | |
|
| | | QMakeDataProviderPrivate * const d;
|
| | |
|
| | | public:
|
| | | QMakeDataProvider();
|
| | | ~QMakeDataProvider();
|
| | |
|
| | | bool readFile(const QString &fileName);
|
| | | void setQtDir(const QString &qtdir);
|
| | | QStringList getFormFiles() const;
|
| | | QStringList getHeaderFiles() const;
|
| | | QStringList getResourceFiles() const;
|
| | | QStringList getSourceFiles() const;
|
| | | bool isFlat() const;
|
| | | bool isValid() const;
|
| | | };
|
| | |
|
| | | #endif // QMAKEDATAPROVIDER_H
|
| | |
|
New file |
| | |
| | | IDI_ICON1 ICON DISCARDABLE "qmakefilereader.ico"
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <ItemGroup Label="ProjectConfigurations">
|
| | | <ProjectConfiguration Include="Debug|Win32">
|
| | | <Configuration>Debug</Configuration>
|
| | | <Platform>Win32</Platform>
|
| | | </ProjectConfiguration>
|
| | | <ProjectConfiguration Include="Release|Win32">
|
| | | <Configuration>Release</Configuration>
|
| | | <Platform>Win32</Platform>
|
| | | </ProjectConfiguration>
|
| | | <ProjectConfiguration Include="Debug|x64">
|
| | | <Configuration>Debug</Configuration>
|
| | | <Platform>x64</Platform>
|
| | | </ProjectConfiguration>
|
| | | <ProjectConfiguration Include="Release|x64">
|
| | | <Configuration>Release</Configuration>
|
| | | <Platform>x64</Platform>
|
| | | </ProjectConfiguration>
|
| | | </ItemGroup>
|
| | | <PropertyGroup Label="Globals">
|
| | | <ProjectGuid>{70711A97-D9B0-3A86-9756-9FF47337908B}</ProjectGuid>
|
| | | <Keyword>QtVS_v303</Keyword>
|
| | | <RootNamespace>QMakeFileReader</RootNamespace>
|
| | | <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='15.0'">10.0.17763.0</WindowsTargetPlatformVersion>
|
| | | <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='16.0'">10.0</WindowsTargetPlatformVersion>
|
| | | <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='17.0'">10.0</WindowsTargetPlatformVersion>
|
| | | <QtMsBuild>$(SolutionDir)\qtmsbuild\QtMsBuild</QtMsBuild>
|
| | | </PropertyGroup>
|
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
| | | <PropertyGroup>
|
| | | <PlatformToolset Condition="'$(VisualStudioVersion)'=='15.0'">v141</PlatformToolset>
|
| | | <PlatformToolset Condition="'$(VisualStudioVersion)'=='16.0'">v142</PlatformToolset>
|
| | | <PlatformToolset Condition="'$(VisualStudioVersion)'=='17.0'">v143</PlatformToolset>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="Configuration">
|
| | | <ConfigurationType>Application</ConfigurationType>
|
| | | <OutDir>bin\$(VisualStudioVersion)\$(Platform)\$(Configuration)\</OutDir>
|
| | | <IntDir>obj\$(VisualStudioVersion)\$(Platform)\$(Configuration)\</IntDir>
|
| | | </PropertyGroup>
|
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
| | | <ImportGroup Label="ExtensionSettings" />
|
| | | <ImportGroup Label="PropertySheets">
|
| | | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
| | | <Import Project="..\QtCppConfig.props" />
|
| | | </ImportGroup>
|
| | | <PropertyGroup Label="UserMacros" />
|
| | | <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
| | | <Import Project="$(QtMsBuild)\qt_defaults.props" />
|
| | | </ImportGroup>
|
| | | <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
| | | <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
| | | </Target>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
| | | <QtModules>core</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
| | | <QtModules>core</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
| | | <QtModules>core</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
| | | <QtModules>core</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
|
| | | <Import Project="$(QtMsBuild)\qt.props" />
|
| | | </ImportGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
| | | <ClCompile>
|
| | | <Optimization>Disabled</Optimization>
|
| | | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
| | | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>evaluator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Console</SubSystem>
|
| | | <OutputFile>$(OutDir)\QMakeFileReader.exe</OutputFile>
|
| | | <GenerateDebugInformation>true</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
| | | <ClCompile>
|
| | | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>evaluator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DebugInformationFormat>None</DebugInformationFormat>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <Optimization>MaxSpeed</Optimization>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <ProgramDataBaseFileName>
|
| | | </ProgramDataBaseFileName>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Console</SubSystem>
|
| | | <OutputFile>$(OutDir)\QMakeFileReader.exe</OutputFile>
|
| | | <GenerateDebugInformation>false</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <LinkIncremental>false</LinkIncremental>
|
| | | <OptimizeReferences>true</OptimizeReferences>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
| | | <ClCompile>
|
| | | <Optimization>Disabled</Optimization>
|
| | | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
| | | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>evaluator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Console</SubSystem>
|
| | | <OutputFile>$(OutDir)\QMakeFileReader.exe</OutputFile>
|
| | | <GenerateDebugInformation>true</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
| | | <ClCompile>
|
| | | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>evaluator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DebugInformationFormat>None</DebugInformationFormat>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <Optimization>MaxSpeed</Optimization>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <ProgramDataBaseFileName>
|
| | | </ProgramDataBaseFileName>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Console</SubSystem>
|
| | | <OutputFile>$(OutDir)\QMakeFileReader.exe</OutputFile>
|
| | | <GenerateDebugInformation>false</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <LinkIncremental>false</LinkIncremental>
|
| | | <OptimizeReferences>true</OptimizeReferences>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemGroup>
|
| | | <ClCompile Include="main.cpp" />
|
| | | <ClCompile Include="evalhandler.cpp" />
|
| | | <ClCompile Include="evaluator\ioutils.cpp" />
|
| | | <ClCompile Include="evaluator\proitems.cpp" />
|
| | | <ClCompile Include="evaluator\qmakebuiltins.cpp" />
|
| | | <ClCompile Include="qmakedataprovider.cpp" />
|
| | | <ClCompile Include="evaluator\qmakeevaluator.cpp" />
|
| | | <ClCompile Include="evaluator\qmakeglobals.cpp" />
|
| | | <ClCompile Include="evaluator\qmakeparser.cpp" />
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ClInclude Include="evalhandler.h" />
|
| | | <ClInclude Include="evaluator\ioutils.h" />
|
| | | <ClInclude Include="evaluator\proitems.h" />
|
| | | <ClInclude Include="evaluator\qmake_global.h" />
|
| | | <ClInclude Include="qmakedataprovider.h" />
|
| | | <ClInclude Include="evaluator\qmakeevaluator.h" />
|
| | | <ClInclude Include="evaluator\qmakeevaluator_p.h" />
|
| | | <ClInclude Include="evaluator\qmakeglobals.h" />
|
| | | <ClInclude Include="evaluator\qmakeparser.h" />
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ResourceCompile Include="qmakefilereader.rc" />
|
| | | </ItemGroup>
|
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
| | | <Import Project="$(SolutionDir)\transform.targets" />
|
| | | <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
| | | <Import Project="$(QtMsBuild)\qt.targets" />
|
| | | </ImportGroup>
|
| | | <ImportGroup Label="ExtensionTargets" />
|
| | | <ItemGroup>
|
| | | <ProjectReference Include="..\qtmsbuild\QtMSBuild.csproj">
|
| | | <Project>{A618D28B-9352-44F4-AA71-609BF68BF871}</Project>
|
| | | </ProjectReference>
|
| | | </ItemGroup>
|
| | | <Target Name="qmakeFileReader_PreBuild">
|
| | | <ItemGroup>
|
| | | <ProjectReference Remove="..\qtmsbuild\QtMSBuild.csproj"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | | <PropertyGroup>
|
| | | <ResolveReferencesDependsOn>qmakeFileReader_PreBuild;$(ResolveReferencesDependsOn)</ResolveReferencesDependsOn>
|
| | | </PropertyGroup>
|
| | | </Project> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <ItemGroup>
|
| | | <Filter Include="Generated Files">
|
| | | <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
| | | <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Header Files">
|
| | | <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
| | | <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Header Files">
|
| | | <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
| | | <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Source Files">
|
| | | <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
| | | <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Source Files">
|
| | | <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
| | | <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
| | | </Filter>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ClCompile Include="evalhandler.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="evaluator\ioutils.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="main.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="evaluator\proitems.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="evaluator\qmakebuiltins.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="qmakedataprovider.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="evaluator\qmakeevaluator.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="evaluator\qmakeglobals.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="evaluator\qmakeparser.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ClInclude Include="evalhandler.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\ioutils.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\proitems.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\qmake_global.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="qmakedataprovider.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\qmakeevaluator.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\qmakeevaluator_p.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\qmakeglobals.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | <ClInclude Include="evaluator\qmakeparser.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ResourceCompile Include="qmakefilereader.rc" />
|
| | | </ItemGroup>
|
| | | </Project> |
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qrceditor.h"
|
| | | #include "mainwindow.h"
|
| | |
|
| | | int main(int argc, char *argv[])
|
| | | {
|
| | | QApplication app(argc, argv);
|
| | | MainWindow mw;
|
| | | mw.show();
|
| | | if (argc == 2)
|
| | | mw.openFile(argv[1]);
|
| | | return app.exec();
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "mainwindow.h"
|
| | | #include "qrceditor.h"
|
| | |
|
| | | #include <QAction>
|
| | | #include <QDebug>
|
| | | #include <QFileDialog>
|
| | | #include <QMenuBar>
|
| | | #include <QStatusBar>
|
| | | #include <QVBoxLayout>
|
| | | #include <QMessageBox>
|
| | | #include <QToolBar>
|
| | | #include <QProcess>
|
| | |
|
| | | #include <windows.h>
|
| | | #include <Tlhelp32.h>
|
| | |
|
| | | MainWindow::MainWindow() :
|
| | | m_qrcEditor(new SharedTools::QrcEditor())
|
| | | {
|
| | | m_qrcEditor->setResourceDragEnabled(true);
|
| | | setWindowTitle(tr("Qt Resource Editor"));
|
| | | QMenu* fMenu = menuBar()->addMenu(tr("&File"));
|
| | | QToolBar* tb = new QToolBar("Title", this);
|
| | | tb->setMovable(false);
|
| | | addToolBar(Qt::TopToolBarArea, tb);
|
| | |
|
| | | QAction* oa = fMenu->addAction(tr("&Open..."));
|
| | | oa->setShortcut(tr("Ctrl+O", "File|Open"));
|
| | | oa->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
|
| | | tb->addAction(oa);
|
| | | connect(oa, SIGNAL(triggered()), this, SLOT(slotOpen()));
|
| | |
|
| | | QAction* sa = fMenu->addAction(tr("&Save"));
|
| | | sa->setShortcut(tr("Ctrl+S", "File|Save"));
|
| | | sa->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
|
| | | tb->addAction(sa);
|
| | | connect(sa, SIGNAL(triggered()), this, SLOT(slotSave()));
|
| | |
|
| | | fMenu->addSeparator();
|
| | |
|
| | | QAction* xa = fMenu->addAction(tr("E&xit"));
|
| | | xa->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
|
| | | connect(xa, SIGNAL(triggered()), this, SLOT(close()));
|
| | |
|
| | | QMenu* hMenu = menuBar()->addMenu(tr("&Help"));
|
| | | QAction* actionAbout = hMenu->addAction(tr("&About"));
|
| | | connect(actionAbout, SIGNAL(triggered()), this, SLOT(slotAbout()));
|
| | |
|
| | | QAction* actionAboutQt = hMenu->addAction(tr("A&bout Qt"));
|
| | | connect(actionAboutQt, SIGNAL(triggered()), this, SLOT(slotAboutQt()));
|
| | |
|
| | | QWidget *cw = new QWidget();
|
| | | setCentralWidget(cw);
|
| | | QVBoxLayout *lt = new QVBoxLayout(cw);
|
| | | lt->addWidget(m_qrcEditor);
|
| | | setMinimumSize(QSize(500, 500));
|
| | | }
|
| | |
|
| | | void MainWindow::openFile(QString fileName)
|
| | | {
|
| | | if (fileName.isEmpty())
|
| | | return;
|
| | |
|
| | | if (m_qrcEditor->isDirty()) {
|
| | | int ret = fileChangedDialog();
|
| | | switch (ret) {
|
| | | case QMessageBox::Yes:
|
| | | slotSave();
|
| | | case QMessageBox::No:
|
| | | break;
|
| | | default:
|
| | | return;
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | if (m_qrcEditor->load(fileName)) {
|
| | | statusBar()->showMessage(tr("%1 opened").arg(fileName));
|
| | | QFileInfo fi(fileName);
|
| | | setWindowTitle(tr("Qt Resource Editor") + " - " + fi.fileName());
|
| | | }
|
| | | else
|
| | | statusBar()->showMessage(tr("Unable to open %1.").arg(fileName));
|
| | | }
|
| | |
|
| | | void MainWindow::slotOpen()
|
| | | {
|
| | | const QString fileName = QFileDialog::getOpenFileName(this, tr("Choose Resource File"),
|
| | | QString(),
|
| | | tr("Resource files (*.qrc)"));
|
| | | this->openFile(fileName);
|
| | | }
|
| | |
|
| | | void MainWindow::slotSave()
|
| | | {
|
| | | const QString oldFileName = m_qrcEditor->fileName();
|
| | | QString fileName = oldFileName;
|
| | |
|
| | | if (fileName.isEmpty()) {
|
| | | fileName = QFileDialog::getSaveFileName(this, tr("Save Resource File"),
|
| | | QString(),
|
| | | tr("Resource files (*.qrc)"));
|
| | | if (fileName.isEmpty())
|
| | | return;
|
| | | }
|
| | |
|
| | | m_qrcEditor->setFileName(fileName);
|
| | | if (m_qrcEditor->save()) {
|
| | | statusBar()->showMessage(tr("%1 written").arg(fileName));
|
| | | } else {
|
| | | statusBar()->showMessage(tr("Unable to write %1.").arg(fileName));
|
| | | m_qrcEditor->setFileName(oldFileName);
|
| | | }
|
| | | }
|
| | |
|
| | | void MainWindow::slotAbout()
|
| | | {
|
| | | QMessageBox::about(this, tr("About Qt Resource Editor"),
|
| | | tr("Qt Resource Editor") + "\n\n" + tr("Copyright (C) 2016 The Qt Company Ltd."));
|
| | | }
|
| | |
|
| | | void MainWindow::slotAboutQt()
|
| | | {
|
| | | QMessageBox::aboutQt(this);
|
| | | }
|
| | |
|
| | | void MainWindow::closeEvent(QCloseEvent *e)
|
| | | {
|
| | | if (m_qrcEditor->isDirty()) {
|
| | | int ret = fileChangedDialog();
|
| | | switch (ret) {
|
| | | case QMessageBox::Yes:
|
| | | slotSave();
|
| | | case QMessageBox::No:
|
| | | QMainWindow::close();
|
| | | break;
|
| | | default:
|
| | | e->ignore();
|
| | | return;
|
| | | break;
|
| | | }
|
| | | }
|
| | | e->accept();
|
| | | }
|
| | |
|
| | | int MainWindow::fileChangedDialog()
|
| | | {
|
| | | QMessageBox message(this);
|
| | | message.setText(tr("The .qrc file has been modified."));
|
| | | message.setWindowTitle("Qt Resource Editor");
|
| | | message.setInformativeText(tr("Do you want to save the changes?"));
|
| | | message.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
| | | message.setDefaultButton(QMessageBox::Yes);
|
| | | return message.exec();
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef MAINWINDOW_H
|
| | | #define MAINWINDOW_H
|
| | |
|
| | | #include <QMainWindow>
|
| | | #include <QString>
|
| | | #include <QCloseEvent>
|
| | |
|
| | | namespace SharedTools {
|
| | | class QrcEditor;
|
| | | }
|
| | |
|
| | | class MainWindow : public QMainWindow
|
| | | {
|
| | | Q_OBJECT
|
| | |
|
| | | public:
|
| | | MainWindow();
|
| | | void openFile(QString fileName);
|
| | |
|
| | | protected:
|
| | | void closeEvent(QCloseEvent *e);
|
| | |
|
| | | private slots:
|
| | | void slotOpen();
|
| | | void slotSave();
|
| | | void slotAbout();
|
| | | void slotAboutQt();
|
| | |
|
| | | private:
|
| | | int fileChangedDialog();
|
| | |
|
| | | private:
|
| | | SharedTools::QrcEditor *m_qrcEditor;
|
| | | QString m_devenvPIDArg;
|
| | | };
|
| | |
|
| | | #endif // MAINWINDOW_H
|
New file |
| | |
| | | IDI_ICON1 ICON DISCARDABLE "qrceditor.ico"
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <ItemGroup Label="ProjectConfigurations">
|
| | | <ProjectConfiguration Include="Debug|Win32">
|
| | | <Configuration>Debug</Configuration>
|
| | | <Platform>Win32</Platform>
|
| | | </ProjectConfiguration>
|
| | | <ProjectConfiguration Include="Release|Win32">
|
| | | <Configuration>Release</Configuration>
|
| | | <Platform>Win32</Platform>
|
| | | </ProjectConfiguration>
|
| | | <ProjectConfiguration Include="Debug|x64">
|
| | | <Configuration>Debug</Configuration>
|
| | | <Platform>x64</Platform>
|
| | | </ProjectConfiguration>
|
| | | <ProjectConfiguration Include="Release|x64">
|
| | | <Configuration>Release</Configuration>
|
| | | <Platform>x64</Platform>
|
| | | </ProjectConfiguration>
|
| | | </ItemGroup>
|
| | | <PropertyGroup Label="Globals">
|
| | | <ProjectGuid>{4CEE73C9-FCFA-3A72-A0A3-036BDBB3240F}</ProjectGuid>
|
| | | <Keyword>QtVS_v303</Keyword>
|
| | | <RootNamespace>QrcEditor</RootNamespace>
|
| | | <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='15.0'">10.0.17763.0</WindowsTargetPlatformVersion>
|
| | | <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='16.0'">10.0</WindowsTargetPlatformVersion>
|
| | | <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='17.0'">10.0</WindowsTargetPlatformVersion>
|
| | | <QtMsBuild>$(SolutionDir)\qtmsbuild\QtMsBuild</QtMsBuild>
|
| | | </PropertyGroup>
|
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
| | | <PropertyGroup>
|
| | | <PlatformToolset Condition="'$(VisualStudioVersion)'=='15.0'">v141</PlatformToolset>
|
| | | <PlatformToolset Condition="'$(VisualStudioVersion)'=='16.0'">v142</PlatformToolset>
|
| | | <PlatformToolset Condition="'$(VisualStudioVersion)'=='17.0'">v143</PlatformToolset>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="Configuration">
|
| | | <ConfigurationType>Application</ConfigurationType>
|
| | | <OutDir>bin\$(VisualStudioVersion)\$(Platform)\$(Configuration)\</OutDir>
|
| | | <IntDir>obj\$(VisualStudioVersion)\$(Platform)\$(Configuration)\</IntDir>
|
| | | </PropertyGroup>
|
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
| | | <ImportGroup Label="ExtensionSettings" />
|
| | | <ImportGroup Label="PropertySheets">
|
| | | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
| | | <Import Project="..\QtCppConfig.props" />
|
| | | </ImportGroup>
|
| | | <PropertyGroup Label="UserMacros" />
|
| | | <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
| | | <Import Project="$(QtMsBuild)\qt_defaults.props" />
|
| | | </ImportGroup>
|
| | | <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
| | | <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
| | | </Target>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
| | | <QtModules>core;xml;gui;widgets</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
| | | <QtModules>core;xml;gui;widgets</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
| | | <QtModules>core;xml;gui;widgets</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
| | | <QtModules>core;xml;gui;widgets</QtModules>
|
| | | <QtInstall>$(QtBuild)</QtInstall>
|
| | | </PropertyGroup>
|
| | | <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
|
| | | <Import Project="$(QtMsBuild)\qt.props" />
|
| | | </ImportGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
| | | <ClCompile>
|
| | | <Optimization>Disabled</Optimization>
|
| | | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
| | | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Windows</SubSystem>
|
| | | <OutputFile>$(OutDir)\QrcEditor.exe</OutputFile>
|
| | | <GenerateDebugInformation>true</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
| | | <ClCompile>
|
| | | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DebugInformationFormat>None</DebugInformationFormat>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <Optimization>MaxSpeed</Optimization>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <ProgramDataBaseFileName>
|
| | | </ProgramDataBaseFileName>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Windows</SubSystem>
|
| | | <OutputFile>$(OutDir)\QrcEditor.exe</OutputFile>
|
| | | <GenerateDebugInformation>false</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <LinkIncremental>false</LinkIncremental>
|
| | | <OptimizeReferences>true</OptimizeReferences>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
| | | <ClCompile>
|
| | | <Optimization>Disabled</Optimization>
|
| | | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
| | | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Windows</SubSystem>
|
| | | <OutputFile>$(OutDir)\QrcEditor.exe</OutputFile>
|
| | | <GenerateDebugInformation>true</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
| | | <ClCompile>
|
| | | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
| | | <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
| | | <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <MultiProcessorCompilation>true</MultiProcessorCompilation>
|
| | | <AdditionalIncludeDirectories>shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
| | | <BrowseInformation>false</BrowseInformation>
|
| | | <DebugInformationFormat>None</DebugInformationFormat>
|
| | | <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
| | | <ExceptionHandling>Sync</ExceptionHandling>
|
| | | <Optimization>MaxSpeed</Optimization>
|
| | | <PreprocessToFile>false</PreprocessToFile>
|
| | | <ProgramDataBaseFileName>
|
| | | </ProgramDataBaseFileName>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | <WarningLevel>Level3</WarningLevel>
|
| | | </ClCompile>
|
| | | <Link>
|
| | | <SubSystem>Windows</SubSystem>
|
| | | <OutputFile>$(OutDir)\QrcEditor.exe</OutputFile>
|
| | | <GenerateDebugInformation>false</GenerateDebugInformation>
|
| | | <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
| | | <DataExecutionPrevention>true</DataExecutionPrevention>
|
| | | <IgnoreImportLibrary>true</IgnoreImportLibrary>
|
| | | <LinkIncremental>false</LinkIncremental>
|
| | | <OptimizeReferences>true</OptimizeReferences>
|
| | | <RandomizedBaseAddress>true</RandomizedBaseAddress>
|
| | | <SuppressStartupBanner>true</SuppressStartupBanner>
|
| | | </Link>
|
| | | <PostBuildEvent>
|
| | | <Command>copy $(TargetPath) bin</Command>
|
| | | </PostBuildEvent>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemGroup>
|
| | | <ClCompile Include="main.cpp" />
|
| | | <ClCompile Include="mainwindow.cpp" />
|
| | | <ClCompile Include="shared\qrceditor.cpp" />
|
| | | <ClCompile Include="shared\resourcefile.cpp" />
|
| | | <ClCompile Include="shared\resourceview.cpp" />
|
| | | <ClCompile Include="shared\undocommands.cpp" />
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <QtMoc Include="mainwindow.h" />
|
| | | <QtMoc Include="shared\qrceditor.h" />
|
| | | <QtMoc Include="shared\resourcefile_p.h" />
|
| | | <QtMoc Include="shared\resourceview.h" />
|
| | | <ClInclude Include="shared\undocommands_p.h" />
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <QtUic Include="shared\qrceditor.ui" />
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ResourceCompile Include="qrceditor.rc" />
|
| | | </ItemGroup>
|
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
| | | <Import Project="$(SolutionDir)\transform.targets" />
|
| | | <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
| | | <Import Project="$(QtMsBuild)\qt.targets" />
|
| | | </ImportGroup>
|
| | | <ImportGroup Label="ExtensionTargets" />
|
| | | <ItemGroup>
|
| | | <ProjectReference Include="..\qtmsbuild\QtMSBuild.csproj">
|
| | | <Project>{A618D28B-9352-44F4-AA71-609BF68BF871}</Project>
|
| | | </ProjectReference>
|
| | | </ItemGroup>
|
| | | <Target Name="QRCEditor_PreBuild">
|
| | | <ItemGroup>
|
| | | <ProjectReference Remove="..\qtmsbuild\QtMSBuild.csproj"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | | <PropertyGroup>
|
| | | <ResolveReferencesDependsOn>QRCEditor_PreBuild;$(ResolveReferencesDependsOn)</ResolveReferencesDependsOn>
|
| | | </PropertyGroup>
|
| | | </Project> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <ItemGroup>
|
| | | <Filter Include="Form Files">
|
| | | <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
| | | <Extensions>ui</Extensions>
|
| | | <ParseFiles>false</ParseFiles>
|
| | | </Filter>
|
| | | <Filter Include="Form Files">
|
| | | <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
| | | <Extensions>ui</Extensions>
|
| | | <ParseFiles>false</ParseFiles>
|
| | | </Filter>
|
| | | <Filter Include="Generated Files">
|
| | | <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
| | | <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Header Files">
|
| | | <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
| | | <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Header Files">
|
| | | <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
| | | <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Source Files">
|
| | | <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
| | | <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
| | | </Filter>
|
| | | <Filter Include="Source Files">
|
| | | <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
| | | <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
| | | </Filter>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ClCompile Include="main.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="mainwindow.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="shared\qrceditor.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="shared\resourcefile.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="shared\resourceview.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | <ClCompile Include="shared\undocommands.cpp">
|
| | | <Filter>Source Files</Filter>
|
| | | </ClCompile>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <QtMoc Include="mainwindow.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </QtMoc>
|
| | | <QtMoc Include="shared\qrceditor.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </QtMoc>
|
| | | <QtMoc Include="shared\resourcefile_p.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </QtMoc>
|
| | | <QtMoc Include="shared\resourceview.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </QtMoc>
|
| | | <ClInclude Include="shared\undocommands_p.h">
|
| | | <Filter>Header Files</Filter>
|
| | | </ClInclude>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <QtUic Include="shared\qrceditor.ui">
|
| | | <Filter>Form Files</Filter>
|
| | | </QtUic>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <ResourceCompile Include="qrceditor.rc" />
|
| | | </ItemGroup>
|
| | | </Project> |
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "qrceditor.h"
|
| | | #include "undocommands_p.h"
|
| | |
|
| | | #include <QtCore/QDebug>
|
| | | #include <QtWidgets/QMenu>
|
| | | #include <QtWidgets/QFileDialog>
|
| | | #include <QtWidgets/QMessageBox>
|
| | |
|
| | | using namespace SharedTools;
|
| | |
|
| | | QrcEditor::QrcEditor(QWidget *parent)
|
| | | : QWidget(parent),
|
| | | m_treeview(new ResourceView(&m_history)),
|
| | | m_addFileAction(0)
|
| | | {
|
| | | m_ui.setupUi(this);
|
| | | QHBoxLayout *layout = new QHBoxLayout;
|
| | | layout->setSpacing(0);
|
| | | layout->setMargin(0);
|
| | | m_ui.centralWidget->setLayout(layout);
|
| | |
|
| | | m_treeview->enableContextMenu(false);
|
| | | layout->addWidget(m_treeview);
|
| | | connect(m_ui.removeButton, SIGNAL(clicked()), this, SLOT(onRemove()));
|
| | |
|
| | | // 'Add' button with menu
|
| | | QMenu *addMenu = new QMenu(this);
|
| | | m_addFileAction = addMenu->addAction(tr("Add Files"), this, SLOT(onAddFiles()));
|
| | | addMenu->addAction(tr("Add Prefix"), this, SLOT(onAddPrefix()));
|
| | | m_ui.addButton->setMenu(addMenu);
|
| | |
|
| | | connect(m_treeview, SIGNAL(addPrefixTriggered()), this, SLOT(onAddPrefix()));
|
| | | connect(m_treeview, SIGNAL(addFilesTriggered(QString)), this, SLOT(onAddFiles()));
|
| | | connect(m_treeview, SIGNAL(removeItem()), this, SLOT(onRemove()));
|
| | | connect(m_treeview, SIGNAL(currentIndexChanged()), this, SLOT(updateCurrent()));
|
| | | connect(m_treeview, SIGNAL(dirtyChanged(bool)), this, SIGNAL(dirtyChanged(bool)));
|
| | | m_treeview->setFocus();
|
| | |
|
| | | connect(m_ui.aliasText, SIGNAL(textEdited(QString)),
|
| | | this, SLOT(onAliasChanged(QString)));
|
| | | connect(m_ui.prefixText, SIGNAL(textEdited(QString)),
|
| | | this, SLOT(onPrefixChanged(QString)));
|
| | | connect(m_ui.languageText, SIGNAL(textEdited(QString)),
|
| | | this, SLOT(onLanguageChanged(QString)));
|
| | |
|
| | | // Prevent undo command merging after a switch of focus:
|
| | | // (0) The initial text is "Green".
|
| | | // (1) The user appends " is a color." --> text is "Green is a color."
|
| | | // (2) The user clicks into some other line edit --> loss of focus
|
| | | // (3) The user gives focuse again and substitutes "Green" with "Red"
|
| | | // --> text now is "Red is a color."
|
| | | // (4) The user hits undo --> text now is "Green is a color."
|
| | | // Without calling advanceMergeId() it would have been "Green", instead.
|
| | | connect(m_ui.aliasText, SIGNAL(editingFinished()),
|
| | | m_treeview, SLOT(advanceMergeId()));
|
| | | connect(m_ui.prefixText, SIGNAL(editingFinished()),
|
| | | m_treeview, SLOT(advanceMergeId()));
|
| | | connect(m_ui.languageText, SIGNAL(editingFinished()),
|
| | | m_treeview, SLOT(advanceMergeId()));
|
| | |
|
| | | connect(m_treeview, SIGNAL(addFilesTriggered(const QString&)),
|
| | | this, SIGNAL(addFilesTriggered(const QString&)));
|
| | |
|
| | | connect(&m_history, SIGNAL(canRedoChanged(bool)), this, SLOT(updateHistoryControls()));
|
| | | connect(&m_history, SIGNAL(canUndoChanged(bool)), this, SLOT(updateHistoryControls()));
|
| | | updateHistoryControls();
|
| | | updateCurrent();
|
| | | }
|
| | |
|
| | | QrcEditor::~QrcEditor()
|
| | | {
|
| | | }
|
| | |
|
| | | QString QrcEditor::fileName() const
|
| | | {
|
| | | return m_treeview->fileName();
|
| | | }
|
| | |
|
| | | void QrcEditor::setFileName(const QString &fileName)
|
| | | {
|
| | | m_treeview->setFileName(fileName);
|
| | | }
|
| | |
|
| | | bool QrcEditor::load(const QString &fileName)
|
| | | {
|
| | | const bool success = m_treeview->load(fileName);
|
| | | if (success) {
|
| | | // Set "focus"
|
| | | m_treeview->setCurrentIndex(m_treeview->model()->index(0,0));
|
| | |
|
| | | // Expand prefix nodes
|
| | | m_treeview->expandAll();
|
| | | }
|
| | | return success;
|
| | | }
|
| | |
|
| | | bool QrcEditor::save()
|
| | | {
|
| | | return m_treeview->save();
|
| | | }
|
| | |
|
| | | bool QrcEditor::isDirty()
|
| | | {
|
| | | return m_treeview->isDirty();
|
| | | }
|
| | |
|
| | | void QrcEditor::setDirty(bool dirty)
|
| | | {
|
| | | m_treeview->setDirty(dirty);
|
| | | }
|
| | |
|
| | | // Propagates a change of selection in the tree
|
| | | // to the alias/prefix/language edit controls
|
| | | void QrcEditor::updateCurrent()
|
| | | {
|
| | | const bool isValid = m_treeview->currentIndex().isValid();
|
| | | const bool isPrefix = m_treeview->isPrefix(m_treeview->currentIndex()) && isValid;
|
| | | const bool isFile = !isPrefix && isValid;
|
| | |
|
| | | m_ui.aliasLabel->setEnabled(isFile);
|
| | | m_ui.aliasText->setEnabled(isFile);
|
| | | m_currentAlias = m_treeview->currentAlias();
|
| | | m_ui.aliasText->setText(m_currentAlias);
|
| | |
|
| | | m_ui.prefixLabel->setEnabled(isPrefix);
|
| | | m_ui.prefixText->setEnabled(isPrefix);
|
| | | m_currentPrefix = m_treeview->currentPrefix();
|
| | | m_ui.prefixText->setText(m_currentPrefix);
|
| | |
|
| | | m_ui.languageLabel->setEnabled(isPrefix);
|
| | | m_ui.languageText->setEnabled(isPrefix);
|
| | | m_currentLanguage = m_treeview->currentLanguage();
|
| | | m_ui.languageText->setText(m_currentLanguage);
|
| | |
|
| | | m_ui.urlLabel->setEnabled(isFile);
|
| | | m_ui.urlText->setEnabled(isFile);
|
| | | if (isFile) {
|
| | | QString url = QLatin1String(":");
|
| | | url += m_currentPrefix;
|
| | | if (!url.endsWith(QLatin1Char('/')))
|
| | | url += QLatin1Char('/');
|
| | | if (m_currentAlias.isEmpty())
|
| | | url += m_treeview->currentIndex().data().toString();
|
| | | else
|
| | | url += m_currentAlias;
|
| | | m_ui.urlText->setText(url);
|
| | | } else {
|
| | | m_ui.urlText->clear();
|
| | | }
|
| | |
|
| | | m_ui.addButton->setEnabled(true);
|
| | | m_addFileAction->setEnabled(isValid);
|
| | | m_ui.removeButton->setEnabled(isValid);
|
| | | }
|
| | |
|
| | | void QrcEditor::updateHistoryControls()
|
| | | {
|
| | | emit undoStackChanged(m_history.canUndo(), m_history.canRedo());
|
| | | }
|
| | |
|
| | | void QrcEditor::resolveLocationIssues(QStringList &files)
|
| | | {
|
| | | const QDir dir = QFileInfo(m_treeview->fileName()).absoluteDir();
|
| | | const QString dotdotSlash = QLatin1String("../");
|
| | | int i = 0;
|
| | | int count = files.count();
|
| | | int initialCount = files.count();
|
| | |
|
| | | // Find first troublesome file
|
| | | for (; i < count; i++) {
|
| | | QString const &file = files.at(i);
|
| | | const QString relativePath = dir.relativeFilePath(file);
|
| | | if (relativePath.startsWith(dotdotSlash))
|
| | | break;
|
| | | }
|
| | |
|
| | | // All paths fine -> no interaction needed
|
| | | if (i == count) {
|
| | | return;
|
| | | }
|
| | |
|
| | | // Interact with user from now on
|
| | | bool abort = false;
|
| | | for (; i < count; i++) {
|
| | | // Path fine -> skip file
|
| | | QString const &file = files.at(i);
|
| | | QString const relativePath = dir.relativeFilePath(file);
|
| | | if (!relativePath.startsWith(dotdotSlash)) {
|
| | | continue;
|
| | | }
|
| | |
|
| | | // Path troublesome and aborted -> remove file
|
| | | if (abort) {
|
| | | files.removeAt(i);
|
| | | count--;
|
| | | i--;
|
| | | continue;
|
| | | } else {
|
| | | // Path troublesome -> query user
|
| | | QMessageBox message(this);
|
| | | message.setWindowTitle(tr("Invalid File Location"));
|
| | | message.setIcon(QMessageBox::Warning);
|
| | | QPushButton * const copyButton = message.addButton(tr("Copy"), QMessageBox::ActionRole);
|
| | | QPushButton * skipButton = NULL;
|
| | | if (initialCount > 1)
|
| | | {
|
| | | skipButton = message.addButton(tr("Skip"), QMessageBox::DestructiveRole);
|
| | | message.setEscapeButton(skipButton);
|
| | | }
|
| | | QPushButton * const abortButton = message.addButton(tr("Abort"), QMessageBox::RejectRole);
|
| | | message.setDefaultButton(copyButton);
|
| | | message.setText(tr("The file %1 is not in a subdirectory of the resource file. You now have the option to copy this file to a valid location.")
|
| | | .arg(QDir::toNativeSeparators(file)));
|
| | | message.exec();
|
| | | if (message.clickedButton() == skipButton) {
|
| | | files.removeAt(i);
|
| | | count--;
|
| | | i--; // Compensate i++
|
| | | } else if (message.clickedButton() == copyButton) {
|
| | | const QFileInfo fi(file);
|
| | | QFileInfo suggestion;
|
| | | QDir tmpTarget(dir.path() + QString(QDir::separator()) + QString("Resources"));;
|
| | | if (tmpTarget.exists())
|
| | | suggestion.setFile(tmpTarget, fi.fileName());
|
| | | else
|
| | | suggestion.setFile(dir, fi.fileName());
|
| | | const QString copyName = QFileDialog::getSaveFileName(this, tr("Choose copy location"),
|
| | | suggestion.absoluteFilePath());
|
| | | if (!copyName.isEmpty()) {
|
| | | QString relPath = dir.relativeFilePath(copyName);
|
| | | if (relPath.startsWith(dotdotSlash)) { // directory is still invalid
|
| | | i--; // Compensate i++ and try again
|
| | | continue;
|
| | | }
|
| | | if (QFile::exists(copyName)) {
|
| | | if (!QFile::remove(copyName)) {
|
| | | QMessageBox::critical(this, tr("Overwrite Failed"),
|
| | | tr("Could not overwrite file %1.")
|
| | | .arg(QDir::toNativeSeparators(copyName)));
|
| | | // Remove file
|
| | | files.removeAt(i);
|
| | | count--;
|
| | | i--; // Compensate i++
|
| | | continue;
|
| | | }
|
| | | }
|
| | | if (!QFile::copy(file, copyName)) {
|
| | | QMessageBox::critical(this, tr("Copying Failed"),
|
| | | tr("Could not copy the file to %1.")
|
| | | .arg(QDir::toNativeSeparators(copyName)));
|
| | | // Remove file
|
| | | files.removeAt(i);
|
| | | count--;
|
| | | i--; // Compensate i++
|
| | | continue;
|
| | | }
|
| | | files[i] = copyName;
|
| | | } else {
|
| | | // Remove file
|
| | | files.removeAt(i);
|
| | | count--;
|
| | | i--; // Compensate i++
|
| | | }
|
| | | } else if (message.clickedButton() == abortButton) {
|
| | | abort = true;
|
| | |
|
| | | files.removeAt(i);
|
| | | count--;
|
| | | i--; // Compensate i++
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | void QrcEditor::setResourceDragEnabled(bool e)
|
| | | {
|
| | | m_treeview->setResourceDragEnabled(e);
|
| | | }
|
| | |
|
| | | bool QrcEditor::resourceDragEnabled() const
|
| | | {
|
| | | return m_treeview->resourceDragEnabled();
|
| | | }
|
| | |
|
| | | void QrcEditor::setDefaultAddFileEnabled(bool enable)
|
| | | {
|
| | | m_treeview->setDefaultAddFileEnabled(enable);
|
| | | }
|
| | |
|
| | | bool QrcEditor::defaultAddFileEnabled() const
|
| | | {
|
| | | return m_treeview->defaultAddFileEnabled();
|
| | | }
|
| | |
|
| | | void QrcEditor::addFile(const QString &prefix, const QString &file)
|
| | | {
|
| | | // TODO: make this function UNDO / REDO aware
|
| | | m_treeview->addFile(prefix, file);
|
| | | }
|
| | |
|
| | | /*
|
| | | void QrcEditor::removeFile(const QString &prefix, const QString &file)
|
| | | {
|
| | | m_treeview->removeFile(prefix, file);
|
| | | }
|
| | | */
|
| | | // Slot for change of line edit content 'alias'
|
| | | void QrcEditor::onAliasChanged(const QString &alias)
|
| | | {
|
| | | const QString &before = m_currentAlias;
|
| | | const QString &after = alias;
|
| | | m_treeview->setCurrentAlias(before, after);
|
| | | m_currentAlias = alias;
|
| | | updateCurrent();
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for change of line edit content 'prefix'
|
| | | void QrcEditor::onPrefixChanged(const QString &prefix)
|
| | | {
|
| | | const QString &before = m_currentPrefix;
|
| | | const QString &after = prefix;
|
| | | m_treeview->setCurrentPrefix(before, after);
|
| | | m_currentPrefix = prefix;
|
| | | updateCurrent();
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for change of line edit content 'language'
|
| | | void QrcEditor::onLanguageChanged(const QString &language)
|
| | | {
|
| | | const QString &before = m_currentLanguage;
|
| | | const QString &after = language;
|
| | | m_treeview->setCurrentLanguage(before, after);
|
| | | m_currentLanguage = language;
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for 'Remove' button
|
| | | void QrcEditor::onRemove()
|
| | | {
|
| | | // Find current item, push and execute command
|
| | | const QModelIndex current = m_treeview->currentIndex();
|
| | | int afterDeletionArrayIndex = current.row();
|
| | | QModelIndex afterDeletionParent = current.parent();
|
| | | m_treeview->findSamePlacePostDeletionModelIndex(afterDeletionArrayIndex, afterDeletionParent);
|
| | | QUndoCommand * const removeCommand = new RemoveEntryCommand(m_treeview, current);
|
| | | m_history.push(removeCommand);
|
| | | const QModelIndex afterDeletionModelIndex
|
| | | = m_treeview->model()->index(afterDeletionArrayIndex, 0, afterDeletionParent);
|
| | | m_treeview->setCurrentIndex(afterDeletionModelIndex);
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for 'Add File' button
|
| | | void QrcEditor::onAddFiles()
|
| | | {
|
| | | QModelIndex const current = m_treeview->currentIndex();
|
| | | int const currentIsPrefixNode = m_treeview->isPrefix(current);
|
| | | int const prefixArrayIndex = currentIsPrefixNode ? current.row()
|
| | | : m_treeview->model()->parent(current).row();
|
| | | int const cursorFileArrayIndex = currentIsPrefixNode ? 0 : current.row();
|
| | | QStringList fileNames = m_treeview->fileNamesToAdd();
|
| | | resolveLocationIssues(fileNames);
|
| | | if (fileNames.isEmpty())
|
| | | return;
|
| | | QUndoCommand * const addFilesCommand = new AddFilesCommand(
|
| | | m_treeview, prefixArrayIndex, cursorFileArrayIndex, fileNames);
|
| | | m_history.push(addFilesCommand);
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for 'Add Prefix' button
|
| | | void QrcEditor::onAddPrefix()
|
| | | {
|
| | | QUndoCommand * const addEmptyPrefixCommand = new AddEmptyPrefixCommand(m_treeview);
|
| | | m_history.push(addEmptyPrefixCommand);
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for 'Undo' button
|
| | | void QrcEditor::onUndo()
|
| | | {
|
| | | m_history.undo();
|
| | | updateCurrent();
|
| | | updateHistoryControls();
|
| | | }
|
| | |
|
| | | // Slot for 'Redo' button
|
| | | void QrcEditor::onRedo()
|
| | | {
|
| | | m_history.redo();
|
| | | updateCurrent();
|
| | | updateHistoryControls();
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef QRCEDITOR_H
|
| | | #define QRCEDITOR_H
|
| | |
|
| | | #include "ui_qrceditor.h"
|
| | | #include "resourceview.h"
|
| | |
|
| | | #include <QtWidgets/QWidget>
|
| | | #include <QtWidgets/QUndoStack>
|
| | |
|
| | | namespace SharedTools {
|
| | |
|
| | | class QrcEditor : public QWidget
|
| | | {
|
| | | Q_OBJECT
|
| | |
|
| | | public:
|
| | | QrcEditor(QWidget *parent = 0);
|
| | | virtual ~QrcEditor();
|
| | |
|
| | | bool load(const QString &fileName);
|
| | | bool save();
|
| | |
|
| | | bool isDirty();
|
| | | void setDirty(bool dirty);
|
| | |
|
| | | QString fileName() const;
|
| | | void setFileName(const QString &fileName);
|
| | |
|
| | | void setResourceDragEnabled(bool e);
|
| | | bool resourceDragEnabled() const;
|
| | |
|
| | | void setDefaultAddFileEnabled(bool enable);
|
| | | bool defaultAddFileEnabled() const;
|
| | |
|
| | | void addFile(const QString &prefix, const QString &file);
|
| | | // void removeFile(const QString &prefix, const QString &file);
|
| | |
|
| | | signals:
|
| | | void dirtyChanged(bool dirty);
|
| | | void addFilesTriggered(const QString &prefix);
|
| | |
|
| | | private slots:
|
| | | void updateCurrent();
|
| | | void updateHistoryControls();
|
| | |
|
| | | private:
|
| | | void resolveLocationIssues(QStringList &files);
|
| | |
|
| | | private slots:
|
| | | void onAliasChanged(const QString &alias);
|
| | | void onPrefixChanged(const QString &prefix);
|
| | | void onLanguageChanged(const QString &language);
|
| | | void onRemove();
|
| | | void onAddFiles();
|
| | | void onAddPrefix();
|
| | |
|
| | | signals:
|
| | | void undoStackChanged(bool canUndo, bool canRedo);
|
| | |
|
| | | public slots:
|
| | | void onUndo();
|
| | | void onRedo();
|
| | |
|
| | | private:
|
| | | Ui::QrcEditor m_ui;
|
| | | QUndoStack m_history;
|
| | | ResourceView *m_treeview;
|
| | | QAction *m_addFileAction;
|
| | |
|
| | | QString m_currentAlias;
|
| | | QString m_currentPrefix;
|
| | | QString m_currentLanguage;
|
| | | };
|
| | |
|
| | | }
|
| | |
|
| | | #endif
|
New file |
| | |
| | | INCLUDEPATH *= $$PWD
|
| | | DEPENDPATH *= $$PWD
|
| | |
|
| | | QT *= xml
|
| | |
|
| | | # Input
|
| | | SOURCES += \
|
| | | $$PWD/resourcefile.cpp \
|
| | | $$PWD/resourceview.cpp \
|
| | | $$PWD/qrceditor.cpp \
|
| | | $$PWD/undocommands.cpp
|
| | |
|
| | | HEADERS += \
|
| | | $$PWD/resourcefile_p.h \
|
| | | $$PWD/resourceview.h \
|
| | | $$PWD/qrceditor.h \
|
| | | $$PWD/undocommands_p.h
|
| | |
|
| | | FORMS += $$PWD/qrceditor.ui
|
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?>
|
| | | <ui version="4.0">
|
| | | <class>QrcEditor</class>
|
| | | <widget class="QWidget" name="QrcEditor">
|
| | | <property name="geometry">
|
| | | <rect>
|
| | | <x>0</x>
|
| | | <y>0</y>
|
| | | <width>491</width>
|
| | | <height>381</height>
|
| | | </rect>
|
| | | </property>
|
| | | <layout class="QVBoxLayout" name="verticalLayout_2">
|
| | | <property name="margin">
|
| | | <number>6</number>
|
| | | </property>
|
| | | <item>
|
| | | <widget class="QWidget" name="centralWidget" native="true">
|
| | | <property name="sizePolicy">
|
| | | <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
| | | <horstretch>0</horstretch>
|
| | | <verstretch>0</verstretch>
|
| | | </sizepolicy>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item>
|
| | | <layout class="QHBoxLayout" name="horizontalLayout">
|
| | | <item>
|
| | | <widget class="QPushButton" name="addButton">
|
| | | <property name="sizePolicy">
|
| | | <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
| | | <horstretch>0</horstretch>
|
| | | <verstretch>0</verstretch>
|
| | | </sizepolicy>
|
| | | </property>
|
| | | <property name="text">
|
| | | <string>Add</string>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item>
|
| | | <widget class="QPushButton" name="removeButton">
|
| | | <property name="text">
|
| | | <string>Remove</string>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item>
|
| | | <spacer name="horizontalSpacer">
|
| | | <property name="orientation">
|
| | | <enum>Qt::Horizontal</enum>
|
| | | </property>
|
| | | <property name="sizeHint" stdset="0">
|
| | | <size>
|
| | | <width>40</width>
|
| | | <height>20</height>
|
| | | </size>
|
| | | </property>
|
| | | </spacer>
|
| | | </item>
|
| | | </layout>
|
| | | </item>
|
| | | <item>
|
| | | <widget class="QGroupBox" name="groupBox">
|
| | | <property name="title">
|
| | | <string>Properties</string>
|
| | | </property>
|
| | | <layout class="QFormLayout" name="formLayout">
|
| | | <property name="sizeConstraint">
|
| | | <enum>QLayout::SetMinAndMaxSize</enum>
|
| | | </property>
|
| | | <property name="fieldGrowthPolicy">
|
| | | <enum>QFormLayout::ExpandingFieldsGrow</enum>
|
| | | </property>
|
| | | <item row="0" column="0">
|
| | | <widget class="QLabel" name="aliasLabel">
|
| | | <property name="text">
|
| | | <string>Alias:</string>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item row="0" column="1">
|
| | | <widget class="QLineEdit" name="aliasText"/>
|
| | | </item>
|
| | | <item row="1" column="0">
|
| | | <widget class="QLabel" name="prefixLabel">
|
| | | <property name="text">
|
| | | <string>Prefix:</string>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item row="1" column="1">
|
| | | <widget class="QLineEdit" name="prefixText"/>
|
| | | </item>
|
| | | <item row="2" column="0">
|
| | | <widget class="QLabel" name="languageLabel">
|
| | | <property name="text">
|
| | | <string>Language:</string>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item row="2" column="1">
|
| | | <widget class="QLineEdit" name="languageText"/>
|
| | | </item>
|
| | | <item row="3" column="0">
|
| | | <widget class="QLabel" name="urlLabel">
|
| | | <property name="text">
|
| | | <string>Resource URL:</string>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | <item row="3" column="1">
|
| | | <widget class="QLineEdit" name="urlText">
|
| | | <property name="readOnly">
|
| | | <bool>true</bool>
|
| | | </property>
|
| | | </widget>
|
| | | </item>
|
| | | </layout>
|
| | | </widget>
|
| | | </item>
|
| | | </layout>
|
| | | </widget>
|
| | | <resources/>
|
| | | <connections/>
|
| | | </ui>
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "resourcefile_p.h"
|
| | |
|
| | | #include <QCoreApplication>
|
| | | #include <QDebug>
|
| | | #include <QDir>
|
| | | #include <QFile>
|
| | | #include <QMimeData>
|
| | | #include <QtAlgorithms>
|
| | | #include <QTextStream>
|
| | |
|
| | | #include <QIcon>
|
| | | #include <QImageReader>
|
| | |
|
| | | #include <QDomDocument>
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | |
|
| | | /*
|
| | | TRANSLATOR qdesigner_internal::ResourceModel
|
| | | */
|
| | |
|
| | | static QString msgFileNameEmpty()
|
| | | {
|
| | | return QCoreApplication::translate("Designer", "The file name is empty.");
|
| | | }
|
| | |
|
| | | namespace qdesigner_internal {
|
| | |
|
| | |
|
| | | /******************************************************************************
|
| | | ** FileList
|
| | | */
|
| | |
|
| | | bool FileList::containsFile(File *file)
|
| | | {
|
| | | foreach (const File *tmpFile, *this)
|
| | | if (tmpFile->name == file->name && tmpFile->prefix() == file->prefix())
|
| | | return true;
|
| | | return false;
|
| | | }
|
| | |
|
| | | /******************************************************************************
|
| | | ** ResourceFile
|
| | | */
|
| | |
|
| | | ResourceFile::ResourceFile(const QString &file_name)
|
| | | {
|
| | | setFileName(file_name);
|
| | | }
|
| | |
|
| | | ResourceFile::~ResourceFile()
|
| | | {
|
| | | clearPrefixList();
|
| | | }
|
| | |
|
| | | bool ResourceFile::load()
|
| | | {
|
| | | m_error_message.clear();
|
| | |
|
| | | if (m_file_name.isEmpty()) {
|
| | | m_error_message = msgFileNameEmpty();
|
| | | return false;
|
| | | }
|
| | |
|
| | | QFile file(m_file_name);
|
| | | if (!file.open(QIODevice::ReadOnly)) {
|
| | | m_error_message = file.errorString();
|
| | | return false;
|
| | | }
|
| | |
|
| | | clearPrefixList();
|
| | |
|
| | | QDomDocument doc;
|
| | |
|
| | | QString error_msg;
|
| | | int error_line, error_col;
|
| | | if (!doc.setContent(&file, &error_msg, &error_line, &error_col)) {
|
| | | m_error_message = QCoreApplication::translate("Designer", "XML error on line %1, col %2: %3")
|
| | | .arg(error_line).arg(error_col).arg(error_msg);
|
| | | return false;
|
| | | }
|
| | |
|
| | | QDomElement root = doc.firstChildElement(QLatin1String("RCC"));
|
| | | if (root.isNull()) {
|
| | | m_error_message = QCoreApplication::translate("Designer", "The <RCC> root element is missing.");
|
| | | return false;
|
| | | }
|
| | |
|
| | | QDomElement relt = root.firstChildElement(QLatin1String("qresource"));
|
| | | for (; !relt.isNull(); relt = relt.nextSiblingElement(QLatin1String("qresource"))) {
|
| | |
|
| | | QString prefix = fixPrefix(relt.attribute(QLatin1String("prefix")));
|
| | | if (prefix.isEmpty())
|
| | | prefix = QString(QLatin1Char('/'));
|
| | | const QString language = relt.attribute(QLatin1String("lang"));
|
| | |
|
| | | const int idx = indexOfPrefix(prefix);
|
| | | Prefix * p = 0;
|
| | | if (idx == -1) {
|
| | | p = new Prefix(prefix, language);
|
| | | m_prefix_list.append(p);
|
| | | } else {
|
| | | p = m_prefix_list[idx];
|
| | | }
|
| | | Q_ASSERT(p);
|
| | |
|
| | | QDomElement felt = relt.firstChildElement(QLatin1String("file"));
|
| | | for (; !felt.isNull(); felt = felt.nextSiblingElement(QLatin1String("file"))) {
|
| | | const QString fileName = absolutePath(felt.text());
|
| | | const QString alias = felt.attribute(QLatin1String("alias"));
|
| | | File * const file = new File(p, fileName, alias);
|
| | | p->file_list.append(file);
|
| | | }
|
| | | }
|
| | |
|
| | | return true;
|
| | | }
|
| | |
|
| | | bool ResourceFile::save()
|
| | | {
|
| | | m_error_message.clear();
|
| | |
|
| | | if (m_file_name.isEmpty()) {
|
| | | m_error_message = msgFileNameEmpty();
|
| | | return false;
|
| | | }
|
| | |
|
| | | QFile file(m_file_name);
|
| | | if (!file.open(QIODevice::WriteOnly)) {
|
| | | m_error_message = file.errorString();
|
| | | return false;
|
| | | }
|
| | |
|
| | | QDomDocument doc;
|
| | | QDomElement root = doc.createElement(QLatin1String("RCC"));
|
| | | doc.appendChild(root);
|
| | |
|
| | | const QStringList name_list = prefixList();
|
| | |
|
| | | foreach (const QString &name, name_list) {
|
| | | FileList file_list;
|
| | | QString lang;
|
| | | foreach (const Prefix *pref, m_prefix_list) {
|
| | | if (pref->name == name){
|
| | | file_list += pref->file_list;
|
| | | lang = pref->lang;
|
| | | }
|
| | | }
|
| | |
|
| | | QDomElement relt = doc.createElement(QLatin1String("qresource"));
|
| | | root.appendChild(relt);
|
| | | relt.setAttribute(QLatin1String("prefix"), name);
|
| | | if (!lang.isEmpty())
|
| | | relt.setAttribute(QLatin1String("lang"), lang);
|
| | |
|
| | | foreach (const File *f, file_list) {
|
| | | const File &file = *f;
|
| | | QDomElement felt = doc.createElement(QLatin1String("file"));
|
| | | relt.appendChild(felt);
|
| | | const QString conv_file = relativePath(file.name).replace(QDir::separator(), QLatin1Char('/'));
|
| | | const QDomText text = doc.createTextNode(conv_file);
|
| | | felt.appendChild(text);
|
| | | if (!file.alias.isEmpty())
|
| | | felt.setAttribute(QLatin1String("alias"), file.alias);
|
| | | }
|
| | | }
|
| | |
|
| | | QTextStream stream(&file);
|
| | | doc.save(stream, 4);
|
| | |
|
| | | return true;
|
| | | }
|
| | |
|
| | | bool ResourceFile::split(const QString &_path, QString *prefix, QString *file) const
|
| | | {
|
| | | prefix->clear();
|
| | | file->clear();
|
| | |
|
| | | QString path = _path;
|
| | | if (!path.startsWith(QLatin1Char(':')))
|
| | | return false;
|
| | | path = path.mid(1);
|
| | |
|
| | | for (int i = 0; i < m_prefix_list.size(); ++i) {
|
| | | Prefix const * const &pref = m_prefix_list.at(i);
|
| | | if (!path.startsWith(pref->name))
|
| | | continue;
|
| | |
|
| | | *prefix = pref->name;
|
| | | if (pref->name == QString(QLatin1Char('/')))
|
| | | *file = path.mid(1);
|
| | | else
|
| | | *file = path.mid(pref->name.size() + 1);
|
| | |
|
| | | const QString filePath = absolutePath(*file);
|
| | |
|
| | | for (int j = 0; j < pref->file_list.count(); j++) {
|
| | | File const * const &f = pref->file_list.at(j);
|
| | | if (!f->alias.isEmpty()) {
|
| | | if (absolutePath(f->alias) == filePath) {
|
| | | *file = f->name;
|
| | | return true;
|
| | | }
|
| | | } else if (f->name == filePath)
|
| | | return true;
|
| | | }
|
| | | }
|
| | |
|
| | | return false;
|
| | | }
|
| | |
|
| | | QString ResourceFile::resolvePath(const QString &path) const
|
| | | {
|
| | | QString prefix, file;
|
| | | if (split(path, &prefix, &file))
|
| | | return absolutePath(file);
|
| | |
|
| | | return QString();
|
| | | }
|
| | |
|
| | | QStringList ResourceFile::prefixList() const
|
| | | {
|
| | | QStringList result;
|
| | | for (int i = 0; i < m_prefix_list.size(); ++i)
|
| | | result.append(m_prefix_list.at(i)->name);
|
| | | return result;
|
| | | }
|
| | |
|
| | | bool ResourceFile::isEmpty() const
|
| | | {
|
| | | return m_file_name.isEmpty() && m_prefix_list.isEmpty();
|
| | | }
|
| | |
|
| | | QStringList ResourceFile::fileList(int pref_idx) const
|
| | | {
|
| | | QStringList result;
|
| | | Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
|
| | | const FileList &abs_file_list = m_prefix_list.at(pref_idx)->file_list;
|
| | | foreach (const File *abs_file, abs_file_list)
|
| | | result.append(relativePath(abs_file->name));
|
| | | return result;
|
| | | }
|
| | |
|
| | | void ResourceFile::addFile(int prefix_idx, const QString &file, int file_idx)
|
| | | {
|
| | | Prefix * const p = m_prefix_list[prefix_idx];
|
| | | Q_ASSERT(p);
|
| | | FileList &files = p->file_list;
|
| | | Q_ASSERT(file_idx >= -1 && file_idx <= files.size());
|
| | | if (file_idx == -1)
|
| | | file_idx = files.size();
|
| | | files.insert(file_idx, new File(p, absolutePath(file)));
|
| | | }
|
| | |
|
| | | void ResourceFile::addPrefix(const QString &prefix, int prefix_idx)
|
| | | {
|
| | | QString fixed_prefix = fixPrefix(prefix);
|
| | | if (indexOfPrefix(fixed_prefix) != -1)
|
| | | return;
|
| | |
|
| | | Q_ASSERT(prefix_idx >= -1 && prefix_idx <= m_prefix_list.size());
|
| | | if (prefix_idx == -1)
|
| | | prefix_idx = m_prefix_list.size();
|
| | | m_prefix_list.insert(prefix_idx, new Prefix(fixed_prefix));
|
| | | }
|
| | |
|
| | | void ResourceFile::removePrefix(int prefix_idx)
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | Prefix * const p = m_prefix_list.at(prefix_idx);
|
| | | delete p;
|
| | | m_prefix_list.removeAt(prefix_idx);
|
| | | }
|
| | |
|
| | | void ResourceFile::removeFile(int prefix_idx, int file_idx)
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | FileList &fileList = m_prefix_list[prefix_idx]->file_list;
|
| | | Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
|
| | | delete fileList.at(file_idx);
|
| | | fileList.removeAt(file_idx);
|
| | | }
|
| | |
|
| | | void ResourceFile::replacePrefix(int prefix_idx, const QString &prefix)
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | m_prefix_list[prefix_idx]->name = fixPrefix(prefix);
|
| | | }
|
| | |
|
| | | void ResourceFile::replaceLang(int prefix_idx, const QString &lang)
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | m_prefix_list[prefix_idx]->lang = lang;
|
| | | }
|
| | |
|
| | | void ResourceFile::replaceAlias(int prefix_idx, int file_idx, const QString &alias)
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | FileList &fileList = m_prefix_list.at(prefix_idx)->file_list;
|
| | | Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
|
| | | fileList[file_idx]->alias = alias;
|
| | | }
|
| | |
|
| | |
|
| | | void ResourceFile::replaceFile(int pref_idx, int file_idx, const QString &file)
|
| | | {
|
| | | Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
|
| | | FileList &fileList = m_prefix_list.at(pref_idx)->file_list;
|
| | | Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
|
| | | fileList[file_idx]->name = file;
|
| | | }
|
| | |
|
| | | int ResourceFile::indexOfPrefix(const QString &prefix) const
|
| | | {
|
| | | QString fixed_prefix = fixPrefix(prefix);
|
| | | for (int i = 0; i < m_prefix_list.size(); ++i) {
|
| | | if (m_prefix_list.at(i)->name == fixed_prefix)
|
| | | return i;
|
| | | }
|
| | | return -1;
|
| | | }
|
| | |
|
| | | int ResourceFile::indexOfFile(int pref_idx, const QString &file) const
|
| | | {
|
| | | Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
|
| | | Prefix * const p = m_prefix_list.at(pref_idx);
|
| | | File equalFile(p, absolutePath(file));
|
| | | return p->file_list.indexOf(&equalFile);
|
| | | }
|
| | |
|
| | | QString ResourceFile::relativePath(const QString &abs_path) const
|
| | | {
|
| | | if (m_file_name.isEmpty() || QFileInfo(abs_path).isRelative())
|
| | | return abs_path;
|
| | |
|
| | | QFileInfo fileInfo(m_file_name);
|
| | | return fileInfo.absoluteDir().relativeFilePath(abs_path);
|
| | | }
|
| | |
|
| | | QString ResourceFile::absolutePath(const QString &rel_path) const
|
| | | {
|
| | | const QFileInfo fi(rel_path);
|
| | | if (fi.isAbsolute())
|
| | | return rel_path;
|
| | |
|
| | | QString rc = QFileInfo(m_file_name).path();
|
| | | rc += QDir::separator();
|
| | | rc += rel_path;
|
| | | return QDir::cleanPath(rc);
|
| | | }
|
| | |
|
| | | bool ResourceFile::contains(const QString &prefix, const QString &file) const
|
| | | {
|
| | | int pref_idx = indexOfPrefix(prefix);
|
| | | if (pref_idx == -1)
|
| | | return false;
|
| | | if (file.isEmpty())
|
| | | return true;
|
| | | Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
|
| | | Prefix * const p = m_prefix_list.at(pref_idx);
|
| | | Q_ASSERT(p);
|
| | | File equalFile(p, absolutePath(file));
|
| | | return p->file_list.containsFile(&equalFile);
|
| | | }
|
| | |
|
| | | bool ResourceFile::contains(int pref_idx, const QString &file) const
|
| | | {
|
| | | Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
|
| | | Prefix * const p = m_prefix_list.at(pref_idx);
|
| | | File equalFile(p, absolutePath(file));
|
| | | return p->file_list.containsFile(&equalFile);
|
| | | }
|
| | |
|
| | | /*static*/ QString ResourceFile::fixPrefix(const QString &prefix)
|
| | | {
|
| | | const QChar slash = QLatin1Char('/');
|
| | | QString result = QString(slash);
|
| | | for (int i = 0; i < prefix.size(); ++i) {
|
| | | const QChar c = prefix.at(i);
|
| | | if (c == slash && result.at(result.size() - 1) == slash)
|
| | | continue;
|
| | | result.append(c);
|
| | | }
|
| | |
|
| | | if (result.size() > 1 && result.endsWith(slash))
|
| | | result = result.mid(0, result.size() - 1);
|
| | |
|
| | | return result;
|
| | | }
|
| | |
|
| | | int ResourceFile::prefixCount() const
|
| | | {
|
| | | return m_prefix_list.size();
|
| | | }
|
| | |
|
| | | QString ResourceFile::prefix(int idx) const
|
| | | {
|
| | | Q_ASSERT((idx >= 0) && (idx < m_prefix_list.count()));
|
| | | return m_prefix_list.at(idx)->name;
|
| | | }
|
| | |
|
| | | QString ResourceFile::lang(int idx) const
|
| | | {
|
| | | Q_ASSERT(idx >= 0 && idx < m_prefix_list.count());
|
| | | return m_prefix_list.at(idx)->lang;
|
| | | }
|
| | |
|
| | | int ResourceFile::fileCount(int prefix_idx) const
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | return m_prefix_list.at(prefix_idx)->file_list.size();
|
| | | }
|
| | |
|
| | | QString ResourceFile::file(int prefix_idx, int file_idx) const
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | FileList &fileList = m_prefix_list.at(prefix_idx)->file_list;
|
| | | Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
|
| | | return fileList.at(file_idx)->name;
|
| | | }
|
| | |
|
| | | QString ResourceFile::alias(int prefix_idx, int file_idx) const
|
| | | {
|
| | | Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
|
| | | FileList &fileList = m_prefix_list.at(prefix_idx)->file_list;
|
| | | Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
|
| | | return fileList.at(file_idx)->alias;
|
| | | }
|
| | |
|
| | | void * ResourceFile::prefixPointer(int prefixIndex) const
|
| | | {
|
| | | Q_ASSERT(prefixIndex >= 0 && prefixIndex < m_prefix_list.count());
|
| | | return m_prefix_list.at(prefixIndex);
|
| | | }
|
| | |
|
| | | void * ResourceFile::filePointer(int prefixIndex, int fileIndex) const
|
| | | {
|
| | | Q_ASSERT(prefixIndex >= 0 && prefixIndex < m_prefix_list.count());
|
| | | FileList &fileList = m_prefix_list.at(prefixIndex)->file_list;
|
| | | Q_ASSERT(fileIndex >= 0 && fileIndex < fileList.count());
|
| | | return fileList.at(fileIndex);
|
| | | }
|
| | |
|
| | | int ResourceFile::prefixPointerIndex(const Prefix *prefix) const
|
| | | {
|
| | | int const count = m_prefix_list.count();
|
| | | for (int i = 0; i < count; i++) {
|
| | | Prefix * const other = m_prefix_list.at(i);
|
| | | if (*other == *prefix)
|
| | | return i;
|
| | | }
|
| | | return -1;
|
| | | }
|
| | |
|
| | | void ResourceFile::clearPrefixList()
|
| | | {
|
| | | qDeleteAll(m_prefix_list);
|
| | | m_prefix_list.clear();
|
| | | }
|
| | |
|
| | | /******************************************************************************
|
| | | ** ResourceModel
|
| | | */
|
| | |
|
| | | ResourceModel::ResourceModel(const ResourceFile &resource_file, QObject *parent)
|
| | | : QAbstractItemModel(parent), m_resource_file(resource_file), m_dirty(false)
|
| | | {
|
| | | }
|
| | |
|
| | | void ResourceModel::setDirty(bool b)
|
| | | {
|
| | | if (b == m_dirty)
|
| | | return;
|
| | |
|
| | | m_dirty = b;
|
| | | emit dirtyChanged(b);
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::index(int row, int column, const QModelIndex &parent) const
|
| | | {
|
| | | if (column != 0)
|
| | | return QModelIndex();
|
| | |
|
| | | void * internalPointer = 0;
|
| | | if (parent.isValid()) {
|
| | | void * const pip = parent.internalPointer();
|
| | | if (pip == 0)
|
| | | return QModelIndex();
|
| | |
|
| | | // File node
|
| | | Node * const node = reinterpret_cast<Node *>(pip);
|
| | | Prefix * const prefix = node->prefix();
|
| | | Q_ASSERT(prefix);
|
| | | if (row < 0 || row >= prefix->file_list.count())
|
| | | return QModelIndex();
|
| | | const int prefixIndex = m_resource_file.prefixPointerIndex(prefix);
|
| | | const int fileIndex = row;
|
| | | internalPointer = m_resource_file.filePointer(prefixIndex, fileIndex);
|
| | | } else {
|
| | | // Prefix node
|
| | | if (row < 0 || row >= m_resource_file.prefixCount())
|
| | | return QModelIndex();
|
| | | internalPointer = m_resource_file.prefixPointer(row);
|
| | | }
|
| | | Q_ASSERT(internalPointer);
|
| | | return createIndex(row, 0, internalPointer);
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::parent(const QModelIndex &index) const
|
| | | {
|
| | | if (!index.isValid())
|
| | | return QModelIndex();
|
| | |
|
| | | void * const internalPointer = index.internalPointer();
|
| | | if (internalPointer == 0)
|
| | | return QModelIndex();
|
| | | Node * const node = reinterpret_cast<Node *>(internalPointer);
|
| | | Prefix * const prefix = node->prefix();
|
| | | Q_ASSERT(prefix);
|
| | | bool const isFileNode = (prefix != node);
|
| | |
|
| | | if (isFileNode) {
|
| | | const int row = m_resource_file.prefixPointerIndex(prefix);
|
| | | Q_ASSERT(row >= 0);
|
| | | return createIndex(row, 0, prefix);
|
| | | } else {
|
| | | return QModelIndex();
|
| | | }
|
| | | }
|
| | |
|
| | | int ResourceModel::rowCount(const QModelIndex &parent) const
|
| | | {
|
| | | if (parent.isValid()) {
|
| | | void * const internalPointer = parent.internalPointer();
|
| | | Node * const node = reinterpret_cast<Node *>(internalPointer);
|
| | | Prefix * const prefix = node->prefix();
|
| | | Q_ASSERT(prefix);
|
| | | bool const isFileNode = (prefix != node);
|
| | |
|
| | | if (isFileNode) {
|
| | | return 0;
|
| | | } else {
|
| | | return prefix->file_list.count();
|
| | | }
|
| | | } else {
|
| | | return m_resource_file.prefixCount();
|
| | | }
|
| | | }
|
| | |
|
| | | int ResourceModel::columnCount(const QModelIndex &) const
|
| | | {
|
| | | return 1;
|
| | | }
|
| | |
|
| | | bool ResourceModel::hasChildren(const QModelIndex &parent) const
|
| | | {
|
| | | return rowCount(parent) != 0;
|
| | | }
|
| | |
|
| | | Qt::DropActions ResourceModel::supportedDropActions() const
|
| | | {
|
| | | // Only action that works for QListWidget and the like.
|
| | | return Qt::CopyAction;
|
| | | }
|
| | |
|
| | | bool ResourceModel::iconFileExtension(const QString &path)
|
| | | {
|
| | | static QStringList ext_list;
|
| | | if (ext_list.isEmpty()) {
|
| | | const QList<QByteArray> _ext_list = QImageReader::supportedImageFormats();
|
| | | foreach (const QByteArray &ext, _ext_list) {
|
| | | QString dotExt = QString(QLatin1Char('.'));
|
| | | dotExt += QString::fromLocal8Bit(ext);
|
| | | ext_list.append(dotExt);
|
| | | }
|
| | | }
|
| | |
|
| | | foreach (const QString &ext, ext_list) {
|
| | | if (path.endsWith(ext, Qt::CaseInsensitive))
|
| | | return true;
|
| | | }
|
| | |
|
| | | return false;
|
| | | }
|
| | |
|
| | | static inline void appendParenthesized(const QString &what, QString &s)
|
| | | {
|
| | | s += QLatin1String(" (");
|
| | | s += what;
|
| | | s += QLatin1Char(')');
|
| | | }
|
| | |
|
| | | QVariant ResourceModel::data(const QModelIndex &index, int role) const
|
| | | {
|
| | | if (!index.isValid())
|
| | | return QVariant();
|
| | |
|
| | | const void *internalPointer = index.internalPointer();
|
| | | const Node *node = reinterpret_cast<const Node *>(internalPointer);
|
| | | const Prefix *prefix = node->prefix();
|
| | | File *file = node->file();
|
| | | Q_ASSERT(prefix);
|
| | | const bool isFileNode = (prefix != node);
|
| | |
|
| | | QVariant result;
|
| | |
|
| | | switch (role) {
|
| | | case Qt::DisplayRole:
|
| | | {
|
| | | QString stringRes;
|
| | | if (!isFileNode) {
|
| | | // Prefix node
|
| | | stringRes = prefix->name;
|
| | | const QString &lang = prefix->lang;
|
| | | if (!lang.isEmpty())
|
| | | appendParenthesized(lang, stringRes);
|
| | | } else {
|
| | | // File node
|
| | | Q_ASSERT(file);
|
| | | QString conv_file = m_resource_file.relativePath(file->name);
|
| | | stringRes = conv_file.replace(QDir::separator(), QLatin1Char('/'));
|
| | | const QString alias = file->alias;
|
| | | if (!alias.isEmpty())
|
| | | appendParenthesized(alias, stringRes);
|
| | | }
|
| | | result = stringRes;
|
| | | }
|
| | | break;
|
| | | case Qt::DecorationRole:
|
| | | if (isFileNode) {
|
| | | // File node
|
| | | Q_ASSERT(file);
|
| | | if (file->icon.isNull()) {
|
| | | const QString path = m_resource_file.absolutePath(file->name);
|
| | | if (iconFileExtension(path))
|
| | | file->icon = QIcon(path);
|
| | | }
|
| | | if (!file->icon.isNull())
|
| | | result = file->icon;
|
| | | }
|
| | | break;
|
| | | default:
|
| | | break;
|
| | | }
|
| | | return result;
|
| | | }
|
| | |
|
| | | void ResourceModel::getItem(const QModelIndex &index, QString &prefix, QString &file) const
|
| | | {
|
| | | prefix.clear();
|
| | | file.clear();
|
| | |
|
| | | if (!index.isValid())
|
| | | return;
|
| | |
|
| | | const void *internalPointer = index.internalPointer();
|
| | | const Node *node = reinterpret_cast<const Node *>(internalPointer);
|
| | | const Prefix *p = node->prefix();
|
| | | Q_ASSERT(p);
|
| | | const bool isFileNode = (p != node);
|
| | |
|
| | | if (isFileNode) {
|
| | | const File *f = node->file();
|
| | | Q_ASSERT(f);
|
| | | if (!f->alias.isEmpty())
|
| | | file = f->alias;
|
| | | else
|
| | | file = f->name;
|
| | | } else {
|
| | | prefix = p->name;
|
| | | }
|
| | | }
|
| | |
|
| | | QString ResourceModel::lang(const QModelIndex &index) const
|
| | | {
|
| | | if (!index.isValid())
|
| | | return QString();
|
| | |
|
| | | return m_resource_file.lang(index.row());
|
| | | }
|
| | |
|
| | | QString ResourceModel::alias(const QModelIndex &index) const
|
| | | {
|
| | | if (!index.isValid() || !index.parent().isValid())
|
| | | return QString();
|
| | | return m_resource_file.alias(index.parent().row(), index.row());
|
| | | }
|
| | |
|
| | | QString ResourceModel::file(const QModelIndex &index) const
|
| | | {
|
| | | if (!index.isValid() || !index.parent().isValid())
|
| | | return QString();
|
| | | return m_resource_file.file(index.parent().row(), index.row());
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::getIndex(const QString &prefixed_file)
|
| | | {
|
| | | QString prefix, file;
|
| | | if (!m_resource_file.split(prefixed_file, &prefix, &file))
|
| | | return QModelIndex();
|
| | | return getIndex(prefix, file);
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::getIndex(const QString &prefix, const QString &file)
|
| | | {
|
| | | if (prefix.isEmpty())
|
| | | return QModelIndex();
|
| | |
|
| | | const int pref_idx = m_resource_file.indexOfPrefix(prefix);
|
| | | if (pref_idx == -1)
|
| | | return QModelIndex();
|
| | |
|
| | | const QModelIndex pref_model_idx = index(pref_idx, 0, QModelIndex());
|
| | | if (file.isEmpty())
|
| | | return pref_model_idx;
|
| | |
|
| | | const int file_idx = m_resource_file.indexOfFile(pref_idx, file);
|
| | | if (file_idx == -1)
|
| | | return QModelIndex();
|
| | |
|
| | | return index(file_idx, 0, pref_model_idx);
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::prefixIndex(const QModelIndex &sel_idx) const
|
| | | {
|
| | | if (!sel_idx.isValid())
|
| | | return QModelIndex();
|
| | | const QModelIndex parentIndex = parent(sel_idx);
|
| | | return parentIndex.isValid() ? parentIndex : sel_idx;
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::addNewPrefix()
|
| | | {
|
| | | const QString format = QLatin1String("/new/prefix%1");
|
| | | int i = 1;
|
| | | QString prefix = format.arg(i);
|
| | | for ( ; m_resource_file.contains(prefix); i++)
|
| | | prefix = format.arg(i);
|
| | |
|
| | | i = rowCount(QModelIndex());
|
| | | beginInsertRows(QModelIndex(), i, i);
|
| | | m_resource_file.addPrefix(prefix);
|
| | | endInsertRows();
|
| | |
|
| | | setDirty(true);
|
| | |
|
| | | return index(i, 0, QModelIndex());
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::addFiles(const QModelIndex &model_idx, const QStringList &file_list)
|
| | | {
|
| | | const QModelIndex prefixModelIndex = prefixIndex(model_idx);
|
| | | const int prefixArrayIndex = prefixModelIndex.row();
|
| | | const int cursorFileArrayIndex = (prefixModelIndex == model_idx) ? 0 : model_idx.row();
|
| | | int dummy;
|
| | | int lastFileArrayIndex;
|
| | | addFiles(prefixArrayIndex, file_list, cursorFileArrayIndex, dummy, lastFileArrayIndex);
|
| | | return index(lastFileArrayIndex, 0, prefixModelIndex);
|
| | | }
|
| | |
|
| | | void ResourceModel::addFiles(int prefixIndex, const QStringList &fileNames, int cursorFile,
|
| | | int &firstFile, int &lastFile)
|
| | | {
|
| | | Q_UNUSED(cursorFile)
|
| | | const QModelIndex prefix_model_idx = index(prefixIndex, 0, QModelIndex());
|
| | | const QStringList &file_list = fileNames;
|
| | | firstFile = -1;
|
| | | lastFile = -1;
|
| | |
|
| | | if (!prefix_model_idx.isValid()) {
|
| | | return;
|
| | | }
|
| | | const int prefix_idx = prefixIndex;
|
| | |
|
| | | QStringList unique_list;
|
| | | foreach (const QString &file, file_list) {
|
| | | if (!m_resource_file.contains(prefix_idx, file) && !unique_list.contains(file))
|
| | | unique_list.append(file);
|
| | | }
|
| | |
|
| | | if (unique_list.isEmpty()) {
|
| | | return;
|
| | | }
|
| | | const int cnt = m_resource_file.fileCount(prefix_idx);
|
| | | beginInsertRows(prefix_model_idx, cnt, cnt + unique_list.count() - 1); // ### FIXME
|
| | |
|
| | | foreach (const QString &file, unique_list)
|
| | | m_resource_file.addFile(prefix_idx, file);
|
| | |
|
| | | const QFileInfo fi(file_list.last());
|
| | | m_lastResourceDir = fi.absolutePath();
|
| | |
|
| | | endInsertRows();
|
| | | setDirty(true);
|
| | |
|
| | | firstFile = cnt;
|
| | | lastFile = cnt + unique_list.count() - 1;
|
| | | }
|
| | |
|
| | |
|
| | | void ResourceModel::insertPrefix(int prefixIndex, const QString &prefix,
|
| | | const QString &lang)
|
| | | {
|
| | | beginInsertRows(QModelIndex(), prefixIndex, prefixIndex);
|
| | | m_resource_file.addPrefix(prefix, prefixIndex);
|
| | | m_resource_file.replaceLang(prefixIndex, lang);
|
| | | endInsertRows();
|
| | | setDirty(true);
|
| | | }
|
| | |
|
| | | void ResourceModel::insertFile(int prefixIndex, int fileIndex,
|
| | | const QString &fileName, const QString &alias)
|
| | | {
|
| | | const QModelIndex parent = index(prefixIndex, 0, QModelIndex());
|
| | | beginInsertRows(parent, fileIndex, fileIndex);
|
| | | m_resource_file.addFile(prefixIndex, fileName, fileIndex);
|
| | | m_resource_file.replaceAlias(prefixIndex, fileIndex, alias);
|
| | | endInsertRows();
|
| | | setDirty(true);
|
| | | }
|
| | |
|
| | | void ResourceModel::changePrefix(const QModelIndex &model_idx, const QString &prefix)
|
| | | {
|
| | | if (!model_idx.isValid())
|
| | | return;
|
| | |
|
| | | const QModelIndex prefix_model_idx = prefixIndex(model_idx);
|
| | | const int prefix_idx = model_idx.row();
|
| | | if (m_resource_file.prefix(prefix_idx) == ResourceFile::fixPrefix(prefix))
|
| | | return;
|
| | |
|
| | | if (m_resource_file.contains(prefix))
|
| | | return;
|
| | |
|
| | | m_resource_file.replacePrefix(prefix_idx, prefix);
|
| | | emit dataChanged(prefix_model_idx, prefix_model_idx);
|
| | | setDirty(true);
|
| | | }
|
| | |
|
| | | void ResourceModel::changeLang(const QModelIndex &model_idx, const QString &lang)
|
| | | {
|
| | | if (!model_idx.isValid())
|
| | | return;
|
| | |
|
| | | const QModelIndex prefix_model_idx = prefixIndex(model_idx);
|
| | | const int prefix_idx = model_idx.row();
|
| | | if (m_resource_file.lang(prefix_idx) == lang)
|
| | | return;
|
| | |
|
| | | m_resource_file.replaceLang(prefix_idx, lang);
|
| | | emit dataChanged(prefix_model_idx, prefix_model_idx);
|
| | | setDirty(true);
|
| | | }
|
| | |
|
| | | void ResourceModel::changeAlias(const QModelIndex &index, const QString &alias)
|
| | | {
|
| | | if (!index.parent().isValid())
|
| | | return;
|
| | |
|
| | | if (m_resource_file.alias(index.parent().row(), index.row()) == alias)
|
| | | return;
|
| | | m_resource_file.replaceAlias(index.parent().row(), index.row(), alias);
|
| | | emit dataChanged(index, index);
|
| | | setDirty(true);
|
| | | }
|
| | |
|
| | | QModelIndex ResourceModel::deleteItem(const QModelIndex &idx)
|
| | | {
|
| | | if (!idx.isValid())
|
| | | return QModelIndex();
|
| | |
|
| | | QString dummy, file;
|
| | | getItem(idx, dummy, file);
|
| | | int prefix_idx = -1;
|
| | | int file_idx = -1;
|
| | |
|
| | | beginRemoveRows(parent(idx), idx.row(), idx.row());
|
| | | if (file.isEmpty()) {
|
| | | // Remove prefix
|
| | | prefix_idx = idx.row();
|
| | | m_resource_file.removePrefix(prefix_idx);
|
| | | if (prefix_idx == m_resource_file.prefixCount())
|
| | | --prefix_idx;
|
| | | } else {
|
| | | // Remove file
|
| | | prefix_idx = prefixIndex(idx).row();
|
| | | file_idx = idx.row();
|
| | | m_resource_file.removeFile(prefix_idx, file_idx);
|
| | | if (file_idx == m_resource_file.fileCount(prefix_idx))
|
| | | --file_idx;
|
| | | }
|
| | | endRemoveRows();
|
| | |
|
| | | setDirty(true);
|
| | |
|
| | | if (prefix_idx == -1)
|
| | | return QModelIndex();
|
| | | const QModelIndex prefix_model_idx = index(prefix_idx, 0, QModelIndex());
|
| | | if (file_idx == -1)
|
| | | return prefix_model_idx;
|
| | | return index(file_idx, 0, prefix_model_idx);
|
| | | }
|
| | |
|
| | | bool ResourceModel::reload()
|
| | | {
|
| | | beginResetModel();
|
| | | const bool result = m_resource_file.load();
|
| | | if (result)
|
| | | setDirty(false);
|
| | | endResetModel();
|
| | | return result;
|
| | | }
|
| | |
|
| | | bool ResourceModel::save()
|
| | | {
|
| | | const bool result = m_resource_file.save();
|
| | | if (result)
|
| | | setDirty(false);
|
| | | return result;
|
| | | }
|
| | |
|
| | | QString ResourceModel::lastResourceOpenDirectory() const
|
| | | {
|
| | | if (m_lastResourceDir.isEmpty())
|
| | | return absolutePath(QString());
|
| | | return m_lastResourceDir;
|
| | | }
|
| | |
|
| | | // Create a resource path 'prefix:/file'
|
| | | QString ResourceModel::resourcePath(const QString &prefix, const QString &file)
|
| | | {
|
| | | QString rc = QString(QLatin1Char(':'));
|
| | | rc += prefix;
|
| | | rc += QLatin1Char('/');
|
| | | rc += file;
|
| | | return QDir::cleanPath(rc);
|
| | | }
|
| | |
|
| | | QMimeData *ResourceModel::mimeData(const QModelIndexList &indexes) const
|
| | | {
|
| | | if (indexes.size() != 1)
|
| | | return 0;
|
| | |
|
| | | QString prefix, file;
|
| | | getItem(indexes.front(), prefix, file);
|
| | | if (prefix.isEmpty() || file.isEmpty())
|
| | | return 0;
|
| | |
|
| | | // DnD format of Designer 4.4
|
| | | QDomDocument doc;
|
| | | QDomElement elem = doc.createElement(QLatin1String("resource"));
|
| | | elem.setAttribute(QLatin1String("type"), QLatin1String("image"));
|
| | | elem.setAttribute(QLatin1String("file"), resourcePath(prefix, file));
|
| | | doc.appendChild(elem);
|
| | |
|
| | | QMimeData *rc = new QMimeData;
|
| | | rc->setText(doc.toString());
|
| | | return rc;
|
| | | }
|
| | |
|
| | | } // namespace qdesigner_internal
|
| | |
|
| | | QT_END_NAMESPACE
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef RESOURCEFILE_P_H
|
| | | #define RESOURCEFILE_P_H
|
| | |
|
| | | #include <QtCore/QAbstractItemModel>
|
| | | #include <QtCore/QMap>
|
| | | #include <QtCore/QString>
|
| | | #include <QtCore/QStringList>
|
| | | #include <QtGui/QIcon>
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | |
|
| | | namespace qdesigner_internal {
|
| | |
|
| | | struct File;
|
| | | struct Prefix;
|
| | |
|
| | | /*!
|
| | | \class Node
|
| | |
|
| | | Forms the base class for nodes in a \l ResourceFile tree.
|
| | | */
|
| | | class Node
|
| | | {
|
| | | protected:
|
| | | Node(File *file, Prefix *prefix) : m_file(file), m_prefix(prefix)
|
| | | {
|
| | | Q_ASSERT(m_prefix);
|
| | | }
|
| | | public:
|
| | | File *file() const { return m_file; }
|
| | | Prefix *prefix() const { return m_prefix; }
|
| | | private:
|
| | | File *m_file;
|
| | | Prefix *m_prefix;
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class File
|
| | |
|
| | | Represents a file node in a \l ResourceFile tree.
|
| | | */
|
| | | struct File : public Node {
|
| | | File(Prefix *prefix, const QString &_name = QString(), const QString &_alias = QString())
|
| | | : Node(this, prefix), name(_name), alias(_alias) {}
|
| | | bool operator < (const File &other) const { return name < other.name; }
|
| | | bool operator == (const File &other) const { return name == other.name; }
|
| | | bool operator != (const File &other) const { return name != other.name; }
|
| | | QString name;
|
| | | QString alias;
|
| | | QIcon icon;
|
| | | };
|
| | |
|
| | | class FileList : public QList<File *>
|
| | | {
|
| | | public:
|
| | | bool containsFile(File *file);
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class Prefix
|
| | |
|
| | | Represents a prefix node in a \l ResourceFile tree.
|
| | | */
|
| | | struct Prefix : public Node
|
| | | {
|
| | | Prefix(const QString &_name = QString(), const QString &_lang = QString(), const FileList &_file_list = FileList())
|
| | | : Node(NULL, this), name(_name), lang(_lang), file_list(_file_list) {}
|
| | | ~Prefix()
|
| | | {
|
| | | qDeleteAll(file_list);
|
| | | file_list.clear();
|
| | | }
|
| | | bool operator == (const Prefix &other) const { return (name == other.name) && (lang == other.lang); }
|
| | | QString name;
|
| | | QString lang;
|
| | | FileList file_list;
|
| | | };
|
| | | typedef QList<Prefix *> PrefixList;
|
| | |
|
| | | /*!
|
| | | \class ResourceFile
|
| | |
|
| | | Represents the structure of a Qt Resource File (.qrc) file.
|
| | | */
|
| | | class ResourceFile
|
| | | {
|
| | | public:
|
| | | ResourceFile(const QString &file_name = QString());
|
| | | ~ResourceFile();
|
| | |
|
| | | void setFileName(const QString &file_name) { m_file_name = file_name; }
|
| | | QString fileName() const { return m_file_name; }
|
| | | bool load();
|
| | | bool save();
|
| | | QString errorMessage() const { return m_error_message; }
|
| | |
|
| | | private:
|
| | | QString resolvePath(const QString &path) const;
|
| | | QStringList prefixList() const;
|
| | | QStringList fileList(int pref_idx) const;
|
| | |
|
| | | public:
|
| | | int prefixCount() const;
|
| | | QString prefix(int idx) const;
|
| | | QString lang(int idx) const;
|
| | |
|
| | | int fileCount(int prefix_idx) const;
|
| | |
|
| | | QString file(int prefix_idx, int file_idx) const;
|
| | | QString alias(int prefix_idx, int file_idx) const;
|
| | |
|
| | | void addFile(int prefix_idx, const QString &file, int file_idx = -1);
|
| | | void addPrefix(const QString &prefix, int prefix_idx = -1);
|
| | |
|
| | | void removePrefix(int prefix_idx);
|
| | | void removeFile(int prefix_idx, int file_idx);
|
| | |
|
| | | void replacePrefix(int prefix_idx, const QString &prefix);
|
| | | void replaceLang(int prefix_idx, const QString &lang);
|
| | | void replaceAlias(int prefix_idx, int file_idx, const QString &alias);
|
| | |
|
| | | private:
|
| | | void replaceFile(int pref_idx, int file_idx, const QString &file);
|
| | | public:
|
| | | int indexOfPrefix(const QString &prefix) const;
|
| | | int indexOfFile(int pref_idx, const QString &file) const;
|
| | |
|
| | | bool contains(const QString &prefix, const QString &file = QString()) const;
|
| | | bool contains(int pref_idx, const QString &file) const;
|
| | |
|
| | | QString relativePath(const QString &abs_path) const;
|
| | | QString absolutePath(const QString &rel_path) const;
|
| | |
|
| | | static QString fixPrefix(const QString &prefix);
|
| | | bool split(const QString &path, QString *prefix, QString *file) const;
|
| | |
|
| | | private:
|
| | | bool isEmpty() const;
|
| | |
|
| | | private:
|
| | | PrefixList m_prefix_list;
|
| | | QString m_file_name;
|
| | | QString m_error_message;
|
| | |
|
| | | public:
|
| | | void * prefixPointer(int prefixIndex) const;
|
| | | void * filePointer(int prefixIndex, int fileIndex) const;
|
| | | int prefixPointerIndex(const Prefix *prefix) const;
|
| | |
|
| | | private:
|
| | | void clearPrefixList();
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class ResourceModel
|
| | |
|
| | | Wraps a \l ResourceFile as a single-column tree model.
|
| | | */
|
| | | class ResourceModel : public QAbstractItemModel
|
| | | {
|
| | | Q_OBJECT
|
| | |
|
| | | public:
|
| | | ResourceModel(const ResourceFile &resource_file, QObject *parent = 0);
|
| | |
|
| | | QModelIndex index(int row, int column,
|
| | | const QModelIndex &parent = QModelIndex()) const;
|
| | | QModelIndex parent(const QModelIndex &index) const;
|
| | | int rowCount(const QModelIndex &parent) const;
|
| | | int columnCount(const QModelIndex &parent) const;
|
| | | bool hasChildren(const QModelIndex &parent) const;
|
| | | Qt::DropActions supportedDropActions() const;
|
| | |
|
| | | protected:
|
| | | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
| | |
|
| | | public:
|
| | | QString fileName() const { return m_resource_file.fileName(); }
|
| | | void setFileName(const QString &file_name) { m_resource_file.setFileName(file_name); }
|
| | | void getItem(const QModelIndex &index, QString &prefix, QString &file) const;
|
| | |
|
| | | QString lang(const QModelIndex &index) const;
|
| | | QString alias(const QModelIndex &index) const;
|
| | | QString file(const QModelIndex &index) const;
|
| | |
|
| | | virtual QModelIndex addNewPrefix();
|
| | | virtual QModelIndex addFiles(const QModelIndex &idx, const QStringList &file_list);
|
| | | void addFiles(int prefixIndex, const QStringList &fileNames, int cursorFile, int &firstFile, int &lastFile);
|
| | | void insertPrefix(int prefixIndex, const QString &prefix, const QString &lang);
|
| | | void insertFile(int prefixIndex, int fileIndex, const QString &fileName, const QString &alias);
|
| | | virtual void changePrefix(const QModelIndex &idx, const QString &prefix);
|
| | | virtual void changeLang(const QModelIndex &idx, const QString &lang);
|
| | | virtual void changeAlias(const QModelIndex &idx, const QString &alias);
|
| | | virtual QModelIndex deleteItem(const QModelIndex &idx);
|
| | | QModelIndex getIndex(const QString &prefix, const QString &file);
|
| | | QModelIndex getIndex(const QString &prefixed_file);
|
| | | QModelIndex prefixIndex(const QModelIndex &sel_idx) const;
|
| | |
|
| | | QString absolutePath(const QString &path) const
|
| | | { return m_resource_file.absolutePath(path); }
|
| | |
|
| | | private:
|
| | | QString relativePath(const QString &path) const
|
| | | { return m_resource_file.relativePath(path); }
|
| | | QString lastResourceOpenDirectory() const;
|
| | |
|
| | | public:
|
| | | virtual bool reload();
|
| | | virtual bool save();
|
| | | // QString errorMessage() const { return m_resource_file.errorMessage(); }
|
| | |
|
| | | bool dirty() const { return m_dirty; }
|
| | | void setDirty(bool b);
|
| | |
|
| | | private:
|
| | | virtual QMimeData *mimeData (const QModelIndexList & indexes) const;
|
| | |
|
| | | static bool iconFileExtension(const QString &path);
|
| | | static QString resourcePath(const QString &prefix, const QString &file);
|
| | |
|
| | | signals:
|
| | | void dirtyChanged(bool b);
|
| | |
|
| | | private:
|
| | | ResourceFile m_resource_file;
|
| | | bool m_dirty;
|
| | | QString m_lastResourceDir;
|
| | | };
|
| | |
|
| | | } // namespace qdesigner_internal
|
| | |
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | #endif // RESOURCEFILE_P_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "resourceview.h"
|
| | |
|
| | | #include "undocommands_p.h"
|
| | |
|
| | | #include <QtCore/QDebug>
|
| | |
|
| | | #include <QtWidgets/QAction>
|
| | | #include <QtWidgets/QApplication>
|
| | | #include <QtWidgets/QFileDialog>
|
| | | #include <QtWidgets/QHeaderView>
|
| | | #include <QtWidgets/QInputDialog>
|
| | | #include <QtWidgets/QMenu>
|
| | | #include <QtGui/QMouseEvent>
|
| | | #include <QtWidgets/QUndoStack>
|
| | |
|
| | | namespace SharedTools {
|
| | |
|
| | | /*!
|
| | | \class FileEntryBackup
|
| | |
|
| | | Backups a file node.
|
| | | */
|
| | | class FileEntryBackup : public EntryBackup
|
| | | {
|
| | | private:
|
| | | int m_fileIndex;
|
| | | QString m_alias;
|
| | |
|
| | | public:
|
| | | FileEntryBackup(ResourceModel &model, int prefixIndex, int fileIndex,
|
| | | const QString &fileName, const QString &alias)
|
| | | : EntryBackup(model, prefixIndex, fileName), m_fileIndex(fileIndex),
|
| | | m_alias(alias) { }
|
| | | void restore() const;
|
| | | };
|
| | |
|
| | | void FileEntryBackup::restore() const
|
| | | {
|
| | | m_model->insertFile(m_prefixIndex, m_fileIndex, m_name, m_alias);
|
| | | }
|
| | |
|
| | | /*!
|
| | | \class PrefixEntryBackup
|
| | |
|
| | | Backups a prefix node including children.
|
| | | */
|
| | | class PrefixEntryBackup : public EntryBackup
|
| | | {
|
| | | private:
|
| | | QString m_language;
|
| | | QList<FileEntryBackup> m_files;
|
| | |
|
| | | public:
|
| | | PrefixEntryBackup(ResourceModel &model, int prefixIndex, const QString &prefix,
|
| | | const QString &language, const QList<FileEntryBackup> &files)
|
| | | : EntryBackup(model, prefixIndex, prefix), m_language(language), m_files(files) { }
|
| | | void restore() const;
|
| | | };
|
| | |
|
| | | void PrefixEntryBackup::restore() const
|
| | | {
|
| | | m_model->insertPrefix(m_prefixIndex, m_name, m_language);
|
| | | foreach (const FileEntryBackup &entry, m_files) {
|
| | | entry.restore();
|
| | | }
|
| | | }
|
| | |
|
| | | namespace Internal {
|
| | |
|
| | | class RelativeResourceModel : public ResourceModel
|
| | | {
|
| | | public:
|
| | | RelativeResourceModel(const ResourceFile &resource_file, QObject *parent = 0);
|
| | |
|
| | | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
|
| | | {
|
| | | if (!index.isValid())
|
| | | return QVariant();
|
| | | /*
|
| | | void const * const internalPointer = index.internalPointer();
|
| | |
|
| | | if ((role == Qt::DisplayRole) && (internalPointer != NULL))
|
| | | return ResourceModel::data(index, Qt::ToolTipRole);
|
| | | */
|
| | | return ResourceModel::data(index, role);
|
| | | }
|
| | |
|
| | | void setResourceDragEnabled(bool e) { m_resourceDragEnabled = e; }
|
| | | bool resourceDragEnabled() const { return m_resourceDragEnabled; }
|
| | |
|
| | | virtual Qt::ItemFlags flags(const QModelIndex &index) const;
|
| | |
|
| | | EntryBackup * removeEntry(const QModelIndex &index);
|
| | |
|
| | | private:
|
| | | bool m_resourceDragEnabled;
|
| | | };
|
| | |
|
| | | RelativeResourceModel::RelativeResourceModel(const ResourceFile &resource_file, QObject *parent) :
|
| | | ResourceModel(resource_file, parent),
|
| | | m_resourceDragEnabled(false)
|
| | | {
|
| | | }
|
| | |
|
| | | Qt::ItemFlags RelativeResourceModel::flags(const QModelIndex &index) const
|
| | | {
|
| | | Qt::ItemFlags rc = ResourceModel::flags(index);
|
| | | if ((rc & Qt::ItemIsEnabled) && m_resourceDragEnabled)
|
| | | rc |= Qt::ItemIsDragEnabled;
|
| | | return rc;
|
| | | }
|
| | |
|
| | | EntryBackup * RelativeResourceModel::removeEntry(const QModelIndex &index)
|
| | | {
|
| | | const QModelIndex prefixIndex = this->prefixIndex(index);
|
| | | const bool isPrefixNode = (prefixIndex == index);
|
| | |
|
| | | // Create backup, remove, return backup
|
| | | if (isPrefixNode) {
|
| | | QString dummy;
|
| | | QString prefixBackup;
|
| | | getItem(index, prefixBackup, dummy);
|
| | | const QString languageBackup = lang(index);
|
| | | const int childCount = rowCount(index);
|
| | | QList<FileEntryBackup> filesBackup;
|
| | | for (int i = 0; i < childCount; i++) {
|
| | | const QModelIndex childIndex = this->index(i, 0, index);
|
| | | const QString fileNameBackup = file(childIndex);
|
| | | const QString aliasBackup = alias(childIndex);
|
| | | FileEntryBackup entry(*this, index.row(), i, fileNameBackup, aliasBackup);
|
| | | filesBackup << entry;
|
| | | }
|
| | | deleteItem(index);
|
| | | return new PrefixEntryBackup(*this, index.row(), prefixBackup, languageBackup, filesBackup);
|
| | | } else {
|
| | | const QString fileNameBackup = file(index);
|
| | | const QString aliasBackup = alias(index);
|
| | | deleteItem(index);
|
| | | return new FileEntryBackup(*this, prefixIndex.row(), index.row(), fileNameBackup, aliasBackup);
|
| | | }
|
| | | }
|
| | |
|
| | | } // namespace Internal
|
| | |
|
| | | ResourceView::ResourceView(QUndoStack *history, QWidget *parent) :
|
| | | QTreeView(parent),
|
| | | m_qrcModel(new Internal::RelativeResourceModel(m_qrcFile, this)),
|
| | | m_addFile(0),
|
| | | m_editAlias(0),
|
| | | m_removeItem(0),
|
| | | m_addPrefix(0),
|
| | | m_editPrefix(0),
|
| | | m_editLang(0),
|
| | | m_viewMenu(0),
|
| | | m_defaultAddFile(false),
|
| | | m_history(history),
|
| | | m_mergeId(-1)
|
| | | {
|
| | | advanceMergeId();
|
| | | setModel(m_qrcModel);
|
| | |
|
| | | header()->hide();
|
| | |
|
| | | connect(m_qrcModel, SIGNAL(dirtyChanged(bool)),
|
| | | this, SIGNAL(dirtyChanged(bool)));
|
| | |
|
| | | setupMenu();
|
| | |
|
| | | setDefaultAddFileEnabled(true);
|
| | | enableContextMenu(true);
|
| | | }
|
| | |
|
| | | ResourceView::~ResourceView()
|
| | | {
|
| | | }
|
| | |
|
| | | void ResourceView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
| | | {
|
| | | Q_UNUSED(current)
|
| | | Q_UNUSED(previous)
|
| | | emit currentIndexChanged();
|
| | | }
|
| | |
|
| | | bool ResourceView::isDirty() const
|
| | | {
|
| | | return m_qrcModel->dirty();
|
| | | }
|
| | |
|
| | | void ResourceView::setDirty(bool dirty)
|
| | | {
|
| | | m_qrcModel->setDirty(dirty);
|
| | | }
|
| | |
|
| | | void ResourceView::setDefaultAddFileEnabled(bool enable)
|
| | | {
|
| | | m_defaultAddFile = enable;
|
| | | }
|
| | |
|
| | | bool ResourceView::defaultAddFileEnabled() const
|
| | | {
|
| | | return m_defaultAddFile;
|
| | | }
|
| | |
|
| | | void ResourceView::findSamePlacePostDeletionModelIndex(int &row, QModelIndex &parent) const
|
| | | {
|
| | | // Concept:
|
| | | // - Make selection stay on same Y level
|
| | | // - Enable user to hit delete several times in row
|
| | | const bool hasLowerBrother = m_qrcModel->hasIndex(row + 1,
|
| | | 0, parent);
|
| | | if (hasLowerBrother) {
|
| | | // First or mid child -> lower brother
|
| | | // o
|
| | | // +--o
|
| | | // +-[o] <-- deleted
|
| | | // +--o <-- chosen
|
| | | // o
|
| | | // --> return unmodified
|
| | | } else {
|
| | | if (parent == QModelIndex()) {
|
| | | // Last prefix node
|
| | | if (row == 0) {
|
| | | // Last and only prefix node
|
| | | // [o] <-- deleted
|
| | | // +--o
|
| | | // +--o
|
| | | row = -1;
|
| | | parent = QModelIndex();
|
| | | } else {
|
| | | const QModelIndex upperBrother = m_qrcModel->index(row - 1,
|
| | | 0, parent);
|
| | | if (m_qrcModel->hasChildren(upperBrother)) {
|
| | | // o
|
| | | // +--o <-- selected
|
| | | // [o] <-- deleted
|
| | | row = m_qrcModel->rowCount(upperBrother) - 1;
|
| | | parent = upperBrother;
|
| | | } else {
|
| | | // o
|
| | | // o <-- selected
|
| | | // [o] <-- deleted
|
| | | row--;
|
| | | }
|
| | | }
|
| | | } else {
|
| | | // Last file node
|
| | | const bool hasPrefixBelow = m_qrcModel->hasIndex(parent.row() + 1,
|
| | | parent.column(), QModelIndex());
|
| | | if (hasPrefixBelow) {
|
| | | // Last child or parent with lower brother -> lower brother of parent
|
| | | // o
|
| | | // +--o
|
| | | // +-[o] <-- deleted
|
| | | // o <-- chosen
|
| | | row = parent.row() + 1;
|
| | | parent = QModelIndex();
|
| | | } else {
|
| | | const bool onlyChild = row == 0;
|
| | | if (onlyChild) {
|
| | | // Last and only child of last parent -> parent
|
| | | // o <-- chosen
|
| | | // +-[o] <-- deleted
|
| | | row = parent.row();
|
| | | parent = m_qrcModel->parent(parent);
|
| | | } else {
|
| | | // Last child of last parent -> upper brother
|
| | | // o
|
| | | // +--o <-- chosen
|
| | | // +-[o] <-- deleted
|
| | | row--;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | EntryBackup * ResourceView::removeEntry(const QModelIndex &index)
|
| | | {
|
| | | Q_ASSERT(m_qrcModel);
|
| | | return m_qrcModel->removeEntry(index);
|
| | | }
|
| | |
|
| | | void ResourceView::addFiles(int prefixIndex, const QStringList &fileNames, int cursorFile,
|
| | | int &firstFile, int &lastFile)
|
| | | {
|
| | | Q_ASSERT(m_qrcModel);
|
| | | m_qrcModel->addFiles(prefixIndex, fileNames, cursorFile, firstFile, lastFile);
|
| | |
|
| | | // Expand prefix node
|
| | | const QModelIndex prefixModelIndex = m_qrcModel->index(prefixIndex, 0, QModelIndex());
|
| | | if (prefixModelIndex.isValid()) {
|
| | | this->setExpanded(prefixModelIndex, true);
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::removeFiles(int prefixIndex, int firstFileIndex, int lastFileIndex)
|
| | | {
|
| | | Q_ASSERT(prefixIndex >= 0 && prefixIndex < m_qrcModel->rowCount(QModelIndex()));
|
| | | const QModelIndex prefixModelIndex = m_qrcModel->index(prefixIndex, 0, QModelIndex());
|
| | | Q_ASSERT(prefixModelIndex != QModelIndex());
|
| | | Q_ASSERT(firstFileIndex >= 0 && firstFileIndex < m_qrcModel->rowCount(prefixModelIndex));
|
| | | Q_ASSERT(lastFileIndex >= 0 && lastFileIndex < m_qrcModel->rowCount(prefixModelIndex));
|
| | |
|
| | | for (int i = lastFileIndex; i >= firstFileIndex; i--) {
|
| | | const QModelIndex index = m_qrcModel->index(i, 0, prefixModelIndex);
|
| | | delete removeEntry(index);
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::enableContextMenu(bool enable)
|
| | | {
|
| | | if (enable) {
|
| | | connect(this, SIGNAL(clicked(const QModelIndex &)),
|
| | | this, SLOT(popupMenu(const QModelIndex &)));
|
| | | } else {
|
| | | disconnect(this, SIGNAL(clicked(const QModelIndex &)),
|
| | | this, SLOT(popupMenu(const QModelIndex &)));
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::setupMenu()
|
| | | {
|
| | | m_viewMenu = new QMenu(this);
|
| | | /*
|
| | | m_addFile = m_viewMenu->addAction(tr("Add Files..."), this, SIGNAL(addFiles()));
|
| | | m_editAlias = m_viewMenu->addAction(tr("Change Alias..."), this, SLOT(onEditAlias()));
|
| | | m_addPrefix = m_viewMenu->addAction(tr("Add Prefix..."), this, SLOT(addPrefix()));
|
| | | m_editPrefix = m_viewMenu->addAction(tr("Change Prefix..."), this, SLOT(onEditPrefix()));
|
| | | m_editLang = m_viewMenu->addAction(tr("Change Language..."), this, SLOT(onEditLang()));
|
| | | m_viewMenu->addSeparator();
|
| | | m_removeItem = m_viewMenu->addAction(tr("Remove Item"), this, SLOT(removeItem()));
|
| | | */
|
| | | m_addFile = m_viewMenu->addAction(tr("Add Files..."), this, SLOT(onAddFiles()));
|
| | | m_editAlias = m_viewMenu->addAction(tr("Change Alias..."), this, SLOT(onEditAlias()));
|
| | | m_addPrefix = m_viewMenu->addAction(tr("Add Prefix..."), this, SIGNAL(addPrefixTriggered()));
|
| | | m_editPrefix = m_viewMenu->addAction(tr("Change Prefix..."), this, SLOT(onEditPrefix()));
|
| | | m_editLang = m_viewMenu->addAction(tr("Change Language..."), this, SLOT(onEditLang()));
|
| | | m_viewMenu->addSeparator();
|
| | | m_removeItem = m_viewMenu->addAction(tr("Remove Item"), this, SIGNAL(removeItem()));
|
| | | }
|
| | |
|
| | | void ResourceView::mouseReleaseEvent(QMouseEvent *e)
|
| | | {
|
| | | m_releasePos = e->globalPos();
|
| | | if (e->button() != Qt::RightButton)
|
| | | m_releasePos = QPoint();
|
| | |
|
| | | QTreeView::mouseReleaseEvent(e);
|
| | | }
|
| | |
|
| | | void ResourceView::keyPressEvent(QKeyEvent *e)
|
| | | {
|
| | | if (e->key() == Qt::Key_Delete)
|
| | | removeItem();
|
| | | else
|
| | | QTreeView::keyPressEvent(e);
|
| | | }
|
| | |
|
| | | void ResourceView::popupMenu(const QModelIndex &index)
|
| | | {
|
| | | if (!m_releasePos.isNull()) {
|
| | | m_addFile->setEnabled(index.isValid());
|
| | | m_editPrefix->setEnabled(index.isValid());
|
| | | m_editLang->setEnabled(index.isValid());
|
| | | m_removeItem->setEnabled(index.isValid());
|
| | |
|
| | | m_viewMenu->popup(m_releasePos);
|
| | | }
|
| | | }
|
| | |
|
| | | QModelIndex ResourceView::addPrefix()
|
| | | {
|
| | | const QModelIndex idx = m_qrcModel->addNewPrefix();
|
| | | selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
|
| | | return idx;
|
| | | }
|
| | |
|
| | | QStringList ResourceView::fileNamesToAdd()
|
| | | {
|
| | | return QFileDialog::getOpenFileNames(this, tr("Open File"),
|
| | | m_qrcModel->absolutePath(QString()),
|
| | | tr("All files (*)"));
|
| | | }
|
| | |
|
| | | void ResourceView::onAddFiles()
|
| | | {
|
| | | emit addFilesTriggered(currentPrefix());
|
| | | }
|
| | |
|
| | | void ResourceView::addFiles(QStringList fileList, const QModelIndex &index)
|
| | | {
|
| | | if (fileList.isEmpty())
|
| | | return;
|
| | | QModelIndex idx = index;
|
| | | if (!m_qrcModel->hasChildren(QModelIndex())) {
|
| | | idx = addPrefix();
|
| | | expand(idx);
|
| | | }
|
| | |
|
| | | idx = m_qrcModel->addFiles(idx, fileList);
|
| | |
|
| | | if (idx.isValid()) {
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(index);
|
| | | setExpanded(preindex, true);
|
| | | selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
|
| | | QString prefix, file;
|
| | | m_qrcModel->getItem(preindex, prefix, file);
|
| | | // XXX emit filesAdded(prefix, fileList);
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::addFile(const QString &prefix, const QString &file)
|
| | | {
|
| | | const QModelIndex preindex = m_qrcModel->getIndex(prefix, QString());
|
| | | addFiles(QStringList(file), preindex);
|
| | | }
|
| | |
|
| | | /*
|
| | | void ResourceView::removeItem()
|
| | | {
|
| | | const QModelIndex index = currentIndex();
|
| | | m_qrcModel->deleteItem(index);
|
| | | }
|
| | |
|
| | | void ResourceView::removeFile(const QString &prefix, const QString &file)
|
| | | {
|
| | | const QModelIndex index = m_qrcModel->getIndex(prefix, file);
|
| | | if (index.isValid())
|
| | | m_qrcModel->deleteItem(index);
|
| | | }
|
| | | */
|
| | | void ResourceView::onEditPrefix()
|
| | | {
|
| | | QModelIndex index = currentIndex();
|
| | | changePrefix(index);
|
| | | }
|
| | |
|
| | | void ResourceView::onEditLang()
|
| | | {
|
| | | const QModelIndex index = currentIndex();
|
| | | changeLang(index);
|
| | | }
|
| | |
|
| | | void ResourceView::onEditAlias()
|
| | | {
|
| | | const QModelIndex index = currentIndex();
|
| | | changeAlias(index);
|
| | | }
|
| | |
|
| | | bool ResourceView::load(const QString &fileName)
|
| | | {
|
| | | const QFileInfo fi(fileName);
|
| | | m_qrcModel->setFileName(fi.absoluteFilePath());
|
| | |
|
| | | if (!fi.exists())
|
| | | return false;
|
| | |
|
| | | return m_qrcModel->reload();
|
| | | }
|
| | |
|
| | | bool ResourceView::save()
|
| | | {
|
| | | return m_qrcModel->save();
|
| | | }
|
| | |
|
| | | void ResourceView::changePrefix(const QModelIndex &index)
|
| | | {
|
| | | bool ok = false;
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(index);
|
| | |
|
| | | QString prefixBefore;
|
| | | QString dummy;
|
| | | m_qrcModel->getItem(preindex, prefixBefore, dummy);
|
| | |
|
| | | QString const prefixAfter = QInputDialog::getText(this, tr("Change Prefix"), tr("Input prefix:"),
|
| | | QLineEdit::Normal, prefixBefore, &ok);
|
| | |
|
| | | if (ok)
|
| | | addUndoCommand(preindex, PrefixProperty, prefixBefore, prefixAfter);
|
| | | }
|
| | |
|
| | | void ResourceView::changeLang(const QModelIndex &index)
|
| | | {
|
| | | bool ok = false;
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(index);
|
| | |
|
| | | QString const langBefore = m_qrcModel->lang(preindex);
|
| | | QString const langAfter = QInputDialog::getText(this, tr("Change Language"), tr("Language:"),
|
| | | QLineEdit::Normal, langBefore, &ok);
|
| | |
|
| | | if (ok) {
|
| | | addUndoCommand(preindex, LanguageProperty, langBefore, langAfter);
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::changeAlias(const QModelIndex &index)
|
| | | {
|
| | | if (!index.parent().isValid())
|
| | | return;
|
| | |
|
| | | bool ok = false;
|
| | |
|
| | | QString const aliasBefore = m_qrcModel->alias(index);
|
| | | QString const aliasAfter = QInputDialog::getText(this, tr("Change File Alias"), tr("Alias:"),
|
| | | QLineEdit::Normal, aliasBefore, &ok);
|
| | |
|
| | | if (ok)
|
| | | addUndoCommand(index, AliasProperty, aliasBefore, aliasAfter);
|
| | | }
|
| | |
|
| | | QString ResourceView::currentAlias() const
|
| | | {
|
| | | const QModelIndex current = currentIndex();
|
| | | if (!current.isValid())
|
| | | return QString();
|
| | | return m_qrcModel->alias(current);
|
| | | }
|
| | |
|
| | | QString ResourceView::currentPrefix() const
|
| | | {
|
| | | const QModelIndex current = currentIndex();
|
| | | if (!current.isValid())
|
| | | return QString();
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(current);
|
| | | QString prefix, file;
|
| | | m_qrcModel->getItem(preindex, prefix, file);
|
| | | return prefix;
|
| | | }
|
| | |
|
| | | QString ResourceView::currentLanguage() const
|
| | | {
|
| | | const QModelIndex current = currentIndex();
|
| | | if (!current.isValid())
|
| | | return QString();
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(current);
|
| | | return m_qrcModel->lang(preindex);
|
| | | }
|
| | |
|
| | | QString ResourceView::getCurrentValue(NodeProperty property) const
|
| | | {
|
| | | switch (property) {
|
| | | case AliasProperty: return currentAlias();
|
| | | case PrefixProperty: return currentPrefix();
|
| | | case LanguageProperty: return currentLanguage();
|
| | | default: Q_ASSERT(false); return QString(); // Kill warning
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::changeValue(const QModelIndex &nodeIndex, NodeProperty property,
|
| | | const QString &value)
|
| | | {
|
| | | switch (property) {
|
| | | case AliasProperty: m_qrcModel->changeAlias(nodeIndex, value); return;
|
| | | case PrefixProperty: m_qrcModel->changePrefix(nodeIndex, value); return;
|
| | | case LanguageProperty: m_qrcModel->changeLang(nodeIndex, value); return;
|
| | | default: Q_ASSERT(false);
|
| | | }
|
| | | }
|
| | |
|
| | | void ResourceView::advanceMergeId()
|
| | | {
|
| | | m_mergeId++;
|
| | | if (m_mergeId < 0)
|
| | | m_mergeId = 0;
|
| | | }
|
| | |
|
| | | void ResourceView::addUndoCommand(const QModelIndex &nodeIndex, NodeProperty property,
|
| | | const QString &before, const QString &after)
|
| | | {
|
| | | QUndoCommand * const command = new ModifyPropertyCommand(this, nodeIndex, property,
|
| | | m_mergeId, before, after);
|
| | | m_history->push(command);
|
| | | }
|
| | |
|
| | | void ResourceView::setCurrentAlias(const QString &before, const QString &after)
|
| | | {
|
| | | const QModelIndex current = currentIndex();
|
| | | if (!current.isValid())
|
| | | return;
|
| | |
|
| | | addUndoCommand(current, AliasProperty, before, after);
|
| | | }
|
| | |
|
| | | void ResourceView::setCurrentPrefix(const QString &before, const QString &after)
|
| | | {
|
| | | const QModelIndex current = currentIndex();
|
| | | if (!current.isValid())
|
| | | return;
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(current);
|
| | |
|
| | | addUndoCommand(preindex, PrefixProperty, before, after);
|
| | | }
|
| | |
|
| | | void ResourceView::setCurrentLanguage(const QString &before, const QString &after)
|
| | | {
|
| | | const QModelIndex current = currentIndex();
|
| | | if (!current.isValid())
|
| | | return;
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(current);
|
| | |
|
| | | addUndoCommand(preindex, LanguageProperty, before, after);
|
| | | }
|
| | |
|
| | | bool ResourceView::isPrefix(const QModelIndex &index) const
|
| | | {
|
| | | if (!index.isValid())
|
| | | return false;
|
| | | const QModelIndex preindex = m_qrcModel->prefixIndex(index);
|
| | | if (preindex == index)
|
| | | return true;
|
| | | return false;
|
| | | }
|
| | |
|
| | | QString ResourceView::fileName() const
|
| | | {
|
| | | return m_qrcModel->fileName();
|
| | | }
|
| | |
|
| | | void ResourceView::setFileName(const QString &fileName)
|
| | | {
|
| | | m_qrcModel->setFileName(fileName);
|
| | | }
|
| | |
|
| | | void ResourceView::setResourceDragEnabled(bool e)
|
| | | {
|
| | | setDragEnabled(e);
|
| | | m_qrcModel->setResourceDragEnabled(e);
|
| | | }
|
| | |
|
| | | bool ResourceView::resourceDragEnabled() const
|
| | | {
|
| | | return m_qrcModel->resourceDragEnabled();
|
| | | }
|
| | |
|
| | | } // namespace SharedTools
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef RESOURCEVIEW_H
|
| | | #define RESOURCEVIEW_H
|
| | |
|
| | | #include "resourcefile_p.h"
|
| | |
|
| | | #include <QtWidgets/QTreeView>
|
| | | #include <QtCore/QPoint>
|
| | |
|
| | | using namespace qdesigner_internal;
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | | class QAction;
|
| | | class QMenu;
|
| | | class QMouseEvent;
|
| | | class QUndoStack;
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | namespace SharedTools {
|
| | |
|
| | | /*!
|
| | | \class EntryBackup
|
| | |
|
| | | Holds the backup of a tree node including children.
|
| | | */
|
| | | class EntryBackup
|
| | | {
|
| | | protected:
|
| | | ResourceModel *m_model;
|
| | | int m_prefixIndex;
|
| | | QString m_name;
|
| | |
|
| | | EntryBackup(ResourceModel &model, int prefixIndex, const QString &name)
|
| | | : m_model(&model), m_prefixIndex(prefixIndex), m_name(name) { }
|
| | |
|
| | | public:
|
| | | virtual void restore() const = 0;
|
| | | virtual ~EntryBackup() { }
|
| | | };
|
| | |
|
| | | namespace Internal {
|
| | | class RelativeResourceModel;
|
| | | }
|
| | |
|
| | | class ResourceView : public QTreeView
|
| | | {
|
| | | Q_OBJECT
|
| | |
|
| | | public:
|
| | | enum NodeProperty {
|
| | | AliasProperty,
|
| | | PrefixProperty,
|
| | | LanguageProperty
|
| | | };
|
| | |
|
| | | ResourceView(QUndoStack *history, QWidget *parent = 0);
|
| | | ~ResourceView();
|
| | |
|
| | | bool load(const QString &fileName);
|
| | | bool save();
|
| | | QString fileName() const;
|
| | | void setFileName(const QString &fileName);
|
| | |
|
| | | bool isDirty() const;
|
| | | void setDirty(bool dirty);
|
| | |
|
| | | void enableContextMenu(bool enable);
|
| | |
|
| | | void addFiles(QStringList fileList, const QModelIndex &index);
|
| | |
|
| | | void addFile(const QString &prefix, const QString &file);
|
| | | // void removeFile(const QString &prefix, const QString &file);
|
| | |
|
| | | bool isPrefix(const QModelIndex &index) const;
|
| | |
|
| | | QString currentAlias() const;
|
| | | QString currentPrefix() const;
|
| | | QString currentLanguage() const;
|
| | |
|
| | | void setResourceDragEnabled(bool e);
|
| | | bool resourceDragEnabled() const;
|
| | |
|
| | | void setDefaultAddFileEnabled(bool enable);
|
| | | bool defaultAddFileEnabled() const;
|
| | |
|
| | | void findSamePlacePostDeletionModelIndex(int &row, QModelIndex &parent) const;
|
| | | EntryBackup *removeEntry(const QModelIndex &index);
|
| | | void addFiles(int prefixIndex, const QStringList &fileNames, int cursorFile,
|
| | | int &firstFile, int &lastFile);
|
| | | void removeFiles(int prefixIndex, int firstFileIndex, int lastFileIndex);
|
| | | QStringList fileNamesToAdd();
|
| | | QModelIndex addPrefix();
|
| | |
|
| | | public slots:
|
| | | void onAddFiles();
|
| | | void setCurrentAlias(const QString &before, const QString &after);
|
| | | void setCurrentPrefix(const QString &before, const QString &after);
|
| | | void setCurrentLanguage(const QString &before, const QString &after);
|
| | | void advanceMergeId();
|
| | |
|
| | | protected:
|
| | | void setupMenu();
|
| | | void changePrefix(const QModelIndex &index);
|
| | | void changeLang(const QModelIndex &index);
|
| | | void changeAlias(const QModelIndex &index);
|
| | | void mouseReleaseEvent(QMouseEvent *e);
|
| | | void keyPressEvent(QKeyEvent *e);
|
| | |
|
| | | signals:
|
| | | void removeItem();
|
| | | void dirtyChanged(bool b);
|
| | | void currentIndexChanged();
|
| | |
|
| | | void addFilesTriggered(const QString &prefix);
|
| | | void addPrefixTriggered();
|
| | |
|
| | | protected slots:
|
| | | void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
| | |
|
| | | private slots:
|
| | | void onEditAlias();
|
| | | void onEditPrefix();
|
| | | void onEditLang();
|
| | | void popupMenu(const QModelIndex &index);
|
| | |
|
| | | public:
|
| | | QString getCurrentValue(NodeProperty property) const;
|
| | | void changeValue(const QModelIndex &nodeIndex, NodeProperty property, const QString &value);
|
| | |
|
| | | private:
|
| | | void addUndoCommand(const QModelIndex &nodeIndex, NodeProperty property,
|
| | | const QString &before, const QString &after);
|
| | |
|
| | | QPoint m_releasePos;
|
| | |
|
| | | qdesigner_internal::ResourceFile m_qrcFile;
|
| | | Internal::RelativeResourceModel *m_qrcModel;
|
| | |
|
| | | QAction *m_addFile;
|
| | | QAction *m_editAlias;
|
| | | QAction *m_removeItem;
|
| | | QAction *m_addPrefix;
|
| | | QAction *m_editPrefix;
|
| | | QAction *m_editLang;
|
| | | QMenu *m_viewMenu;
|
| | | bool m_defaultAddFile;
|
| | | QUndoStack *m_history;
|
| | | int m_mergeId;
|
| | | };
|
| | |
|
| | | } // namespace SharedTools
|
| | |
|
| | | #endif // RESOURCEVIEW_H
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #include "undocommands_p.h"
|
| | |
|
| | | #include <QtCore/QModelIndex>
|
| | |
|
| | | namespace SharedTools {
|
| | |
|
| | | ViewCommand::ViewCommand(ResourceView *view)
|
| | | : m_view(view)
|
| | | { }
|
| | |
|
| | | ViewCommand::~ViewCommand()
|
| | | { }
|
| | |
|
| | | ModelIndexViewCommand::ModelIndexViewCommand(ResourceView *view)
|
| | | : ViewCommand(view)
|
| | | { }
|
| | |
|
| | | ModelIndexViewCommand::~ModelIndexViewCommand()
|
| | | { }
|
| | |
|
| | | void ModelIndexViewCommand::storeIndex(const QModelIndex &index)
|
| | | {
|
| | | if (m_view->isPrefix(index)) {
|
| | | m_prefixArrayIndex = index.row();
|
| | | m_fileArrayIndex = -1;
|
| | | } else {
|
| | | m_fileArrayIndex = index.row();
|
| | | m_prefixArrayIndex = m_view->model()->parent(index).row();
|
| | | }
|
| | | }
|
| | |
|
| | | QModelIndex ModelIndexViewCommand::makeIndex() const
|
| | | {
|
| | | const QModelIndex prefixModelIndex
|
| | | = m_view->model()->index(m_prefixArrayIndex, 0, QModelIndex());
|
| | | if (m_fileArrayIndex != -1) {
|
| | | // File node
|
| | | const QModelIndex fileModelIndex
|
| | | = m_view->model()->index(m_fileArrayIndex, 0, prefixModelIndex);
|
| | | return fileModelIndex;
|
| | | } else {
|
| | | // Prefix node
|
| | | return prefixModelIndex;
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | |
|
| | | ModifyPropertyCommand::ModifyPropertyCommand(ResourceView *view, const QModelIndex &nodeIndex,
|
| | | ResourceView::NodeProperty property, const int mergeId, const QString &before,
|
| | | const QString &after)
|
| | | : ModelIndexViewCommand(view), m_property(property), m_before(before), m_after(after),
|
| | | m_mergeId(mergeId)
|
| | | {
|
| | | storeIndex(nodeIndex);
|
| | | }
|
| | |
|
| | | bool ModifyPropertyCommand::mergeWith(const QUndoCommand * command)
|
| | | {
|
| | | if (command->id() != id() || m_property != static_cast<const ModifyPropertyCommand *>(command)->m_property)
|
| | | return false;
|
| | | // Choose older command (this) and forgot the other
|
| | | return true;
|
| | | }
|
| | |
|
| | | void ModifyPropertyCommand::undo()
|
| | | {
|
| | | Q_ASSERT(m_view);
|
| | |
|
| | | // Save current text in m_after for redo()
|
| | | m_after = m_view->getCurrentValue(m_property);
|
| | |
|
| | | // Reset text to m_before
|
| | | m_view->changeValue(makeIndex(), m_property, m_before);
|
| | | }
|
| | |
|
| | | void ModifyPropertyCommand::redo()
|
| | | {
|
| | | // Prevent execution from within QUndoStack::push
|
| | | if (m_after.isNull())
|
| | | return;
|
| | |
|
| | | // Bring back text before undo
|
| | | Q_ASSERT(m_view);
|
| | | m_view->changeValue(makeIndex(), m_property, m_after);
|
| | | }
|
| | |
|
| | | RemoveEntryCommand::RemoveEntryCommand(ResourceView *view, const QModelIndex &index)
|
| | | : ModelIndexViewCommand(view), m_entry(0), m_isExpanded(true)
|
| | | {
|
| | | storeIndex(index);
|
| | | }
|
| | |
|
| | | RemoveEntryCommand::~RemoveEntryCommand()
|
| | | {
|
| | | freeEntry();
|
| | | }
|
| | |
|
| | | void RemoveEntryCommand::redo()
|
| | | {
|
| | | freeEntry();
|
| | | const QModelIndex index = makeIndex();
|
| | | m_isExpanded = m_view->isExpanded(index);
|
| | | m_entry = m_view->removeEntry(index);
|
| | | }
|
| | |
|
| | | void RemoveEntryCommand::undo()
|
| | | {
|
| | | if (m_entry == 0) {
|
| | | m_entry->restore();
|
| | | Q_ASSERT(m_view != 0);
|
| | | const QModelIndex index = makeIndex();
|
| | | m_view->setExpanded(index, m_isExpanded);
|
| | | m_view->setCurrentIndex(index);
|
| | | freeEntry();
|
| | | }
|
| | | }
|
| | |
|
| | | void RemoveEntryCommand::freeEntry()
|
| | | {
|
| | | delete m_entry;
|
| | | m_entry = 0;
|
| | | }
|
| | |
|
| | | AddFilesCommand::AddFilesCommand(ResourceView *view, int prefixIndex, int cursorFileIndex,
|
| | | const QStringList &fileNames)
|
| | | : ViewCommand(view), m_prefixIndex(prefixIndex), m_cursorFileIndex(cursorFileIndex),
|
| | | m_fileNames(fileNames), m_firstFile(-1), m_lastFile(-1)
|
| | | { }
|
| | |
|
| | | void AddFilesCommand::redo()
|
| | | {
|
| | | m_view->addFiles(m_prefixIndex, m_fileNames, m_cursorFileIndex, m_firstFile, m_lastFile);
|
| | | }
|
| | |
|
| | | void AddFilesCommand::undo()
|
| | | {
|
| | | m_view->removeFiles(m_prefixIndex, m_firstFile, m_lastFile);
|
| | | }
|
| | |
|
| | | AddEmptyPrefixCommand::AddEmptyPrefixCommand(ResourceView *view)
|
| | | : ViewCommand(view)
|
| | | { }
|
| | |
|
| | | void AddEmptyPrefixCommand::redo()
|
| | | {
|
| | | m_prefixArrayIndex = m_view->addPrefix().row();
|
| | | }
|
| | |
|
| | | void AddEmptyPrefixCommand::undo()
|
| | | {
|
| | | const QModelIndex prefixModelIndex = m_view->model()->index(
|
| | | m_prefixArrayIndex, 0, QModelIndex());
|
| | | delete m_view->removeEntry(prefixModelIndex);
|
| | | }
|
| | |
|
| | | } // namespace SharedTools
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2016 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #ifndef UNDO_COMMANDS_H
|
| | | #define UNDO_COMMANDS_H
|
| | |
|
| | | #include "resourceview.h"
|
| | |
|
| | | #include <QtCore/QString>
|
| | | #include <QtWidgets/QUndoCommand>
|
| | |
|
| | | QT_BEGIN_NAMESPACE
|
| | | class QModelIndex;
|
| | | QT_END_NAMESPACE
|
| | |
|
| | | namespace SharedTools {
|
| | |
|
| | | /*!
|
| | | \class ViewCommand
|
| | |
|
| | | Provides a base for \l ResourceView-related commands.
|
| | | */
|
| | | class ViewCommand : public QUndoCommand
|
| | | {
|
| | | protected:
|
| | | ResourceView *m_view;
|
| | |
|
| | | ViewCommand(ResourceView *view);
|
| | | virtual ~ViewCommand();
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class ModelIndexViewCommand
|
| | |
|
| | | Provides a mean to store/restore a \l QModelIndex as it cannot
|
| | | be stored safely in most cases. This is an abstract class.
|
| | | */
|
| | | class ModelIndexViewCommand : public ViewCommand
|
| | | {
|
| | | int m_prefixArrayIndex;
|
| | | int m_fileArrayIndex;
|
| | |
|
| | | protected:
|
| | | ModelIndexViewCommand(ResourceView *view);
|
| | | virtual ~ModelIndexViewCommand();
|
| | | void storeIndex(const QModelIndex &index);
|
| | | QModelIndex makeIndex() const;
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class ModifyPropertyCommand
|
| | |
|
| | | Modifies the name/prefix/language property of a prefix/file node.
|
| | | */
|
| | | class ModifyPropertyCommand : public ModelIndexViewCommand
|
| | | {
|
| | | ResourceView::NodeProperty m_property;
|
| | | QString m_before;
|
| | | QString m_after;
|
| | | int m_mergeId;
|
| | |
|
| | | public:
|
| | | ModifyPropertyCommand(ResourceView *view, const QModelIndex &nodeIndex,
|
| | | ResourceView::NodeProperty property, const int mergeId, const QString &before,
|
| | | const QString &after = QString());
|
| | |
|
| | | private:
|
| | | int id() const { return m_mergeId; }
|
| | | bool mergeWith(const QUndoCommand * command);
|
| | | void undo();
|
| | | void redo();
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class RemoveEntryCommand
|
| | |
|
| | | Removes a \l QModelIndex including all children from a \l ResourceView.
|
| | | */
|
| | | class RemoveEntryCommand : public ModelIndexViewCommand
|
| | | {
|
| | | EntryBackup *m_entry;
|
| | | bool m_isExpanded;
|
| | |
|
| | | public:
|
| | | RemoveEntryCommand(ResourceView *view, const QModelIndex &index);
|
| | | ~RemoveEntryCommand();
|
| | |
|
| | | private:
|
| | | void redo();
|
| | | void undo();
|
| | | void freeEntry();
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class AddFilesCommand
|
| | |
|
| | | Adds a list of files to a given prefix node.
|
| | | */
|
| | | class AddFilesCommand : public ViewCommand
|
| | | {
|
| | | int m_prefixIndex;
|
| | | int m_cursorFileIndex;
|
| | | int m_firstFile;
|
| | | int m_lastFile;
|
| | | const QStringList m_fileNames;
|
| | |
|
| | | public:
|
| | | AddFilesCommand(ResourceView *view, int prefixIndex, int cursorFileIndex,
|
| | | const QStringList &fileNames);
|
| | |
|
| | | private:
|
| | | void redo();
|
| | | void undo();
|
| | | };
|
| | |
|
| | | /*!
|
| | | \class AddEmptyPrefixCommand
|
| | |
|
| | | Adds a new, empty prefix node.
|
| | | */
|
| | | class AddEmptyPrefixCommand : public ViewCommand
|
| | | {
|
| | | int m_prefixArrayIndex;
|
| | |
|
| | | public:
|
| | | AddEmptyPrefixCommand(ResourceView *view);
|
| | |
|
| | | private:
|
| | | void redo();
|
| | | void undo();
|
| | | };
|
| | |
|
| | | } // namespace SharedTools
|
| | |
|
| | | #endif // UNDO_COMMANDS_H
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <ImportGroup Label="PropertySheets" />
|
| | | <PropertyGroup Label="UserMacros" />
|
| | | <PropertyGroup Condition="'$(QtBuild_Static_Vs2017)'==''">
|
| | | <QtBuild_Static_Vs2017>..\..\..\install\qt5-x86-vs2017-static</QtBuild_Static_Vs2017>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(QtBuild_Static_Vs2019)'==''">
|
| | | <QtBuild_Static_Vs2019>..\..\..\install\qt5-x86-vs2019-static</QtBuild_Static_Vs2019>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(QtBuild_Static_Vs2022)'==''">
|
| | | <QtBuild_Static_Vs2022>..\..\..\install\qt5-x86-vs2022-static</QtBuild_Static_Vs2022>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <QtBuild>$(QtBuild_Static_Vs2017)</QtBuild>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <QtBuild>$(QtBuild_Static_Vs2019)</QtBuild>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <QtBuild>$(QtBuild_Static_Vs2022)</QtBuild>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup>
|
| | | <QtBuild>$([System.IO.Path]::Combine($(ProjectDir),$(QtBuild)))</QtBuild>
|
| | | <QtBuild>$([System.IO.Path]::GetFullPath($(QtBuild)))</QtBuild>
|
| | | </PropertyGroup>
|
| | | </Project>
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using Microsoft.Build.Framework;
|
| | |
|
| | | namespace QtVsTools.QtMSBuild
|
| | | {
|
| | | public interface ITaskLoggingHelper
|
| | | {
|
| | | bool HasLoggedErrors { get; }
|
| | |
|
| | | void LogCommandLine(
|
| | | string commandLine);
|
| | |
|
| | | void LogCommandLine(
|
| | | MessageImportance importance,
|
| | | string commandLine);
|
| | |
|
| | | void LogCriticalMessage(
|
| | | string subcategory,
|
| | | string code,
|
| | | string helpKeyword,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogError(
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogError(
|
| | | string subcategory,
|
| | | string errorCode,
|
| | | string helpKeyword,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogError(
|
| | | string subcategory,
|
| | | string errorCode,
|
| | | string helpKeyword,
|
| | | string helpLink,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogErrorFromException(
|
| | | Exception exception);
|
| | |
|
| | | void LogErrorFromException(
|
| | | Exception exception,
|
| | | bool showStackTrace);
|
| | |
|
| | | void LogErrorFromException(
|
| | | Exception exception,
|
| | | bool showStackTrace,
|
| | | bool showDetail,
|
| | | string file);
|
| | |
|
| | | void LogErrorFromResources(
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogErrorFromResources(
|
| | | string subcategoryResourceName,
|
| | | string errorCode,
|
| | | string helpKeyword,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogErrorWithCodeFromResources(
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogErrorWithCodeFromResources(
|
| | | string subcategoryResourceName,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogExternalProjectFinished(
|
| | | string message,
|
| | | string helpKeyword,
|
| | | string projectFile,
|
| | | bool succeeded);
|
| | |
|
| | | void LogExternalProjectStarted(
|
| | | string message,
|
| | | string helpKeyword,
|
| | | string projectFile,
|
| | | string targetNames);
|
| | |
|
| | | void LogMessage(
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogMessage(
|
| | | MessageImportance importance,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogMessage(
|
| | | string subcategory,
|
| | | string code,
|
| | | string helpKeyword,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | MessageImportance importance,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogMessageFromResources(
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogMessageFromResources(
|
| | | MessageImportance importance,
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | bool LogMessageFromText(
|
| | | string lineOfText,
|
| | | MessageImportance messageImportance);
|
| | |
|
| | | bool LogMessagesFromFile(
|
| | | string fileName);
|
| | |
|
| | | bool LogMessagesFromFile(
|
| | | string fileName,
|
| | | MessageImportance messageImportance);
|
| | |
|
| | | bool LogMessagesFromStream(
|
| | | TextReader stream,
|
| | | MessageImportance messageImportance);
|
| | |
|
| | | bool LogsMessagesOfImportance(
|
| | | MessageImportance importance);
|
| | |
|
| | | void LogTelemetry(
|
| | | string eventName,
|
| | | IDictionary<string,
|
| | | string> properties);
|
| | |
|
| | | void LogWarning(
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogWarning(
|
| | | string subcategory,
|
| | | string warningCode,
|
| | | string helpKeyword,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogWarning(
|
| | | string subcategory,
|
| | | string warningCode,
|
| | | string helpKeyword,
|
| | | string helpLink,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string message,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogWarningFromException(
|
| | | Exception exception);
|
| | |
|
| | | void LogWarningFromException(
|
| | | Exception exception,
|
| | | bool showStackTrace);
|
| | |
|
| | | void LogWarningFromResources(
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogWarningFromResources(
|
| | | string subcategoryResourceName,
|
| | | string warningCode,
|
| | | string helpKeyword,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogWarningWithCodeFromResources(
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | |
|
| | | void LogWarningWithCodeFromResources(
|
| | | string subcategoryResourceName,
|
| | | string file,
|
| | | int lineNumber,
|
| | | int columnNumber,
|
| | | int endLineNumber,
|
| | | int endColumnNumber,
|
| | | string messageResourceName,
|
| | | params object[] messageArgs);
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************
|
| | | <#@output extension="tt.cs" #>
|
| | | <#@include file="$(SolutionDir)\version.tt" #>
|
| | | ** <#=WARNING_GENERATED_FILE#>
|
| | | ****************************************************************************/
|
| | |
|
| | | using System.Reflection;
|
| | | using System.Runtime.CompilerServices;
|
| | | using System.Runtime.InteropServices;
|
| | |
|
| | | // General Information about an assembly is controlled through the following
|
| | | // set of attributes. Change these attribute values to modify the information
|
| | | // associated with an assembly.
|
| | | [assembly: AssemblyTitle("QtMSBuild")]
|
| | | [assembly: AssemblyDescription("The Qt Visual Studio Tools allow developers to use the standard development environment without having to worry about any Qt-related build steps or tools.")]
|
| | | [assembly: AssemblyConfiguration("")]
|
| | | [assembly: AssemblyCompany("The Qt Company Ltd.")]
|
| | | [assembly: AssemblyProduct("Qt Visual Studio Tools")]
|
| | | [assembly: AssemblyCopyright("Copyright (C) 2016-2021 The Qt Company Ltd.")]
|
| | | [assembly: AssemblyTrademark("The Qt Company Ltd. Qt and their respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.")]
|
| | | [assembly: AssemblyCulture("")]
|
| | |
|
| | | // Setting ComVisible to false makes the types in this assembly not visible
|
| | | // to COM components. If you need to access a type in this assembly from
|
| | | // COM, set the ComVisible attribute to true on that type.
|
| | | [assembly: ComVisible(false)]
|
| | |
|
| | | // The following GUID is for the ID of the typelib if this project is exposed to COM
|
| | | [assembly: Guid("a618d28b-9352-44f4-aa71-609bf68bf871")]
|
| | |
|
| | | // Version information for an assembly consists of the following four values:
|
| | | //
|
| | | // Major Version
|
| | | // Minor Version
|
| | | // Build Number
|
| | | // Revision
|
| | | //
|
| | | // You can specify all the values or you can default the Build and Revision Numbers
|
| | | // by using the '*' as shown below:
|
| | | // [assembly: AssemblyVersion("1.0.*")]
|
| | | [assembly: AssemblyVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>")]
|
| | | [assembly: AssemblyFileVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY_FILE#>")]
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
| | | <PropertyGroup>
|
| | | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
| | | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
| | | <SchemaVersion>2.0</SchemaVersion>
|
| | | <OutputType>Library</OutputType>
|
| | | <AppDesignerFolder>Properties</AppDesignerFolder>
|
| | | <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
| | | <RootNamespace>QtMSBuild</RootNamespace>
|
| | | <AssemblyName>QtMSBuild</AssemblyName>
|
| | | <ProjectGuid>{A618D28B-9352-44F4-AA71-609BF68BF871}</ProjectGuid>
|
| | | <FileAlignment>512</FileAlignment>
|
| | | <Deterministic>true</Deterministic>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
| | | <DebugSymbols>true</DebugSymbols>
|
| | | <DebugType>full</DebugType>
|
| | | <Optimize>false</Optimize>
|
| | | <OutputPath>bin\Debug\</OutputPath>
|
| | | <DefineConstants>DEBUG;TRACE</DefineConstants>
|
| | | <ErrorReport>prompt</ErrorReport>
|
| | | <WarningLevel>4</WarningLevel>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
| | | <DebugType>pdbonly</DebugType>
|
| | | <Optimize>true</Optimize>
|
| | | <OutputPath>bin\Release\</OutputPath>
|
| | | <DefineConstants>TRACE</DefineConstants>
|
| | | <ErrorReport>prompt</ErrorReport>
|
| | | <WarningLevel>4</WarningLevel>
|
| | | </PropertyGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Global references
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
| | | <Reference Include="System" />
|
| | | <Reference Include="$(VCTargetsPath)\Application Type\Linux\1.0\Microsoft.Build.Linux.Tasks.dll" />
|
| | | <Reference Include="$(VCTargetsPath)\Application Type\Linux\1.0\liblinux.dll" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific references
|
| | | // -->
|
| | | <Import Project="$(SolutionDir)\references.props" />
|
| | | <ItemGroup>
|
| | | <PackageReference Include="Microsoft.Build"
|
| | | Version="$(Version_Microsoft_Build)" />
|
| | | <PackageReference Include="Microsoft.Build.Framework"
|
| | | Version="$(Version_Microsoft_Build_Framework)" />
|
| | | <PackageReference Include="Microsoft.Build.Tasks.Core"
|
| | | Version="$(Version_Microsoft_Build_Tasks_Core)" />
|
| | | <PackageReference Include="Microsoft.Bcl.AsyncInterfaces"
|
| | | Version="$(Version_Microsoft_Bcl_AsyncInterfaces)" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Solution project references
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <ProjectReference Include="..\QtVsTools.RegExpr\QtVsTools.RegExpr.csproj">
|
| | | <Project>{a2831b9b-4d3b-46cb-85df-1b5c277c17db}</Project>
|
| | | <Name>QtVsTools.RegExpr</Name>
|
| | | </ProjectReference>
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Project items
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <T4Template Include="Properties\AssemblyInfo.cs">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>Properties\AssemblyInfo.tt.cs</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>AssemblyInfo.tt.cs</LastGenOutput>
|
| | | </T4Template>
|
| | | <Compile Include="ITaskLoggingHelper.cs" />
|
| | | <Compile Include="Properties\AssemblyInfo.tt.cs">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>AssemblyInfo.cs</DependentUpon>
|
| | | </Compile>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild common property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\qt_defaults.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\Qt.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_private.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_settings.xml">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_settings.targets">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_globals.targets">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_vars.targets">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild moc property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\moc\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\moc\qtmoc.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\moc\qtmoc.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\moc\qtmoc.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <T4Template Include="QtMSBuild\moc\qtmoc_v3.xml_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>moc\qtmoc_v3.xml</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>qtmoc_v3.xml</LastGenOutput>
|
| | | <SubType>Designer</SubType>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\moc\qtmoc_v3.xml">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qtmoc_v3.xml_TT</DependentUpon>
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <T4Template Include="QtMSBuild\moc\qtmoc_cl.targets_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>moc\qtmoc_cl.targets</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <SubType>Designer</SubType>
|
| | | <LastGenOutput>qtmoc_cl.targets</LastGenOutput>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\moc\qtmoc_cl.targets">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qtmoc_cl.targets_TT</DependentUpon>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild qml property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\qml\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qml\qtqml.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qml\qtqml.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qml\qtqml_cache.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qml\qtqml_cache.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qml\qtqml_static.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qml\qtqml_static.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild rcc property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\rcc\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\rcc\qtrcc.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\rcc\qtrcc.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\rcc\qtrcc.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <T4Template Include="QtMSBuild\rcc\qtrcc_v3.xml_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>rcc\qtrcc_v3.xml</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>qtrcc_v3.xml</LastGenOutput>
|
| | | <SubType>Designer</SubType>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\rcc\qtrcc_v3.xml">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qtrcc_v3.xml_TT</DependentUpon>
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <T4Template Include="QtMSBuild\rcc\qtrcc_cl.targets_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>rcc\qtrcc_cl.targets</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <SubType>Designer</SubType>
|
| | | <LastGenOutput>qtrcc_cl.targets</LastGenOutput>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\rcc\qtrcc_cl.targets">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qtrcc_cl.targets_TT</DependentUpon>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild repc property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\repc\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\repc\qtrepc.props">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\repc\qtrepc.targets">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\repc\qtrepc.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <T4Template Include="QtMSBuild\repc\qtrepc_v3.xml_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>repc\qtrepc_v3.xml</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>qtrepc_v3.xml</LastGenOutput>
|
| | | <SubType>Designer</SubType>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\repc\qtrepc_v3.xml">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qtrepc_v3.xml_TT</DependentUpon>
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <T4Template Include="QtMSBuild\repc\qtrepc_cl.targets_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>repc\qtrepc_cl.targets</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <SubType>Designer</SubType>
|
| | | <LastGenOutput>qtrepc_cl.targets</LastGenOutput>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\repc\qtrepc_cl.targets">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qtrepc_cl.targets_TT</DependentUpon>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild uic property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\uic\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\uic\qtuic.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\uic\qtuic.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\uic\qtuic.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\uic\qtuic_v3.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild deploy properties and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\deploy\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\deploy\qtdeploy.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\deploy\qtdeploy.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\deploy\qtdeploy.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild translation tools property pages and targets
|
| | | // -->
|
| | | <Content Include="QtMSBuild\translation\qttranslation.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\translation\qttranslation.targets">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\translation\qttranslation.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\translation\qt_import.props">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Inline tasks
|
| | | // -->
|
| | | <Compile Include="Tasks\CriticalSection.cs" />
|
| | | <Compile Include="Tasks\GetVarsFromMSBuild.cs" />
|
| | | <Compile Include="Tasks\HostExec_LinuxWSL_Error.cs" />
|
| | | <Compile Include="Tasks\HostTranslatePaths_LinuxWSL_Error.cs" />
|
| | | <Compile Include="Tasks\ListQrc.cs" />
|
| | | <Compile Include="Tasks\ParseVarDefs.cs" />
|
| | | <Compile Include="Tasks\GetVarsFromMakefile.cs" />
|
| | | <Compile Include="Tasks\QtRunWork.cs" />
|
| | | <Compile Include="Tasks\GetItemHash.cs" />
|
| | | <Compile Include="Tasks\Flatten.cs" />
|
| | | <Compile Include="Tasks\Expand.cs" />
|
| | | <Compile Include="Tasks\Join.cs" />
|
| | | <Compile Include="Tasks\DumpItems.cs" />
|
| | | <Compile Include="Tasks\HostTranslatePaths_Windows.cs" />
|
| | | <Compile Include="Tasks\HostExec_Windows.cs" />
|
| | | <Compile Include="Tasks\HostTranslatePaths_LinuxSSL.cs" />
|
| | | <Compile Include="Tasks\HostExec_LinuxSSL.cs" />
|
| | | <Compile Include="Tasks\HostTranslatePaths_LinuxWSL.cs" />
|
| | | <Compile Include="Tasks\HostExec_LinuxWSL.cs" />
|
| | | <T4Template Include="QtMSBuild\qt_tasks.targets_TT">
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>qt_tasks.targets</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <SubType>Designer</SubType>
|
| | | <LastGenOutput>qt_tasks.targets</LastGenOutput>
|
| | | </T4Template>
|
| | | <Content Include="QtMSBuild\qt_tasks.targets">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>qt_tasks.targets_TT</DependentUpon>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <T4Template Include="$(SolutionDir)\vstools.pri_TT">
|
| | | <Link>vstools.pri_TT</Link>
|
| | | <Generator>TextTemplatingFileGenerator</Generator>
|
| | | <OutputFile>$(SolutionDir)\vstools.pri</OutputFile>
|
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>vstools.pri</LastGenOutput>
|
| | | <SubType>Designer</SubType>
|
| | | </T4Template>
|
| | | <None Include="$(SolutionDir)\vstools.pri">
|
| | | <Link>vstools.pri</Link>
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>vstools.pri_TT</DependentUpon>
|
| | | <SubType>Designer</SubType>
|
| | | </None>
|
| | | </ItemGroup>
|
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
| | | <Import Project="$(SolutionDir)\transform.targets" />
|
| | | </Project> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Item type definition and default values
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import private Qt property definitions
|
| | | // -->
|
| | | <ImportGroup Label="Qt">
|
| | | <Import Project="$(MSBuildThisFileDirectory)\qt_private.props"/>
|
| | | </ImportGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // User-defined settings
|
| | | // -->
|
| | | <PropertyGroup Label="UserMacros">
|
| | | <!-- Placeholder for user macros written by VS Property Manager -->
|
| | | </PropertyGroup>
|
| | | <PropertyGroup>
|
| | | <!-- Placeholder for properties written by VS Property Manager -->
|
| | | </PropertyGroup>
|
| | | <ItemDefinitionGroup>
|
| | | <!-- Placeholder for default metadata written by VS Property Manager -->
|
| | | </ItemDefinitionGroup>
|
| | | <ItemGroup>
|
| | | <!-- Placeholder for items written by VS Property Manager -->
|
| | | </ItemGroup>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild import
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtMsBuildProps>
|
| | | $(QtMsBuildProps);
|
| | | $(MSBuildThisFileDirectory)qtdeploy.props
|
| | | </QtMsBuildProps>
|
| | | <QtMsBuildTargets>
|
| | | $(QtMsBuildTargets);
|
| | | $(MSBuildThisFileDirectory)qtdeploy.targets
|
| | | </QtMsBuildTargets>
|
| | | </PropertyGroup>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Deployment of Qt dependencies
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <PropertyGroup>
|
| | | <QtDeploy Condition="'$(QtDeploy)' == ''">false</QtDeploy>
|
| | | </PropertyGroup>
|
| | | <ItemDefinitionGroup>
|
| | | <QtDeploy>
|
| | | <QtDeployFiles>$(TargetPath)</QtDeployFiles>
|
| | | <QtDeployDir Condition="'$(QtDeployToProjectDir)' == 'true'">$(ProjectDir)</QtDeployDir>
|
| | | <QtDeployDir Condition="'$(QtDeployToProjectDir)' != 'true'">$(OutDir)</QtDeployDir>
|
| | | <QtDeployLibDir/>
|
| | | <QtDeployPluginDir/>
|
| | | <QtDeployDebugRelease>false</QtDeployDebugRelease>
|
| | | <QtDeployPdb>false</QtDeployPdb>
|
| | | <QtDeployForce>false</QtDeployForce>
|
| | | <QtDeployNoPatchQt>false</QtDeployNoPatchQt>
|
| | | <QtDeployNoPlugins>false</QtDeployNoPlugins>
|
| | | <QtDeployNoLibraries>false</QtDeployNoLibraries>
|
| | | <QtDeployQmlDir/>
|
| | | <QtDeployQmlImport/>
|
| | | <QtDeployNoQuickImport>false</QtDeployNoQuickImport>
|
| | | <QtDeployNoTranslations>false</QtDeployNoTranslations>
|
| | | <QtDeployNoSystemD3dCompiler>false</QtDeployNoSystemD3dCompiler>
|
| | | <QtDeployNoVirtualKeyboard>false</QtDeployNoVirtualKeyboard>
|
| | | <QtDeployCompilerRuntime>false</QtDeployCompilerRuntime>
|
| | | <QtDeployWebkit2>false</QtDeployWebkit2>
|
| | | <QtDeployAngle>false</QtDeployAngle>
|
| | | <QtDeployNoOpenglSw>false</QtDeployNoOpenglSw>
|
| | | <QtDeployIncludeModules/>
|
| | | <QtDeployExcludeModules/>
|
| | | <QtDeployVerbose>false</QtDeployVerbose>
|
| | | <QtDeployVsContent Condition="'$(QtDeployVsContent)' == 'true'">true</QtDeployVsContent>
|
| | | <QtDeployVsContent Condition="'$(QtDeployVsContent)' != 'true'">false</QtDeployVsContent>
|
| | | </QtDeploy>
|
| | | </ItemDefinitionGroup>
|
| | | <ItemGroup Condition="'$(QtDeploy)' == 'true'">
|
| | | <ProjectTools Include="QtDeploy"/>
|
| | | </ItemGroup>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Deployment of Qt dependencies
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Setup property page
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <PropertyPageSchema
|
| | | Include="$(MSBuildThisFileDirectory)qtdeploy.xml" />
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Default deploy log location
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtDeployLog Condition="'$(QtDeployLog)' == ''">$(IntDir)windeployqt.log</QtDeployLog>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Schedule QtDeploy target to run after Link
|
| | | // -->
|
| | | <PropertyGroup Condition="'$(QtDeploy)' == 'true' AND '$(ApplicationType)' != 'Linux'">
|
| | | <BuildLinkTargets>$(BuildLinkTargets);QtDeploy</BuildLinkTargets>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Deploy Qt files
|
| | | // -->
|
| | | <Target Name="QtDeploy"
|
| | | AfterTargets="Link"
|
| | | Inputs="$(TargetPath)" Outputs="$(QtDeployLog)"
|
| | | Condition="'$(QtDeploy)' == 'true' AND '$(ApplicationType)' != 'Linux'">
|
| | |
|
| | | <ItemGroup>
|
| | | <QtDeploy Include="$(TargetPath)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Convert string lists in source item properties to lists of items
|
| | | // -->
|
| | | <Flatten Items="@(QtDeploy)"
|
| | | Metadata="QtDeployFiles;
|
| | | QtDeployDir;
|
| | | QtDeployLibDir;
|
| | | QtDeployPluginDir;
|
| | | QtDeployDebugRelease;
|
| | | QtDeployPdb;
|
| | | QtDeployForce;
|
| | | QtDeployNoPatchQt;
|
| | | QtDeployNoPlugins;
|
| | | QtDeployNoLibraries;
|
| | | QtDeployQmlDir;
|
| | | QtDeployQmlImport;
|
| | | QtDeployNoQuickImport;
|
| | | QtDeployNoTranslations;
|
| | | QtDeployNoSystemD3dCompiler;
|
| | | QtDeployNoVirtualKeyboard;
|
| | | QtDeployCompilerRuntime;
|
| | | QtDeployWebkit2;
|
| | | QtDeployAngle;
|
| | | QtDeployNoOpenglSw;
|
| | | QtDeployIncludeModules;
|
| | | QtDeployExcludeModules;
|
| | | QtDeployVerbose">
|
| | | <Output
|
| | | TaskParameter="Result" ItemName="Options" />
|
| | | </Flatten>
|
| | |
|
| | | <ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Remove quotes from all paths
|
| | | // -->
|
| | | <Options>
|
| | | <Value Condition="( '%(Name)' == 'QtDeployFiles'
|
| | | OR '%(Name)' == 'QtDeployDir'
|
| | | OR '%(Name)' == 'QtDeployLibDir'
|
| | | OR '%(Name)' == 'QtDeployPluginDir'
|
| | | OR '%(Name)' == 'QtDeployQmlDir'
|
| | | OR '%(Name)' == 'QtDeployQmlImport' )"
|
| | | >$([System.String]::Copy('%(Value)').Replace('"', ''))</Value>
|
| | | </Options>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Escape trailing back-slash in paths
|
| | | // -->
|
| | | <Options>
|
| | | <Value Condition="( '%(Name)' == 'QtDeployFiles'
|
| | | OR '%(Name)' == 'QtDeployDir'
|
| | | OR '%(Name)' == 'QtDeployLibDir'
|
| | | OR '%(Name)' == 'QtDeployPluginDir'
|
| | | OR '%(Name)' == 'QtDeployQmlDir'
|
| | | OR '%(Name)' == 'QtDeployQmlImport' )
|
| | | AND $([System.String]::Copy('%(Value)').Contains(' '))
|
| | | AND $([System.String]::Copy('%(Value)').EndsWith('\'))"
|
| | | >%(Value)\</Value>
|
| | | </Options>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Add quotes to paths containing spaces
|
| | | // -->
|
| | | <Options>
|
| | | <Value Condition="( '%(Name)' == 'QtDeployFiles'
|
| | | OR '%(Name)' == 'QtDeployDir'
|
| | | OR '%(Name)' == 'QtDeployLibDir'
|
| | | OR '%(Name)' == 'QtDeployPluginDir'
|
| | | OR '%(Name)' == 'QtDeployQmlDir'
|
| | | OR '%(Name)' == 'QtDeployQmlImport' )
|
| | | AND $([System.String]::Copy('%(Value)').Contains(' '))"
|
| | | >"%(Value)"</Value>
|
| | | </Options>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate tool command line arguments
|
| | | // -->
|
| | | <Options>
|
| | | <!-- [files] Binaries or directory containing the binary. -->
|
| | | <PosArg Condition="'%(Name)' == 'QtDeployFiles'">%(Value)</PosArg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -dir <directory> Use directory instead of binary directory. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployDir'">--dir %(Value)</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -libdir <path> Copy libraries to path. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployLibDir'">--libdir %(Value)</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -plugindir <path> Copy plugins to path. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployPluginDir'">--plugindir %(Value)</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -debug Assume debug binaries.
|
| | | -release Assume release binaries.-->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployDebugRelease' AND '%(Value)' == 'debug'"
|
| | | >--debug</Arg>
|
| | | <Arg Condition="'%(Name)' == 'QtDeployDebugRelease' AND '%(Value)' == 'release'"
|
| | | >--release</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -pdb Deploy .pdb files (MSVC). -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployPdb' AND '%(Value)' == 'true'"
|
| | | >--pdb</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -force Force updating files. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployForce' AND '%(Value)' == 'true'"
|
| | | >--force</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-patchqt Do not patch the Qt5Core library. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoPatchQt' AND '%(Value)' == 'true'"
|
| | | >--no-patchqt</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-plugins Skip plugin deployment. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoPlugins' AND '%(Value)' == 'true'"
|
| | | >--no-plugins</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-libraries Skip library deployment. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoLibraries' AND '%(Value)' == 'true'"
|
| | | >--no-libraries</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -qmldir <directory> Scan for QML-imports starting from directory. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployQmlDir'">--qmldir %(Value)</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -qmlimport <directory> Add the given path to the QML module search
|
| | | locations. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployQmlImport'">--qmlimport %(Value)</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-quick-import Skip deployment of Qt Quick imports. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoQuickImport' AND '%(Value)' == 'true'"
|
| | | >--no-quick-import</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-translations Skip deployment of translations. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoTranslations' AND '%(Value)' == 'true'"
|
| | | >--no-translations</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-system-d3d-compiler Skip deployment of the system D3D compiler. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoSystemD3dCompiler' AND '%(Value)' == 'true'"
|
| | | >--no-system-d3d-compiler</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-virtualkeyboard Disable deployment of the Virtual Keyboard. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoVirtualKeyboard' AND '%(Value)' == 'true'"
|
| | | >--no-virtualkeyboard</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -compiler-runtime Deploy compiler runtime (Desktop only).
|
| | | -no-compiler-runtime Do not deploy compiler runtime (Desktop only). -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployCompilerRuntime' AND '%(Value)' == 'deploy'"
|
| | | >--compiler-runtime</Arg>
|
| | | <Arg Condition="'%(Name)' == 'QtDeployCompilerRuntime' AND '%(Value)' == 'skip'"
|
| | | >--no-compiler-runtime</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -webkit2 Deployment of WebKit2 (web process).
|
| | | -no-webkit2 Skip deployment of WebKit2. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployWebkit2' AND '%(Value)' == 'deploy'"
|
| | | >--webkit2</Arg>
|
| | | <Arg Condition="'%(Name)' == 'QtDeployWebkit2' AND '%(Value)' == 'skip'"
|
| | | >--no-webkit2</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -angle Force deployment of ANGLE.
|
| | | -no-angle Disable deployment of ANGLE. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployAngle' AND '%(Value)' == 'deploy'"
|
| | | >--angle</Arg>
|
| | | <Arg Condition="'%(Name)' == 'QtDeployAngle' AND '%(Value)' == 'skip'"
|
| | | >--no-angle</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- -no-opengl-sw Do not deploy the software rasterizer library. -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployNoOpenglSw' AND '%(Value)' == 'true'"
|
| | | >--no-opengl-sw</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- Qt libraries can be added by passing their name (-xml) ... -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployIncludeModules'">-%(Value)</Arg>
|
| | | </Options>
|
| | | <Options>
|
| | | <!-- ... or removed by passing the name prepended by -no- (-no-xml). -->
|
| | | <Arg Condition="'%(Name)' == 'QtDeployExcludeModules'">--no-%(Value)</Arg>
|
| | | </Options>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run windeployqt
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <Cmd><![CDATA["$(QtToolsPath)\windeployqt.exe"]]></Cmd>
|
| | | <Cmd>$(Cmd) --list target</Cmd>
|
| | | <Cmd Condition="'%(Options.Arg)' != ''">$(Cmd) %(Options.Arg)</Cmd>
|
| | | <Cmd Condition="'%(Options.PosArg)' != ''">$(Cmd) %(Options.PosArg)</Cmd>
|
| | | </PropertyGroup>
|
| | | <Message Importance="high" Text="windeployqt: $(Cmd)" />
|
| | | <Exec Command="$(Cmd) > "$(QtDeployLog)"" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Read deploy log into QtDeployed list
|
| | | // -->
|
| | | <ReadLinesFromFile File="$(QtDeployLog)">
|
| | | <Output TaskParameter="Lines" ItemName="QtDeployed" />
|
| | | </ReadLinesFromFile>
|
| | | <ItemGroup>
|
| | | <QtDeployed Remove="@(QtDeployed)" Condition="!Exists('%(Fullpath)')"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Mark deployed files as source content for VS deployment project
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <None Include="@(QtDeployed)" Condition="'%(QtDeploy.QtDeployVsContent)' == 'true'">
|
| | | <DeploymentContent>true</DeploymentContent>
|
| | | <RootFolder>$(ProjectDir)</RootFolder>
|
| | | </None>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Log output files; used by VS on clean and up-to-date check
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <QtDeployLog Include="$(QtDeployLog)"/>
|
| | | <QtDeployed Include="$(QtDeployLog)"/>
|
| | | </ItemGroup>
|
| | | <WriteLinesToFile
|
| | | File="$(TLogLocation)windeployqt.read.1u.tlog"
|
| | | Lines="^$(ProjectPath)"
|
| | | Overwrite="true" Encoding="Unicode"/>
|
| | | <WriteLinesToFile
|
| | | File="$(TLogLocation)windeployqt.write.1u.tlog"
|
| | | Lines="^$(ProjectPath);@(QtDeployLog->'%(Fullpath)')"
|
| | | Overwrite="true" Encoding="Unicode"/>
|
| | | <WriteLinesToFile
|
| | | File="$(TLogLocation)$(ProjectName).write.1u.tlog"
|
| | | Lines="^$(ProjectFileName);@(QtDeployed->'%(Fullpath)')"
|
| | | Overwrite="false" Encoding="Unicode"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <Cmd/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <Options Remove="@(Options)"/>
|
| | | <QtDeploy Remove="@(QtDeploy)"/>
|
| | | <QtDeployLog Remove="@(QtDeployLog)"/>
|
| | | <QtDeployed Remove="@(QtDeployed)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // windeployqt Property Page
|
| | | //
|
| | | // -->
|
| | | <ProjectSchemaDefinitions
|
| | | xmlns="http://schemas.microsoft.com/build/2009/properties"
|
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
| | | <Rule
|
| | | Name="QtRule70_Deploy"
|
| | | PageTemplate="tool"
|
| | | DisplayName="Qt Deploy Tool"
|
| | | Order="999">
|
| | | <Rule.DataSource>
|
| | | <DataSource
|
| | | Persistence="UserFile"
|
| | | ItemType="QtDeploy"
|
| | | HasConfigurationCondition="true"/>
|
| | | </Rule.DataSource>
|
| | | <Rule.Categories>
|
| | | <Category Name="General" DisplayName="windeployqt"/>
|
| | | </Rule.Categories>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Application Binary
|
| | | // -->
|
| | | <StringListProperty
|
| | | Name="QtDeployFiles" DisplayName="Application Binary">
|
| | | <StringListProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Binaries or directory containing the application binary ( [files] ).]]>
|
| | | </sys:String>
|
| | | </StringListProperty.Description>
|
| | | </StringListProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Deployment Directory
|
| | | // -->
|
| | | <StringProperty
|
| | | Name="QtDeployDir" DisplayName="Deployment Directory">
|
| | | <StringProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Use directory instead of binary directory ( --dir <directory> ).]]>
|
| | | </sys:String>
|
| | | </StringProperty.Description>
|
| | | </StringProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Library Directory
|
| | | // -->
|
| | | <StringProperty
|
| | | Name="QtDeployLibDir" DisplayName="Library Directory">
|
| | | <StringProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Copy libraries to path ( --libdir <path> ).]]>
|
| | | </sys:String>
|
| | | </StringProperty.Description>
|
| | | </StringProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Plugin Directory
|
| | | // -->
|
| | | <StringProperty
|
| | | Name="QtDeployPluginDir" DisplayName="Plugin Directory">
|
| | | <StringProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Copy plugins to path ( --plugindir <path> ).]]>
|
| | | </sys:String>
|
| | | </StringProperty.Description>
|
| | | </StringProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Debug/Release Binaries
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployDebugRelease" DisplayName="Debug/Release Binaries">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Assume debug or release binaries ( --debug | --release ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Default"/>
|
| | | <EnumValue Name="debug" DisplayName="Debug ( --debug )"/>
|
| | | <EnumValue Name="release" DisplayName="Release ( --release )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Deploy PDB Files
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployPdb" DisplayName="Deploy PDB Files">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Deploy .pdb files (MSVC) ( --pdb ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --pdb )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployForce" DisplayName="Force Update">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Force updating files ( --force ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --force )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Qt5Core Patch
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoPatchQt" DisplayName="Skip Qt5Core Patch">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Do not patch the Qt5Core library ( --no-patchqt ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-patchqt )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Plugins
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoPlugins" DisplayName="Skip Plugins">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Skip plugin deployment ( --no-plugins ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-plugins )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Libraries
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoLibraries" DisplayName="Skip Libraries">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Skip library deployment ( --no-libraries ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-libraries )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QML Directories Root
|
| | | // -->
|
| | | <StringProperty
|
| | | Name="QtDeployQmlDir" DisplayName="QML Directories Root">
|
| | | <StringProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Scan for QML-imports starting from directory ( --qmldir <directory> ).]]>
|
| | | </sys:String>
|
| | | </StringProperty.Description>
|
| | | </StringProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QML Modules Path
|
| | | // -->
|
| | | <StringListProperty
|
| | | Name="QtDeployQmlImport" DisplayName="QML Modules Path">
|
| | | <StringListProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Add the given path to the QML module search locations ( --qmlimport <directory> ).]]>
|
| | | </sys:String>
|
| | | </StringListProperty.Description>
|
| | | </StringListProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Qt Quick Imports
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoQuickImport" DisplayName="Skip Qt Quick Imports">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Skip deployment of Qt Quick imports ( --no-quick-import ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-quick-import )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Translations
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoTranslations" DisplayName="Skip Translations">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Skip deployment of translations ( --no-translations ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-translations )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Direct3D Compiler
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoSystemD3dCompiler" DisplayName="Skip Direct3D Compiler">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Skip deployment of the system D3D compiler ( --no-system-d3d-compiler ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-system-d3d-compiler )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Virtual Keyboard
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoVirtualKeyboard" DisplayName="Skip Virtual Keyboard">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Disable deployment of the Virtual Keyboard ( --no-virtualkeyboard ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-virtualkeyboard )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Compiler Runtime
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployCompilerRuntime" DisplayName="Compiler Runtime">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Deploy compiler runtime (Desktop only).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Default"/>
|
| | | <EnumValue Name="deploy" DisplayName="Deploy ( --compiler-runtime )"/>
|
| | | <EnumValue Name="skip" DisplayName="Do Not Deploy ( --no-compiler-runtime )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // WebKit2 Deployment
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployWebkit2" DisplayName="WebKit2 Deployment">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Deployment of WebKit2 (web process).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Default"/>
|
| | | <EnumValue Name="deploy" DisplayName="Deploy ( --webkit2 )"/>
|
| | | <EnumValue Name="skip" DisplayName="Do Not Deploy ( --no-webkit2 )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // ANGLE Deployment
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployAngle" DisplayName="ANGLE Deployment">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Deployment of ANGLE.]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Default"/>
|
| | | <EnumValue Name="deploy" DisplayName="Deploy ( --angle )"/>
|
| | | <EnumValue Name="skip" DisplayName="Do Not Deploy ( --no-angle )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip Rasterizer Library
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployNoOpenglSw" DisplayName="Skip Rasterizer Library">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Do not deploy the software rasterizer library ( --no-opengl-sw ).]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enabled ( --no-opengl-sw )"/>
|
| | | </EnumProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Include Qt Libraries
|
| | | // -->
|
| | | <StringListProperty
|
| | | Name="QtDeployIncludeModules" DisplayName="Include Qt Libraries">
|
| | | <StringListProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Qt libraries can be added by passing their name ( -<name> ).]]>
|
| | | </sys:String>
|
| | | </StringListProperty.Description>
|
| | | </StringListProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Exclude Qt Libraries
|
| | | // -->
|
| | | <StringListProperty
|
| | | Name="QtDeployExcludeModules" DisplayName="Exclude Qt Libraries">
|
| | | <StringListProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Qt libraries can be removed by passing their prepended by --no- ( --no-<name> ).]]>
|
| | | </sys:String>
|
| | | </StringListProperty.Description>
|
| | | </StringListProperty>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set As Solution Deployment Content
|
| | | // -->
|
| | | <EnumProperty
|
| | | Name="QtDeployVsContent" DisplayName="Set As Solution Deployment Content">
|
| | | <EnumProperty.Description>
|
| | | <sys:String>
|
| | | <![CDATA[Mark deployed files as solution deployment content.]]>
|
| | | </sys:String>
|
| | | </EnumProperty.Description>
|
| | | <EnumValue Name="false" DisplayName="Disabled"/>
|
| | | <EnumValue Name="true" DisplayName="Enable"/>
|
| | | </EnumProperty>
|
| | | </Rule>
|
| | | </ProjectSchemaDefinitions>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild import
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtMsBuildProps>
|
| | | $(QtMsBuildProps);
|
| | | $(MSBuildThisFileDirectory)qtmoc.props
|
| | | </QtMsBuildProps>
|
| | | <QtMsBuildTargets>
|
| | | $(QtMsBuildTargets);
|
| | | $(MSBuildThisFileDirectory)qtmoc.targets
|
| | | </QtMsBuildTargets>
|
| | | </PropertyGroup>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild moc property definitions
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_BeforeMoc)' != ''"
|
| | | Project="$(QtMsBuildProps_BeforeMoc)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QtMoc item template
|
| | | // -->
|
| | | <ItemDefinitionGroup>
|
| | | <QtMoc>
|
| | | <ExecutionDescription>moc %(Identity)</ExecutionDescription>
|
| | |
|
| | | <QTDIR Condition="'$(QtVsProjectSettings)' != 'true'"
|
| | | >$(QTDIR)</QTDIR>
|
| | | <QTDIR Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >$(QtInstallDir)</QTDIR>
|
| | |
|
| | | <InputFile>%(FullPath)</InputFile>
|
| | |
|
| | | <OutputFile Condition="'$(QtVsProjectSettings)' != 'true'"
|
| | | >$(ProjectDir)GeneratedFiles\$(Configuration)\moc_%(Filename).cpp</OutputFile>
|
| | |
|
| | | <QtMocDir Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >$(IntDir)moc\</QtMocDir>
|
| | | <QtMocFileName Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >moc_%(Filename).cpp</QtMocFileName>
|
| | |
|
| | | <DynamicSource>output</DynamicSource>
|
| | | <ParallelProcess>true</ParallelProcess>
|
| | | <CommandLineTemplate>[AllOptions] [AdditionalOptions]</CommandLineTemplate>
|
| | | <Outputs>%(OutputFile)</Outputs>
|
| | | <OverrideClCompile>false</OverrideClCompile>
|
| | | </QtMoc>
|
| | | </ItemDefinitionGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_AfterMoc)' != ''"
|
| | | Project="$(QtMsBuildProps_AfterMoc)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Definitions specific to moc
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_BeforeMoc)' != ''"
|
| | | Project="$(QtMsBuildTargets_BeforeMoc)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild global properties
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtBuildTargets>QtMoc;$(QtBuildTargets)</QtBuildTargets>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Setup item type and property page
|
| | | // -->
|
| | | <Choose>
|
| | | <When Condition="'$(QtVsProjectSettings)' == 'true' AND '$(QtVsProjectClProperties)' == 'true'">
|
| | | <ItemGroup>
|
| | | <PropertyPageSchema
|
| | | Include="$(MSBuildThisFileDirectory)qtmoc_v3.xml" />
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <Otherwise>
|
| | | <ItemGroup Condition="'$(QtVsProjectSettings)' == 'false'">
|
| | | <PropertyPageSchema
|
| | | Include="$(MSBuildThisFileDirectory)qtmoc.xml" />
|
| | | </ItemGroup>
|
| | | </Otherwise>
|
| | | </Choose>
|
| | | <ItemGroup>
|
| | | <AvailableItemName Include="QtMoc">
|
| | | <Targets>Qt;_ClCompile</Targets>
|
| | | </AvailableItemName>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <QtMocRuleName>QtRule30_Moc</QtMocRuleName>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtMocInit
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Initialize default metadata
|
| | | // -->
|
| | | <Target Name="QtMocInit">
|
| | | <!--// Initialize %(OutputFile) -->
|
| | | <ItemGroup Condition="'$(QtVsProjectSettings)' == 'true' AND '@(QtMoc)' != ''">
|
| | | <QtMocAux Include="@(QtMoc)">
|
| | | <OutputFile
|
| | | >$([System.IO.Path]::Combine('%(QtMoc.QtMocDir)','%(QtMoc.QtMocFileName)'))</OutputFile>
|
| | | </QtMocAux>
|
| | | <QtMoc Remove="@(QtMoc)"/>
|
| | | <QtMoc Include="@(QtMocAux)"/>
|
| | | <QtMocAux Remove="@(QtMocAux)"/>
|
| | | </ItemGroup>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Add moc output dir to C++ include path
|
| | | // -->
|
| | | <ItemGroup Condition="'@(QtMoc)' != ''">
|
| | | <QtIncludePath Include="$([System.IO.Path]::GetDirectoryName('%(QtMoc.OutputFile)'))"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtMocPrepare
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Prepare to process sources
|
| | | // -->
|
| | | <Target Name="QtMocPrepare" DependsOnTargets="QtMocInit"
|
| | | Inputs="%(QtMoc.Identity)" Outputs="@(QtMoc->'####### Don't skip this target #######')">
|
| | | <ItemGroup>
|
| | | <selected_files Include="$(SelectedFiles)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtMocPrepare @(QtMoc)"/>
|
| | |
|
| | | <PropertyGroup>
|
| | | <selected_files>[@(selected_files->'%(Identity)','][')]</selected_files>
|
| | | <file>[@(QtMoc->'%(Identity)')]</file>
|
| | | <output_file>@(QtMoc->'%(OutputFile)')</output_file>
|
| | | <is_selected Condition="$(selected_files.Contains('$(file)'))">true</is_selected>
|
| | | <is_selected Condition="!$(selected_files.Contains('$(file)'))">false</is_selected>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Delete output file to force build of source if it was manually selected to build
|
| | | // (e.g. by the 'Compile' option in the context menu for the file) -->
|
| | | <Delete Files="$(output_file)"
|
| | | Condition="'$(SelectedFiles)' != '' AND '$(is_selected)' == 'true'" />
|
| | |
|
| | | <!--// If a source was manually selected to build, remove all other sources -->
|
| | | <ItemGroup Condition="'@(selected_files)' != ''">
|
| | | <QtMoc Remove="@(QtMoc)"
|
| | | Condition="'$(SelectedFiles)' != '' AND '$(is_selected)' != 'true'" />
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// Remove sources excluded from build -->
|
| | | <ItemGroup>
|
| | | <QtMoc Remove="@(QtMoc)"
|
| | | Condition="'$(SelectedFiles)' == '' AND '%(QtMoc.ExcludedFromBuild)' == 'true'"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <PropertyGroup>
|
| | | <selected_files/>
|
| | | <file/>
|
| | | <output_file/>
|
| | | <is_selected/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtMocSetModified
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set InputChanged flag if source file or dependencies have been modified
|
| | | // -->
|
| | | <Target Name="QtMocSetModified" DependsOnTargets="QtMocPrepare"
|
| | | Condition="'@(QtMoc)' != ''"
|
| | | Inputs="%(QtMoc.FullPath);%(QtMoc.AdditionalDependencies)" Outputs="@(QtMoc->'%(OutputFile)')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtMocSetModified @(QtMoc)" />
|
| | |
|
| | | <CreateProperty Value="true">
|
| | | <Output TaskParameter="ValueSetByTask" PropertyName="input_changed" />
|
| | | </CreateProperty>
|
| | | <ItemGroup>
|
| | | <QtMoc>
|
| | | <InputChanged>$(input_changed)</InputChanged>
|
| | | </QtMoc>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtMocOverrideCpp
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // -->
|
| | | <Import Project="qtmoc_cl.targets"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtMoc
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Process each source file and produce the corresponding QtWork items
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtMocDependsOn>
|
| | | QtPrepare;
|
| | | QtMocPrepare;
|
| | | QtMocSetModified;
|
| | | QtMocOverrideCpp;
|
| | | $(QtMocDependsOn)
|
| | | </QtMocDependsOn>
|
| | | </PropertyGroup>
|
| | | <Target Name="QtMoc"
|
| | | DependsOnTargets="$(QtMocDependsOn)"
|
| | | BeforeTargets="$(QtMocBeforeTargets)" AfterTargets="$(QtMocAfterTargets)"
|
| | | Condition="'@(QtMoc)' != ''"
|
| | | Inputs="%(QtMoc.FullPath);%(QtMoc.AdditionalDependencies);$(MSBuildProjectFile)"
|
| | | Outputs="@(QtMoc->'%(OutputFile)')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="## QtMoc @(QtMoc)" />
|
| | |
|
| | | <CreateProperty Value="true">
|
| | | <Output TaskParameter="ValueSetByTask" PropertyName="dependencies_changed" />
|
| | | </CreateProperty>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Convert string lists in source item properties to lists of items
|
| | | // -->
|
| | | <Flatten Items="@(QtMoc)"
|
| | | Metadata="InputFile;
|
| | | OutputFile;
|
| | | IncludePath;
|
| | | MacFramework;
|
| | | PreprocessOnly;
|
| | | Define;
|
| | | Undefine;
|
| | | Metadata;
|
| | | CompilerFlavor;
|
| | | NoInclude;
|
| | | PathPrefix;
|
| | | ForceInclude;
|
| | | PrependInclude;
|
| | | Include;
|
| | | NoNotesWarnings;
|
| | | NoNotes;
|
| | | NoWarnings;
|
| | | IgnoreConflicts;
|
| | | OptionsFile">
|
| | | <Output
|
| | | TaskParameter="Result" ItemName="LocalOptions" />
|
| | | </Flatten>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Translate local paths to build host paths
|
| | | // -->
|
| | | <HostTranslatePaths
|
| | | Items="@(LocalOptions)"
|
| | | Names="InputFile;
|
| | | OutputFile;
|
| | | IncludePath;
|
| | | MacFramework;
|
| | | PathPrefix;
|
| | | ForceInclude;
|
| | | PrependInclude;
|
| | | Include;
|
| | | OptionsFile">
|
| | | <Output
|
| | | TaskParameter="Result" ItemName="options" />
|
| | | </HostTranslatePaths>
|
| | |
|
| | | <ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Escape double-quotes in macro definitions
|
| | | // -->
|
| | | <options>
|
| | | <Value Condition="('%(Name)' == 'Define' OR '%(Name)' == 'Undefine')
|
| | | AND ($([System.String]::Copy('%(Value)').Contains(' '))
|
| | | OR $([System.String]::Copy('%(Value)').Contains('"')))"
|
| | | > "$([System.String]::Copy('%(Value)').Replace('"', '\"'))"</Value>
|
| | | </options>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Remove quotes from all paths
|
| | | // Escape trailing back-slash in paths
|
| | | // Add quotes to paths containing spaces
|
| | | // -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'InputFile' OR '%(Name)' == 'OutputFile'
|
| | | OR '%(Name)' == 'IncludePath' OR '%(Name)' == 'MacFramework' OR '%(Name)' == 'PathPrefix'
|
| | | OR '%(Name)' == 'ForceInclude' OR '%(Name)' == 'PrependInclude' OR '%(Name)' == 'Include'
|
| | | OR '%(Name)' == 'OptionsFile'"
|
| | | >$([System.String]::Copy('%(Value)').Replace('"', ''))</Value>
|
| | | </options>
|
| | |
|
| | | <options>
|
| | | <Value Condition="('%(Name)' == 'InputFile' OR '%(Name)' == 'OutputFile'
|
| | | OR '%(Name)' == 'IncludePath' OR '%(Name)' == 'MacFramework' OR '%(Name)' == 'PathPrefix'
|
| | | OR '%(Name)' == 'ForceInclude' OR '%(Name)' == 'PrependInclude' OR '%(Name)' == 'Include'
|
| | | OR '%(Name)' == 'OptionsFile')
|
| | | AND $([System.String]::Copy('%(Value)').Contains(' '))
|
| | | AND $([System.String]::Copy('%(Value)').EndsWith('\'))"
|
| | | >%(Value)\</Value>
|
| | | </options>
|
| | |
|
| | | <options>
|
| | | <Value Condition="('%(Name)' == 'InputFile' OR '%(Name)' == 'OutputFile'
|
| | | OR '%(Name)' == 'IncludePath' OR '%(Name)' == 'MacFramework' OR '%(Name)' == 'PathPrefix'
|
| | | OR '%(Name)' == 'ForceInclude' OR '%(Name)' == 'PrependInclude' OR '%(Name)' == 'Include'
|
| | | OR '%(Name)' == 'OptionsFile')
|
| | | AND $([System.String]::Copy('%(Value)').Contains(' '))"
|
| | | >"%(Value)"</Value>
|
| | | </options>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate tool command line arguments
|
| | | // -->
|
| | | <!--// [header-file] Header file to read from -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'InputFile'">%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -o <file> Write output to file -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'OutputFile'">-o %(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -I <dir> Add dir to the include path for header files -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'IncludePath'">-I%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -F <framework> Add macOS framework to the include path for headers -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'MacFramework'">-F %(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -E Preprocess only; do not generate meta object code -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'PreprocessOnly' AND '%(Value)' != 'true'"></Value>
|
| | | </options>
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'PreprocessOnly' AND '%(Value)' == 'true'">-E</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -D <macro[=def]> Define macro, with optional definition -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'Define'">-D%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -U <macro> Undefine macro-->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'Undefine'">-U%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -M <key=value> Add key/value pair to plugin meta data -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'Metadata'">-M%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -compiler-flavor <flavor> Set the compiler flavor: either "msvc" or "unix" -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'CompilerFlavor'">--compiler-flavor %(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -i Do not generate an #include statement -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoInclude' AND '%(Value)' != 'true'"></Value>
|
| | | </options>
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoInclude' AND '%(Value)' == 'true'">-i</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -p <path> Path prefix for included file -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'PathPrefix'">-p%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -f <file> Force #include <file> (overwrite default) -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'ForceInclude'">-f %(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -b <file> Prepend #include <file> (preserve default include) -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'PrependInclude'">-b %(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -include <file> Parse <file> as an #include before the main source(s) -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'Include'">--include %(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -n <which> Do not display notes (-nn) or warnings (-nw) -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoNotesWarnings'">-n%(Value)</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -no-notes Do not display notes -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoNotes' AND '%(Value)' != 'true'"></Value>
|
| | | </options>
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoNotes' AND '%(Value)' == 'true'">--no-notes</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -no-warnings Do not display warnings (implies -no-notes) -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoWarnings' AND '%(Value)' != 'true'"></Value>
|
| | | </options>
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'NoWarnings' AND '%(Value)' == 'true'">--no-warnings</Value>
|
| | | </options>
|
| | |
|
| | | <!--// -ignore-option-clashes Ignore all options that conflict with compilers -->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'IgnoreConflicts' AND '%(Value)' != 'true'"></Value>
|
| | | </options>
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'IgnoreConflicts' AND '%(Value)' == 'true'"
|
| | | >--ignore-option-clashes</Value>
|
| | | </options>
|
| | |
|
| | | <!--// [@option-file] Read additional options from option-file-->
|
| | | <options>
|
| | | <Value Condition="'%(Name)' == 'OptionsFile'">@%(Value)</Value>
|
| | | </options>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <options>@(options->'%(Value)', ' ')</options>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Aux properties
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <!--// Force modified flag if source was manually selected to build -->
|
| | | <input_changed Condition="'$(SelectedFiles)' != ''"
|
| | | >true</input_changed>
|
| | | <input_changed Condition="'$(SelectedFiles)' == ''"
|
| | | >%(QtMoc.InputChanged)</input_changed>
|
| | |
|
| | | <!--// Run work in parallel processes -->
|
| | | <run_parallel Condition="'@(QtMoc)' != ''
|
| | | AND '%(QtMoc.ParallelProcess)' == 'true'
|
| | | AND '$(SelectedFiles)' == ''"
|
| | | >true</run_parallel>
|
| | |
|
| | | <!--// Run work in single process -->
|
| | | <run_single Condition="'@(QtMoc)' != ''
|
| | | AND ('%(QtMoc.ParallelProcess)' != 'true'
|
| | | OR '$(SelectedFiles)' != '')"
|
| | | >true</run_single>
|
| | |
|
| | | <!--// Get relative path to output -->
|
| | | <output_relative
|
| | | >$([MSBuild]::MakeRelative($(ProjectDir), %(QtMoc.OutputFile)).TrimStart('\'))</output_relative>
|
| | |
|
| | | <!--// Get relative path to input -->
|
| | | <input_relative
|
| | | >$([MSBuild]::MakeRelative($(ProjectDir), %(QtMoc.InputFile)).TrimStart('\'))</input_relative>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Create work item
|
| | | // -->
|
| | | <ItemGroup Condition="'$(run_parallel)' == 'true' OR '$(run_single)' == 'true'">
|
| | | <QtWork Include="@(QtMoc)">
|
| | | <WorkType>moc</WorkType>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >$(QtToolsPath)/moc</ToolPath>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' != 'true'"
|
| | | >%(QtMoc.QTDIR)\bin\moc.exe</ToolPath>
|
| | | <Options>$(options)</Options>
|
| | | <Message>%(QtMoc.ExecutionDescription)</Message>
|
| | | <DependenciesChanged>$(dependencies_changed)</DependenciesChanged>
|
| | | <InputChanged>$(input_changed)</InputChanged>
|
| | | <ParallelBuild Condition="'$(run_parallel)' == 'true'">true</ParallelBuild>
|
| | | <ParallelBuild Condition="'$(run_single)' == 'true'">false</ParallelBuild>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////
|
| | | // C++ dynamic source -->
|
| | | <ClCompile Condition="'%(QtMoc.DynamicSource)' == 'output'">$(output_relative)</ClCompile>
|
| | | <ClCompile Condition="'%(QtMoc.DynamicSource)' == 'input'">$(input_relative)</ClCompile>
|
| | | </QtWork>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <options/>
|
| | | <dependencies_changed/>
|
| | | <input_changed/>
|
| | | <run_parallel/>
|
| | | <run_single/>
|
| | | <output_relative/>
|
| | | <input_relative/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <LocalOptions Remove="@(LocalOptions)"/>
|
| | | <options Remove="@(options)"/>
|
| | | <selected_files Remove="@(selected_files)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_AfterMoc)' != ''"
|
| | | Project="$(QtMsBuildTargets_AfterMoc)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Defines the fields included in the moc property page, as well as any
|
| | | // other metadata associated to QtMoc items
|
| | | // -->
|
| | | <ProjectSchemaDefinitions
|
| | | xmlns="http://schemas.microsoft.com/build/2009/properties"
|
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
| | | <Rule
|
| | | Name="QtRule30_Moc"
|
| | | PageTemplate="tool"
|
| | | DisplayName="Qt Meta-Object Compiler"
|
| | | Order="9">
|
| | | <Rule.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType="QtMoc" />
|
| | | </Rule.DataSource>
|
| | | <Rule.Categories>
|
| | | <Category
|
| | | Name="General">
|
| | | <Category.DisplayName>
|
| | | <sys:String>moc.exe</sys:String>
|
| | | </Category.DisplayName>
|
| | | </Category>
|
| | | </Rule.Categories>
|
| | | <StringListProperty
|
| | | Name="Inputs"
|
| | | Category="General"
|
| | | IsRequired="true"
|
| | | Visible="False">
|
| | | <StringListProperty.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType="QtMoc"
|
| | | SourceType="Item" />
|
| | | </StringListProperty.DataSource>
|
| | | </StringListProperty>
|
| | | <StringProperty
|
| | | Name="ExecutionDescription"
|
| | | DisplayName="Execution Description"
|
| | | IncludeInCommandLine="False"/>
|
| | | <StringProperty
|
| | | Name="QTDIR"
|
| | | DisplayName="Qt Directory"
|
| | | Description="Path to installation of Qt."/>
|
| | | <StringProperty
|
| | | Name="InputFile"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Input File"
|
| | | Description="Specifies the full path of the input file. (<file>)"
|
| | | Switch=""[value]"" />
|
| | | <StringProperty
|
| | | Name="OutputFile"
|
| | | Category="General"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Output File"
|
| | | Description="Specifies the full path of the output file. (-o <file>)"
|
| | | Switch="-o "[value]"" />
|
| | | <StringListProperty
|
| | | Name="IncludePath"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Include Path"
|
| | | Description=
|
| | | "Add <dir> to the include path for header files; separate with semicolons if more than one.
|
| | | (-I<dir>)"
|
| | | Switch=""-I[value]"" />
|
| | | <StringProperty
|
| | | Name="MacFramework"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="macOS Framework"
|
| | | Description=
|
| | | "Add macOS <framework> to the include path for header files. (-F <framework>)"
|
| | | Switch="-F "[value]""
|
| | | Visible="False"/>
|
| | | <BoolProperty
|
| | | Name="PreprocessOnly"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Preprocess Only"
|
| | | Description="Preprocess only; do not generate meta object code. (-E)"
|
| | | Switch="-E"
|
| | | Visible="False"/>
|
| | | <StringListProperty
|
| | | Name="Define"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Macro Definitions"
|
| | | Description=
|
| | | "Define macro, with optional definition; separate with semicolons if more than one.
|
| | | (-D<macro>[=<def>])"
|
| | | Switch="-D " />
|
| | | <StringListProperty
|
| | | Name="Undefine"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Undefine Macro Definitions"
|
| | | Description="Undefine macro; separate with semicolons if more than one. (-U<macro>)"
|
| | | Switch="-U[value]" />
|
| | | <StringListProperty
|
| | | Name="Metadata"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Plugin Meta Data"
|
| | | Description=
|
| | | "Add key/value pair to plugin meta data; separate with semicolons if more than one.
|
| | | (-M<key=value>)"
|
| | | Switch="-M[value]" />
|
| | | <StringProperty
|
| | | Name="CompilerFlavor"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Compiler Flavor"
|
| | | Description=
|
| | | "Set the compiler <flavor>: either "msvc" or "unix".
|
| | | (--compiler-flavor <flavor>)"
|
| | | Switch="--compiler-flavor [value]"/>
|
| | | <BoolProperty
|
| | | Name="NoInclude"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Include"
|
| | | Description="Do not generate an #include statement. (-i)"
|
| | | Switch="-i"/>
|
| | | <StringProperty
|
| | | Name="PathPrefix"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Path Prefix"
|
| | | Description="<path> prefix for included file. (-p <path>)"
|
| | | Switch="-p [value]"/>
|
| | | <StringListProperty
|
| | | Name="ForceInclude"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Force Include"
|
| | | Description=
|
| | | "Force #include <file> (overwrite default); separate with semicolons if more than one.
|
| | | (-f <file>)"
|
| | | Switch="-f "[value]""/>
|
| | | <StringListProperty
|
| | | Name="PrependInclude"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Prepend Include"
|
| | | Description=
|
| | | "Prepend #include <file> (preserve default); separate with semicolons if more than one.
|
| | | (-b <file>)"
|
| | | Switch="-b "[value]""/>
|
| | | <StringListProperty
|
| | | Name="Include"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Include"
|
| | | Description=
|
| | | "Parse <file> as an #include before the main source(s); separate with semicolons if more
|
| | | than one. (--include <file>)"
|
| | | Switch="--include "[value]""/>
|
| | | <StringListProperty
|
| | | Name="NoNotesWarnings"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Notes Or Warnings"
|
| | | Description=
|
| | | "Do not display notes (-nn) or warnings (-nw); Compatibility option; separate with semicolons if
|
| | | more than one. (-n<n|w>)"
|
| | | Switch="-n[value]"
|
| | | Visible="False"/>
|
| | | <BoolProperty
|
| | | Name="NoNotes"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Notes"
|
| | | Description="Do not display notes. (--no-notes)"
|
| | | Switch="--no-notes"/>
|
| | | <BoolProperty
|
| | | Name="NoWarnings"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Warnings"
|
| | | Description="Do not display warnings (implies --no-notes). (--no-warnings)"
|
| | | Switch="--no-warnings"/>
|
| | | <BoolProperty
|
| | | Name="IgnoreConflicts"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Ignore Conflicts"
|
| | | Description=
|
| | | "Ignore all options that conflict with compilers, like -pthread conflicting with moc's -p option.
|
| | | (--ignore-option-clashes)"
|
| | | Switch="--ignore-option-clashes"/>
|
| | | <StringProperty
|
| | | Name="OptionsFile"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Options File"
|
| | | Description="Read additional command-line options from <file>. (@<file>)"
|
| | | Switch=""@[value]"" />
|
| | | <StringProperty
|
| | | Name="CommandLineTemplate"
|
| | | DisplayName="Command Line"
|
| | | Visible="False"
|
| | | IncludeInCommandLine="False" />
|
| | | <DynamicEnumProperty
|
| | | Name="QtMocBeforeTargets"
|
| | | Category="General"
|
| | | EnumProvider="Targets"
|
| | | IncludeInCommandLine="False" Visible="False">
|
| | | <DynamicEnumProperty.DisplayName>
|
| | | <sys:String>Execute Before</sys:String>
|
| | | </DynamicEnumProperty.DisplayName>
|
| | | <DynamicEnumProperty.Description>
|
| | | <sys:String>Specifies the targets for the build customization to run before.</sys:String>
|
| | | </DynamicEnumProperty.Description>
|
| | | <DynamicEnumProperty.ProviderSettings>
|
| | | <NameValuePair
|
| | | Name="Exclude"
|
| | | Value="^QtMocBeforeTargets|^Compute" />
|
| | | </DynamicEnumProperty.ProviderSettings>
|
| | | <DynamicEnumProperty.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType=""
|
| | | HasConfigurationCondition="true" />
|
| | | </DynamicEnumProperty.DataSource>
|
| | | </DynamicEnumProperty>
|
| | | <DynamicEnumProperty
|
| | | Name="QtMocAfterTargets"
|
| | | Category="General"
|
| | | EnumProvider="Targets"
|
| | | IncludeInCommandLine="False" Visible="False">
|
| | | <DynamicEnumProperty.DisplayName>
|
| | | <sys:String>Execute After</sys:String>
|
| | | </DynamicEnumProperty.DisplayName>
|
| | | <DynamicEnumProperty.Description>
|
| | | <sys:String>Specifies the targets for the build customization to run after.</sys:String>
|
| | | </DynamicEnumProperty.Description>
|
| | | <DynamicEnumProperty.ProviderSettings>
|
| | | <NameValuePair
|
| | | Name="Exclude"
|
| | | Value="^QtMocAfterTargets|^Compute" />
|
| | | </DynamicEnumProperty.ProviderSettings>
|
| | | <DynamicEnumProperty.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType=""
|
| | | HasConfigurationCondition="true" />
|
| | | </DynamicEnumProperty.DataSource>
|
| | | </DynamicEnumProperty>
|
| | | <StringListProperty
|
| | | Name="Outputs"
|
| | | DisplayName="Outputs"
|
| | | IncludeInCommandLine="False"
|
| | | Visible="False" />
|
| | | <StringListProperty
|
| | | Name="AdditionalDependencies"
|
| | | DisplayName="Additional Dependencies"
|
| | | IncludeInCommandLine="False"/>
|
| | | <StringProperty
|
| | | Subtype="AdditionalOptions"
|
| | | Name="AdditionalOptions"
|
| | | Category="General">
|
| | | <StringProperty.DisplayName>
|
| | | <sys:String>Additional Options</sys:String>
|
| | | </StringProperty.DisplayName>
|
| | | <StringProperty.Description>
|
| | | <sys:String>Additional Options</sys:String>
|
| | | </StringProperty.Description>
|
| | | </StringProperty>
|
| | | <EnumProperty
|
| | | Name="DynamicSource"
|
| | | DisplayName="Dynamic C++ Source"
|
| | | Description="Add file to list of C++ sources during build.">
|
| | | <EnumValue
|
| | | Name="output"
|
| | | DisplayName="Output File"
|
| | | Description="Use output as dynamic C++ source."/>
|
| | | <EnumValue
|
| | | Name="input"
|
| | | DisplayName="Input File"
|
| | | Description="Use input as dynamic C++ source."/>
|
| | | <EnumValue
|
| | | Name="false"
|
| | | DisplayName="Disable"
|
| | | Description="Disable dynamic source."/>
|
| | | </EnumProperty>
|
| | | <BoolProperty
|
| | | Name="ParallelProcess"
|
| | | DisplayName="Parallel Process"
|
| | | Description="Run tool in parallel process."/>
|
| | | </Rule>
|
| | | <ItemType
|
| | | Name="QtMoc"
|
| | | DisplayName="Qt Meta-Object Compiler (moc)" />
|
| | | <ContentType
|
| | | Name="QtMoc"
|
| | | DisplayName="Qt Meta-Object Compiler (moc)"
|
| | | ItemType="QtMoc" />
|
| | | </ProjectSchemaDefinitions>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | *****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | *****************************************************************************
|
| | | <#@output extension="targets" #>
|
| | | <#@include file="$(SolutionDir)\common.tt" #>
|
| | | <#@assembly Name="System.Xml" #>
|
| | | <#@assembly Name="System.Xml.Linq" #>
|
| | | <#@import namespace="System.Collections.Generic" #>
|
| | | <#@import namespace="System.Linq" #>
|
| | | <#@import namespace="System.Text" #>
|
| | | <#@import namespace="System.Xml" #>
|
| | | <#@import namespace="System.Xml.Linq" #>
|
| | | <#
|
| | | var pathRuleCl = Path.Combine(VC_TARGETS_PATH, "1033", "cl.xml");
|
| | | var xmlRule = XmlLoad(File.ReadAllText(pathRuleCl, Encoding.UTF8));
|
| | | #>
|
| | | ** <#=WARNING_GENERATED_FILE#>
|
| | | *****************************************************************************
|
| | | -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <Target Name="QtMocOverrideCpp" DependsOnTargets="QtMocPrepare;QtGetDefaultClCompile"
|
| | | Inputs="%(QtMoc.Identity)" Outputs="@(QtMoc->'####### Don't skip this target #######')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtMocOverrideCpp @(QtMoc)" />
|
| | |
|
| | | <PropertyGroup Condition="'$(QtVsProjectClProperties)' == 'true'">
|
| | | <override_cl_compile>%(QtMoc.OverrideClCompile)</override_cl_compile>
|
| | | </PropertyGroup>
|
| | |
|
| | | <ItemGroup Condition="'$(override_cl_compile)' == 'extend'">
|
| | | <QtMoc>
|
| | | <!-- BEGIN Generated Text <#=XML_COMMENT_END#>
|
| | | <#=
|
| | | XmlPrint(xmlRule.Elements()
|
| | | .Where(x => x.Name.ToString().Equals("StringListProperty"))
|
| | | .Where(x => (string)x.Attribute("Visible") != "false")
|
| | | .Where(x => (string)x.Attribute("Category") != "Command Line")
|
| | | .Where(x => !x.Descendants("DataSource").Any())
|
| | | .Select(x => new XElement((string)x.Attribute("Name"),
|
| | | string.Format(
|
| | | "@(ClCompile->WithMetadataValue('Identity','DefaultClCompile')->'%({0})');%(QtMoc.{0})",
|
| | | (string)x.Attribute("Name")))))
|
| | | #>
|
| | | <#=XML_COMMENT_BEGIN#> END Generated Text -->
|
| | | <AdditionalCppOptions
|
| | | Condition="'%(QtMoc.AdditionalCppOptions)' != ''"
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(AdditionalOptions)') %(QtMoc.AdditionalCppOptions)</AdditionalCppOptions>
|
| | | <AdditionalCppOptions
|
| | | Condition="'%(QtMoc.AdditionalCppOptions)' == ''"
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(AdditionalOptions)')</AdditionalCppOptions>
|
| | | </QtMoc>
|
| | | <QtMoc>
|
| | | <IncludePath>%(QtMoc.AdditionalIncludeDirectories)</IncludePath>
|
| | | <Define>%(QtMoc.PreprocessorDefinitions)</Define>
|
| | | <Undefine>%(QtMoc.UndefinePreprocessorDefinitions)</Undefine>
|
| | | </QtMoc>
|
| | | </ItemGroup>
|
| | |
|
| | | <ItemGroup Condition="'$(override_cl_compile)' == 'replace'">
|
| | | <QtMoc>
|
| | | <IncludePath Condition="'%(QtMoc.AdditionalIncludeDirectories)' != ''"
|
| | | >%(QtMoc.AdditionalIncludeDirectories)</IncludePath>
|
| | | <IncludePath Condition="'%(QtMoc.AdditionalIncludeDirectories)' == ''"
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity', 'DefaultClCompile')->
|
| | | '%(AdditionalIncludeDirectories)')</IncludePath>
|
| | | <Define Condition="'%(QtMoc.PreprocessorDefinitions)' != ''"
|
| | | >%(QtMoc.PreprocessorDefinitions)</Define>
|
| | | <Define Condition="'%(QtMoc.PreprocessorDefinitions)' == ''"
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(PreprocessorDefinitions)')</Define>
|
| | | <Undefine Condition="'%(QtMoc.UndefinePreprocessorDefinitions)' == ''"
|
| | | >%(QtMoc.UndefinePreprocessorDefinitions)</Undefine>
|
| | | <Undefine Condition="'%(QtMoc.UndefinePreprocessorDefinitions)' != ''"
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(UndefinePreprocessorDefinitions)')</Undefine>
|
| | | </QtMoc>
|
| | | </ItemGroup>
|
| | |
|
| | | <ItemGroup Condition="'$(override_cl_compile)' == 'false'">
|
| | | <QtMoc>
|
| | | <!-- BEGIN Generated Text <#=XML_COMMENT_END#>
|
| | | <#=
|
| | | XmlPrint(xmlRule.Elements()
|
| | | .Where(x => x.Name.ToString().EndsWith("Property"))
|
| | | .Where(x => (string)x.Attribute("Visible") != "false")
|
| | | .Where(x => (string)x.Attribute("Category") != "Command Line")
|
| | | .Where(x => !x.Descendants("DataSource").Any())
|
| | | .Select(x => new XElement((string)x.Attribute("Name"),
|
| | | new XAttribute("Condition",
|
| | | string.Format("'%(QtMoc.{0})' != ''", (string)x.Attribute("Name"))),
|
| | | string.Format(
|
| | | "@(ClCompile->WithMetadataValue('Identity','DefaultClCompile')->'%({0})')",
|
| | | (string)x.Attribute("Name")))))
|
| | | #>
|
| | | <#=XML_COMMENT_BEGIN#> END Generated Text -->
|
| | | <IncludePath
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(AdditionalIncludeDirectories)')</IncludePath>
|
| | | <Define
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(PreprocessorDefinitions)')</Define>
|
| | | <Undefine
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(UndefinePreprocessorDefinitions)')</Undefine>
|
| | | <AdditionalCppOptions
|
| | | >@(ClCompile->
|
| | | WithMetadataValue('Identity','DefaultClCompile')->
|
| | | '%(AdditionalOptions)')</AdditionalCppOptions>
|
| | | </QtMoc>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <override_cl_compile/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | *****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | *****************************************************************************
|
| | | <#@output extension="xml" #>
|
| | | <#@include file="$(SolutionDir)\common.tt" #>
|
| | | <#@assembly Name="System.Xml" #>
|
| | | <#@assembly Name="System.Xml.Linq" #>
|
| | | <#@import namespace="System.Collections.Generic" #>
|
| | | <#@import namespace="System.Linq" #>
|
| | | <#@import namespace="System.Text" #>
|
| | | <#@import namespace="System.Xml" #>
|
| | | <#@import namespace="System.Xml.Linq" #>
|
| | | <#
|
| | | var pathRuleCl = Path.Combine(VC_TARGETS_PATH, "1033", "cl.xml");
|
| | | var xmlRule = XmlLoad(File.ReadAllText(pathRuleCl, Encoding.UTF8));
|
| | | var categoryNames = xmlRule
|
| | | .Elements("Rule.Categories")
|
| | | .Elements("Category")
|
| | | .Where(x => x.Attribute("Subtype") == null)
|
| | | .ToDictionary(
|
| | | x => (string)x.Attribute("Name"),
|
| | | x => (string)x.Attribute("DisplayName"));
|
| | | #>
|
| | | ** <#=WARNING_GENERATED_FILE#>
|
| | | *****************************************************************************
|
| | | -->
|
| | |
|
| | | <ProjectSchemaDefinitions
|
| | | xmlns="http://schemas.microsoft.com/build/2009/properties"
|
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
| | | <Rule
|
| | | Name="QtRule30_Moc"
|
| | | PageTemplate="tool"
|
| | | DisplayName="Qt Meta-Object Compiler"
|
| | | Order="9">
|
| | | <Rule.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType="QtMoc" />
|
| | | </Rule.DataSource>
|
| | | <Rule.Categories>
|
| | | <Category Name="General" DisplayName="moc"/>
|
| | | <Category Name="MocCpp" DisplayName="Override C/C++"/>
|
| | | </Rule.Categories>
|
| | | <StringListProperty
|
| | | Name="Inputs"
|
| | | Category="General"
|
| | | IsRequired="true"
|
| | | Visible="False">
|
| | | <StringListProperty.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType="QtMoc"
|
| | | SourceType="Item" />
|
| | | </StringListProperty.DataSource>
|
| | | </StringListProperty>
|
| | | <StringProperty
|
| | | Name="ExecutionDescription"
|
| | | DisplayName="Execution Description"
|
| | | IncludeInCommandLine="False"/>
|
| | | <StringProperty
|
| | | Name="QtMocDir"
|
| | | Category="General"
|
| | | DisplayName="Output Directory"
|
| | | Description="Specifies the path of the generated moc output directory."/>
|
| | | <StringProperty
|
| | | Name="QtMocFileName"
|
| | | Category="General"
|
| | | DisplayName="Output File Name"
|
| | | Description="Specifies the name of the generated moc output file."/>
|
| | | <StringProperty
|
| | | Name="QTDIR"
|
| | | DisplayName="Qt Directory"
|
| | | Visible="false"/>
|
| | | <StringProperty
|
| | | Name="InputFile"
|
| | | DisplayName="Input File"
|
| | | Visible="false"/>
|
| | | <StringProperty
|
| | | Name="OutputFile"
|
| | | DisplayName="Output File"
|
| | | Visible="false"/>
|
| | | <StringProperty
|
| | | Name="MacFramework"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="macOS Framework"
|
| | | Description=
|
| | | "Add macOS <framework> to the include path for header files. (-F <framework>)"
|
| | | Switch="-F "[value]""
|
| | | Visible="False"/>
|
| | | <BoolProperty
|
| | | Name="PreprocessOnly"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Preprocess Only"
|
| | | Description="Preprocess only; do not generate meta object code. (-E)"
|
| | | Switch="-E"
|
| | | Visible="False"/>
|
| | | <StringListProperty
|
| | | Name="Metadata"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Plugin Meta Data"
|
| | | Description=
|
| | | "Add key/value pair to plugin meta data; separate with semicolons if more than one.
|
| | | (-M<key=value>)"
|
| | | Switch="-M[value]" />
|
| | | <StringProperty
|
| | | Name="CompilerFlavor"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Compiler Flavor"
|
| | | Description=
|
| | | "Set the compiler <flavor>: either "msvc" or "unix".
|
| | | (--compiler-flavor <flavor>)"
|
| | | Switch="--compiler-flavor [value]"/>
|
| | | <BoolProperty
|
| | | Name="NoInclude"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Include"
|
| | | Description="Do not generate an #include statement. (-i)"
|
| | | Switch="-i"/>
|
| | | <StringProperty
|
| | | Name="PathPrefix"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Path Prefix"
|
| | | Description="<path> prefix for included file. (-p <path>)"
|
| | | Switch="-p [value]"/>
|
| | | <StringListProperty
|
| | | Name="ForceInclude"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Force Include"
|
| | | Description=
|
| | | "Force #include <file> (overwrite default); separate with semicolons if more than one.
|
| | | (-f <file>)"
|
| | | Switch="-f "[value]""/>
|
| | | <StringListProperty
|
| | | Name="PrependInclude"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Prepend Include"
|
| | | Description=
|
| | | "Prepend #include <file> (preserve default); separate with semicolons if more than one.
|
| | | (-b <file>)"
|
| | | Switch="-b "[value]""/>
|
| | | <StringListProperty
|
| | | Name="Include"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Include"
|
| | | Description=
|
| | | "Parse <file> as an #include before the main source(s); separate with semicolons if more
|
| | | than one. (--include <file>)"
|
| | | Switch="--include "[value]""/>
|
| | | <StringListProperty
|
| | | Name="NoNotesWarnings"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Notes Or Warnings"
|
| | | Description=
|
| | | "Do not display notes (-nn) or warnings (-nw); Compatibility option; separate with semicolons if
|
| | | more than one. (-n<n|w>)"
|
| | | Switch="-n[value]"
|
| | | Visible="False"/>
|
| | | <BoolProperty
|
| | | Name="NoNotes"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Notes"
|
| | | Description="Do not display notes. (--no-notes)"
|
| | | Switch="--no-notes"/>
|
| | | <BoolProperty
|
| | | Name="NoWarnings"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="No Warnings"
|
| | | Description="Do not display warnings (implies --no-notes). (--no-warnings)"
|
| | | Switch="--no-warnings"/>
|
| | | <BoolProperty
|
| | | Name="IgnoreConflicts"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Ignore Conflicts"
|
| | | Description=
|
| | | "Ignore all options that conflict with compilers, like -pthread conflicting with moc's -p option.
|
| | | (--ignore-option-clashes)"
|
| | | Switch="--ignore-option-clashes"/>
|
| | | <StringProperty
|
| | | Name="OptionsFile"
|
| | | HelpUrl="http://doc.qt.io/qt-5/moc.html"
|
| | | DisplayName="Options File"
|
| | | Description="Read additional command-line options from <file>. (@<file>)"
|
| | | Switch=""@[value]"" />
|
| | | <StringProperty
|
| | | Name="CommandLineTemplate"
|
| | | DisplayName="Command Line"
|
| | | Visible="False"
|
| | | IncludeInCommandLine="False" />
|
| | | <DynamicEnumProperty
|
| | | Name="QtMocBeforeTargets"
|
| | | Category="General"
|
| | | EnumProvider="Targets"
|
| | | IncludeInCommandLine="False" Visible="False">
|
| | | <DynamicEnumProperty.DisplayName>
|
| | | <sys:String>Execute Before</sys:String>
|
| | | </DynamicEnumProperty.DisplayName>
|
| | | <DynamicEnumProperty.Description>
|
| | | <sys:String>Specifies the targets for the build customization to run before.</sys:String>
|
| | | </DynamicEnumProperty.Description>
|
| | | <DynamicEnumProperty.ProviderSettings>
|
| | | <NameValuePair
|
| | | Name="Exclude"
|
| | | Value="^QtMocBeforeTargets|^Compute" />
|
| | | </DynamicEnumProperty.ProviderSettings>
|
| | | <DynamicEnumProperty.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType=""
|
| | | HasConfigurationCondition="true" />
|
| | | </DynamicEnumProperty.DataSource>
|
| | | </DynamicEnumProperty>
|
| | | <DynamicEnumProperty
|
| | | Name="QtMocAfterTargets"
|
| | | Category="General"
|
| | | EnumProvider="Targets"
|
| | | IncludeInCommandLine="False" Visible="False">
|
| | | <DynamicEnumProperty.DisplayName>
|
| | | <sys:String>Execute After</sys:String>
|
| | | </DynamicEnumProperty.DisplayName>
|
| | | <DynamicEnumProperty.Description>
|
| | | <sys:String>Specifies the targets for the build customization to run after.</sys:String>
|
| | | </DynamicEnumProperty.Description>
|
| | | <DynamicEnumProperty.ProviderSettings>
|
| | | <NameValuePair
|
| | | Name="Exclude"
|
| | | Value="^QtMocAfterTargets|^Compute" />
|
| | | </DynamicEnumProperty.ProviderSettings>
|
| | | <DynamicEnumProperty.DataSource>
|
| | | <DataSource
|
| | | Persistence="ProjectFile"
|
| | | ItemType=""
|
| | | HasConfigurationCondition="true" />
|
| | | </DynamicEnumProperty.DataSource>
|
| | | </DynamicEnumProperty>
|
| | | <StringListProperty
|
| | | Name="Outputs"
|
| | | DisplayName="Outputs"
|
| | | IncludeInCommandLine="False"
|
| | | Visible="False" />
|
| | | <StringListProperty
|
| | | Name="AdditionalDependencies"
|
| | | DisplayName="Additional Dependencies"
|
| | | IncludeInCommandLine="False"/>
|
| | | <StringProperty
|
| | | Subtype="AdditionalOptions"
|
| | | Name="AdditionalOptions"
|
| | | Category="General">
|
| | | <StringProperty.DisplayName>
|
| | | <sys:String>Additional Options</sys:String>
|
| | | </StringProperty.DisplayName>
|
| | | <StringProperty.Description>
|
| | | <sys:String>Additional Options</sys:String>
|
| | | </StringProperty.Description>
|
| | | </StringProperty>
|
| | | <EnumProperty
|
| | | Name="DynamicSource"
|
| | | DisplayName="Dynamic C++ Source"
|
| | | Description="Add file to list of C++ sources during build.">
|
| | | <EnumValue
|
| | | Name="output"
|
| | | DisplayName="Output File"
|
| | | Description="Use output as dynamic C++ source."/>
|
| | | <EnumValue
|
| | | Name="input"
|
| | | DisplayName="Input File"
|
| | | Description="Use input as dynamic C++ source."/>
|
| | | <EnumValue
|
| | | Name="false"
|
| | | DisplayName="Disable"
|
| | | Description="Disable dynamic source."/>
|
| | | </EnumProperty>
|
| | | <BoolProperty
|
| | | Name="ParallelProcess"
|
| | | DisplayName="Parallel Process"
|
| | | Description="Run tool in parallel process."/>
|
| | | <StringListProperty Name="IncludePath" Visible="false"/>
|
| | | <StringListProperty Name="Define" Visible="false"/>
|
| | | <StringListProperty Name="Undefine" Visible="false"/>
|
| | | <EnumProperty
|
| | | Name="OverrideClCompile"
|
| | | Category="MocCpp"
|
| | | DisplayName="Override C/C++ Properties"
|
| | | Description="Define how C/C++ properties are redefined for moc">
|
| | | <EnumValue Name="extend" DisplayName=
|
| | | "Extend (append override definitions to C/C++ list properties; replace other properties)"/>
|
| | | <EnumValue Name="replace" DisplayName=
|
| | | "Replace (use override definitions instead of C/C++ properties)"/>
|
| | | <EnumValue Name="false" DisplayName=
|
| | | "Disabled (use C/C++ properties; ignore override definitions)"/>
|
| | | </EnumProperty>
|
| | | <!-- BEGIN Generated Text <#=XML_COMMENT_END#>
|
| | | <#=
|
| | | XmlPrint(xmlRule.Elements()
|
| | | .Where(x => x.Name.ToString().EndsWith("Property"))
|
| | | .Where(x => (string)x.Attribute("Visible") != "false")
|
| | | .Where(x => (string)x.Attribute("Category") != "Command Line")
|
| | | .Where(x => !x.Descendants("DataSource").Any())
|
| | | .GroupBy(x => (string)x.Attribute("Category"))
|
| | | .SelectMany(y => y.Select(x =>
|
| | | {
|
| | | x = new XElement(x);
|
| | | x.SetAttributeValue("Category", "MocCpp");
|
| | | x.SetAttributeValue("Description", "(overrides C/C++ property) "
|
| | | + (string)x.Attribute("Description"));
|
| | | return x;
|
| | | })
|
| | | .Prepend(new XElement("StringProperty",
|
| | | new XAttribute("Name", "QtCppHeader_" + y.Key.Replace(' ', '_')),
|
| | | new XAttribute("Category", "MocCpp"),
|
| | | new XAttribute("ReadOnly", "true"),
|
| | | new XAttribute("DisplayName", string.Format("{0} {1} {2}",
|
| | | new string('#', 10), categoryNames[y.Key], new string('#', 30)))))))
|
| | | #>
|
| | | <#=XML_COMMENT_BEGIN#> END Generated Text -->
|
| | | <StringProperty
|
| | | Name="AdditionalCppOptions"
|
| | | DisplayName="Additional Options"
|
| | | Description="Additional Options."
|
| | | Category="MocCpp"/>
|
| | | </Rule>
|
| | | <ItemType
|
| | | Name="QtMoc"
|
| | | DisplayName="Qt Meta-Object Compiler (moc)" />
|
| | | <ContentType
|
| | | Name="QtMoc"
|
| | | DisplayName="Qt Meta-Object Compiler (moc)"
|
| | | ItemType="QtMoc" />
|
| | | </ProjectSchemaDefinitions>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild import
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtMsBuildProps_AfterRcc>
|
| | | $(QtMsBuildProps_AfterRcc);
|
| | | $(MSBuildThisFileDirectory)qtqml.props;
|
| | | $(MSBuildThisFileDirectory)qtqml_cache.props;
|
| | | $(MSBuildThisFileDirectory)qtqml_static.props
|
| | | </QtMsBuildProps_AfterRcc>
|
| | | <QtMsBuildTargets_AfterRcc>
|
| | | $(QtMsBuildTargets_AfterRcc);
|
| | | $(MSBuildThisFileDirectory)qtqml.targets;
|
| | | $(MSBuildThisFileDirectory)qtqml_cache.targets;
|
| | | $(MSBuildThisFileDirectory)qtqml_static.targets
|
| | | </QtMsBuildTargets_AfterRcc>
|
| | | </PropertyGroup>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild QML property definitions
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_BeforeQml)' != ''"
|
| | | Project="$(QtMsBuildProps_BeforeQml)"/>
|
| | |
|
| | | <!-- Default QML work dir = $(IntDir)\qml
|
| | | * can be overridden in property sheets -->
|
| | | <PropertyGroup>
|
| | | <QtQmlIntDir Condition="'$(QtQmlIntDir)' == ''"
|
| | | >$([System.IO.Path]::Combine('$(ProjectDir)', '$(IntDir)', 'qml'))</QtQmlIntDir>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_AfterQml)' != ''"
|
| | | Project="$(QtMsBuildProps_AfterQml)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QML targets
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_BeforeQml)' != ''"
|
| | | Project="$(QtMsBuildTargets_BeforeQml)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild global properties
|
| | | // * add QtQml to the list of targets to run during build
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtBuildTargets>$(QtBuildTargets);QtQml</QtBuildTargets>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QML build entry point
|
| | | // -->
|
| | | <Target Name="QtQml" DependsOnTargets="QtQmlCreateItems">
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Create QtQml items for project files with extension '.qml' or '.js'
|
| | | // -->
|
| | | <Target Name="QtQmlCreateItems">
|
| | | <ItemGroup>
|
| | | <QtQml Include="@(None)"
|
| | | Condition="'%(None.Extension)' == '.qml' OR '%(None.Extension)' == '.js'" />
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_AfterQml)' != ''"
|
| | | Project="$(QtMsBuildTargets_AfterQml)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild QML property definitions
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_BeforeQmlCache)' != ''"
|
| | | Project="$(QtMsBuildProps_BeforeQmlCache)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QtRcc item template, QML cache generation properties
|
| | | // -->
|
| | | <ItemDefinitionGroup>
|
| | | <QtRcc>
|
| | | <QmlCacheGenerate>false</QmlCacheGenerate>
|
| | | <!--
|
| | | // QML cache generation -->
|
| | | <QmlCacheGenMessage
|
| | | ><![CDATA[Qt Quick Compiler: compiling %<Identity> ahead of time]]></QmlCacheGenMessage>
|
| | | <QmlCacheOutputFile
|
| | | ><![CDATA[$(ProjectDir)GeneratedFiles\%<Filename>_%<Suffix>.cpp]]></QmlCacheOutputFile>
|
| | | <!--
|
| | | // QRC filtering -->
|
| | | <QmlCacheFilterMessage
|
| | | >Qt Quick Compiler: filtering %(Identity)</QmlCacheFilterMessage>
|
| | | <QmlCacheFilteredFile
|
| | | >$(ProjectDir)GeneratedFiles\%(Filename)_qmlcache.qrc</QmlCacheFilteredFile>
|
| | | <QmlCacheFilteredOutputFile
|
| | | >$(ProjectDir)GeneratedFiles\qrc_%(Filename)_qmlcache.cpp</QmlCacheFilteredOutputFile>
|
| | | <QmlCacheFilteredInitFuncName
|
| | | >%(Filename)_qmlcache</QmlCacheFilteredInitFuncName>
|
| | | <!--
|
| | | // QML cache loader generation -->
|
| | | <QmlCacheLoaderMessage
|
| | | >Qt Quick Compiler: generating cache loader</QmlCacheLoaderMessage>
|
| | | <QmlCacheLoaderFile
|
| | | >$(ProjectDir)GeneratedFiles\qmlcache_loader.cpp</QmlCacheLoaderFile>
|
| | | </QtRcc>
|
| | | </ItemDefinitionGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_AfterQmlCache)' != ''"
|
| | | Project="$(QtMsBuildProps_AfterQmlCache)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Targets required to build the QML cache (aka. qtquickcompiler)
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_BeforeQmlCache)' != ''"
|
| | | Project="$(QtMsBuildTargets_BeforeQmlCache)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild global properties
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtBuildTargets>$(QtBuildTargets);QtQmlCache</QtBuildTargets>
|
| | | <QtRccDependsOn>$(QtRccDependsOn);QtQmlCache</QtRccDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // TARGET QtQmlCachePrepare
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Pre-process rcc source files marked for QML cache generation
|
| | | // -->
|
| | | <Target Name="QtQmlCachePrepare"
|
| | | DependsOnTargets="QtRccSetDependencies"
|
| | | BeforeTargets="QtRccPrepare" Condition="'@(QtRcc)' != ''"
|
| | | Inputs="%(QtRcc.Identity)" Outputs="@(QtRcc->'####### Don't skip this target #######')">
|
| | | <ItemGroup>
|
| | | <selected_files Include="$(SelectedFiles)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtQmlCachePrepare %(QtRcc.Identity)" />
|
| | |
|
| | | <!--// Remove sources excluded from build -->
|
| | | <ItemGroup>
|
| | | <QtRcc Remove="@(QtRcc)"
|
| | | Condition="'$(SelectedFiles)' == '' AND '%(QtRcc.ExcludedFromBuild)' == 'true'"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // $(is_selected) ::= file is selected to build
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <selected_files>[@(selected_files->'%(Identity)','][')]</selected_files>
|
| | | <file>[@(QtRcc->'%(Identity)')]</file>
|
| | | <output_file>@(QtRcc->'%(OutputFile)')</output_file>
|
| | | <is_selected
|
| | | Condition="'@(selected_files)' == '' OR $(selected_files.Contains('$(file)'))"
|
| | | >true</is_selected>
|
| | | <is_selected
|
| | | Condition="'@(selected_files)' != '' AND !$(selected_files.Contains('$(file)'))"
|
| | | >false</is_selected>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Parse QRC file
|
| | | // @(res_file) ::= names of resource files
|
| | | // @(res_qml_js) ::= names of QML and JS resource files
|
| | | // @(res_other) ::= names of other resource files
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <res_file
|
| | | Condition="'@(QtRcc)' != '' AND '%(QtRcc.QmlCacheGenerate)' == 'true'"
|
| | | Include="%(QtRcc.ResourceFiles)"/>
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'@(res_file)' != ''">
|
| | | <res_qml_js Include="%(res_file.Identity)"
|
| | | Condition="'%(res_file.Extension)' == '.qml' OR '%(res_file.Extension)' == '.js'"/>
|
| | | <res_other Include="%(res_file.Identity)"
|
| | | Condition="'%(res_file.Extension)' != '.qml' AND '%(res_file.Extension)' != '.js'"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Expand QML and JS build items
|
| | | // -->
|
| | | <ItemGroup Condition="'@(res_qml_js)' != ''">
|
| | | <template Include="template">
|
| | | <InputFile><![CDATA[%<FullPath>]]></InputFile>
|
| | | <OutputFile>@(QtRcc->'%(QmlCacheOutputFile)')</OutputFile>
|
| | | <Message>@(QtRcc->'%(QmlCacheGenMessage)')</Message>
|
| | | <Outputs>%(OutputFile)</Outputs>
|
| | | <ResourceFile>@(QtRcc->'%(FullPath)')</ResourceFile>
|
| | | <IsSelected>$(is_selected)</IsSelected>
|
| | | <AdditionalDependencies>@(QtRcc)</AdditionalDependencies>
|
| | | </template>
|
| | | </ItemGroup>
|
| | | <!--
|
| | | // @(QtQmlCacheItem) ::= QML and JS resource files to be cached -->
|
| | | <Expand Condition="'@(res_qml_js)' != ''"
|
| | | Items="@(res_qml_js)" BaseItem="@(QtRcc)" Template="@(template)">
|
| | | <Output TaskParameter="Result" ItemName="QtQmlCacheItem"/>
|
| | | </Expand>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Convert rcc sources to QML cache generation filter sources
|
| | | // -->
|
| | | <ItemGroup Condition="'@(QtQmlCacheItem)' != ''">
|
| | | <!--
|
| | | // @(QtRccFilter) ::= QRC files to be filtered -->
|
| | | <QtRccFilter Include="@(QtRcc)">
|
| | | <QtQmlCacheItems>@(QtQmlCacheItem)</QtQmlCacheItems>
|
| | | <OtherResources>@(res_other->'%(Identity)')</OtherResources>
|
| | | <InputChanged>false</InputChanged>
|
| | | <OutputFile>%(QtRcc.QmlCacheFilteredFile)</OutputFile>
|
| | | <Outputs>%(QtRcc.QmlCacheFilteredFile)</Outputs>
|
| | | <IsSelected>$(is_selected)</IsSelected>
|
| | | </QtRccFilter>
|
| | | <QtRcc Remove="@(QtRcc)"/>
|
| | | </ItemGroup>
|
| | | <!--
|
| | | // Delete output file to force build of source if it was manually selected to build
|
| | | // (e.g. by the 'Compile' option in the context menu for the file) -->
|
| | | <Delete
|
| | | Condition="'$(SelectedFiles)' != '' AND '$(is_selected)' == 'true'"
|
| | | Files="%(QtRccFilter.OutputFile)"/>
|
| | | <Delete
|
| | | Condition="'$(SelectedFiles)' != '' AND '$(is_selected)' == 'true'"
|
| | | Files="%(QtQmlCacheItem.OutputFile)"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <selected_files/>
|
| | | <file/>
|
| | | <output_file/>
|
| | | <is_selected/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <res_file Remove="@(res_file)"/>
|
| | | <res_qml_js Remove="@(res_qml_js)"/>
|
| | | <res_other Remove="@(res_other)"/>
|
| | | <template Remove="@(res_other)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // TARGET QtRccFilterSetModified
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set InputModified flag for modified files (i.e. Inputs newer than Outputs)
|
| | | // -->
|
| | | <Target Name="QtRccFilterSetModified" DependsOnTargets="QtQmlCachePrepare"
|
| | | Inputs="%(QtRccFilter.FullPath);%(QtRccFilter.AdditionalDependencies)"
|
| | | Outputs="@(QtRccFilter->'%(OutputFile)')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true' AND '@(QtRccFilter)' != ''"
|
| | | Text="## QtRccFilterSetModified %(QtRccFilter.Identity) => %(QtRccFilter.OutputFile)"/>
|
| | |
|
| | | <PropertyGroup>
|
| | | <input_changed/>
|
| | | </PropertyGroup>
|
| | | <CreateProperty Condition="'@(QtRccFilter)' != ''" Value="true">
|
| | | <Output TaskParameter="ValueSetByTask" PropertyName="input_changed" />
|
| | | </CreateProperty>
|
| | | <ItemGroup>
|
| | | <QtRccFilter>
|
| | | <InputChanged>$(input_changed)</InputChanged>
|
| | | <IsSelected Condition="'$(input_changed)' == 'true'">true</IsSelected>
|
| | | </QtRccFilter>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <input_changed/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // TARGET QtRccFilter
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Filter QRC file:
|
| | | // - Filter QML and JS resources from QRC
|
| | | // - If other resources are present, generate new QRC with filtered contents
|
| | | // - Collect data to use in cache loader generation
|
| | | // -->
|
| | | <Target Name="QtRccFilter" DependsOnTargets="QtRccFilterSetModified"
|
| | | Inputs="%(QtRccFilter.FullPath);%(QtRccFilter.AdditionalDependencies);$(MSBuildProjectFile)"
|
| | | Outputs="@(QtRccFilter->'%(OutputFile)')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtRccFilter %(QtRccFilter.Identity) => @(QtRccFilter->'%(OutputFile)')" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set DependenciesChanged flag for modified files or dependencies
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <dependencies_changed/>
|
| | | </PropertyGroup>
|
| | | <CreateProperty Value="true">
|
| | | <Output TaskParameter="ValueSetByTask" PropertyName="dependencies_changed" />
|
| | | </CreateProperty>
|
| | | <ItemGroup>
|
| | | <QtRccFilter>
|
| | | <DependenciesChanged>$(dependencies_changed)</DependenciesChanged>
|
| | | </QtRccFilter>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // @(input_file) ::= QRC file to filter
|
| | | // @(filtered_file) ::= filtered QRC file
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <input_file Include="%(QtRccFilter.InputFile)"
|
| | | Condition="'%(QtRccFilter.QtQmlCacheItems)' != '' AND '%(QtRccFilter.InputFile)' != ''"/>
|
| | | <filtered_file Include="%(QtRccFilter.QmlCacheFilteredFile)"
|
| | | Condition="'%(QtRccFilter.QmlCacheFilteredFile)' != ''"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Prepare qmlcachegen command for QRC filtering
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <!--
|
| | | // $(options) ::= qmlcachegen command line options -->
|
| | | <options Condition="'%(QtRccFilter.QtQmlCacheItems)' != '' AND '@(input_file)' != ''"
|
| | | >$(options) @(input_file->'--filter-resource-file "%(Identity)"')</options>
|
| | | <options Condition="'%(QtRccFilter.QtQmlCacheItems)' != '' AND '@(filtered_file)' != ''"
|
| | | >$(options) @(filtered_file->'-o "%(Identity)"')</options>
|
| | | <!--
|
| | | // $(full_path) ::= full path of filtered file -->
|
| | | <full_path Condition="'%(QtRccFilter.QtQmlCacheItems)' != ''"
|
| | | >$([System.IO.Path]::Combine($(MSBuildProjectDirectory),%(QmlCacheFilteredFile)))</full_path>
|
| | | <!--
|
| | | // $(relative_path) ::= path of filtered file, relative to project directory -->
|
| | | <relative_path Condition="'%(QtRccFilter.QtQmlCacheItems)' != ''"
|
| | | >$([MSBuild]::MakeRelative($(MSBuildProjectDirectory),$(full_path)).TrimStart('\'))</relative_path>
|
| | | <!--
|
| | | // $(run_parallel) ::= run qmlcachegen in a parallel process
|
| | | // $(run_single) ::= run qmlcachegen in single process mode -->
|
| | | <run_parallel Condition="'@(QtRccFilter)' != ''
|
| | | AND '%(QtRccFilter.ParallelProcess)' == 'true' AND '$(SelectedFiles)' == ''"
|
| | | >true</run_parallel>
|
| | | <run_single Condition="'@(QtRccFilter)' != ''
|
| | | AND ('%(QtRccFilter.ParallelProcess)' != 'true' OR '$(SelectedFiles)' != '')"
|
| | | >true</run_single>
|
| | | </PropertyGroup>
|
| | |
|
| | | <ItemGroup Condition="'@(QtRccFilter)' != ''">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Create work item for QRC filtering
|
| | | // -->
|
| | | <QtWork
|
| | | Include="@(QtRccFilter)"
|
| | | Condition="'%(QtRccFilter.QtQmlCacheItems)' != ''
|
| | | AND '%(QtRccFilter.OtherResources)' != ''
|
| | | AND '%(QtRccFilter.IsSelected)' == 'true'">
|
| | | <WorkType>qmlcachegen_filter</WorkType>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >$(QtToolsPath)\qmlcachegen.exe</ToolPath>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' != 'true'"
|
| | | >%(QtRccFilter.QTDIR)\bin\qmlcachegen.exe</ToolPath>
|
| | | <Options>$(options)</Options>
|
| | | <OutputFile>$(full_path)</OutputFile>
|
| | | <Message>%(QtRccFilter.QmlCacheFilterMessage)</Message>
|
| | | <ParallelBuild Condition="'$(run_parallel)' == 'true'">true</ParallelBuild>
|
| | | <ParallelBuild Condition="'$(run_single)' == 'true'">false</ParallelBuild>
|
| | | </QtWork>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Create build item for generated QRC file
|
| | | // -->
|
| | | <QtRcc Condition="'%(QtRccFilter.QtQmlCacheItems)' != ''
|
| | | AND '%(QtRccFilter.OtherResources)' != ''"
|
| | | Include="@(QtRccFilter->'$(relative_path)')">
|
| | | <InputFile>@(QtRccFilter->'%(QmlCacheFilteredFile)')</InputFile>
|
| | | <OutputFile>@(QtRccFilter->'%(QmlCacheFilteredOutputFile)')</OutputFile>
|
| | | <InitFuncName>@(QtRccFilter->'%(QmlCacheFilteredInitFuncName)')</InitFuncName>
|
| | | <DependsOn>@(QtRccFilter)</DependsOn>
|
| | | </QtRcc>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // If sources were manually selected (e.g. by the 'Compile' option in the context menu for
|
| | | // project items), add generated QRC to the list of selected files
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <selected_rcc
|
| | | Condition="'$(SelectedFiles)' != ''
|
| | | AND '%(QtRccFilter.IsSelected)' == 'true'
|
| | | AND '%(QtRccFilter.QtQmlCacheItems)' != ''
|
| | | AND '%(QtRccFilter.OtherResources)' != ''"
|
| | | >$(relative_path)</selected_rcc>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(selected_rcc)' != ''">
|
| | | <SelectedFiles>$(SelectedFiles);$(selected_rcc)</SelectedFiles>
|
| | | </PropertyGroup>
|
| | | <ItemGroup Condition="'$(selected_rcc)' != ''">
|
| | | <selected_files Include="$(selected_rcc)"/>
|
| | | <SelectedFiles Include="$(selected_rcc)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Update timestamp of generated QRC file to force rcc target to run
|
| | | // -->
|
| | | <MakeDir Directories="$([System.IO.Path]::GetDirectoryName(%(QtRccFilter.OutputFile)))"/>
|
| | | <Touch Condition="'%(QtRccFilter.InputChanged)' == 'true'"
|
| | | AlwaysCreate="true" Files="%(QtRccFilter.OutputFile)"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Create loader input item, used in cache loader generation
|
| | | // -->
|
| | | <ItemGroup Condition="'@(QtRccFilter)' != ''">
|
| | | <loader_input Include="@(QtRccFilter->'QtQmlCacheLoader')">
|
| | | <Inputs>%(QtRccFilter.Identity)</Inputs>
|
| | | <InputFile>%(QtRccFilter.InputFile)</InputFile>
|
| | | <Mapping Condition="'%(QtRccFilter.QtQmlCacheItems)' != '' AND '%(QtRccFilter.OtherResources)' != ''"
|
| | | >%(QtRccFilter.InputFile)=$(full_path)</Mapping>
|
| | | </loader_input>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <input_file Remove="@(input_file)"/>
|
| | | <filtered_file Remove="@(filtered_file)"/>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <dependencies_changed/>
|
| | | <options/>
|
| | | <full_path/>
|
| | | <relative_path/>
|
| | | <run_parallel/>
|
| | | <run_single/>
|
| | | <selected_rcc/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // TARGET QtQmlCacheLoader
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate QML cache loader
|
| | | // -->
|
| | | <Target Name="QtQmlCacheLoader" DependsOnTargets="QtRccFilter">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtQmlCacheLoader @(QtQmlCacheLoader->'%(Inputs)')" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Get QML cache loader properties from project rcc property page
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <QtRcc Include="qmlcachengen_loader"/>
|
| | | <loader Include="@(QtRcc)" Condition="'%(QtRcc.Identity)' == 'qmlcachengen_loader'"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate QML cache loader
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <!--
|
| | | // $(options) ::= qmlcachegen command line options -->
|
| | | <options Condition="'@(loader_input)' != ''"
|
| | | >$(options) @(loader_input->'--resource-file-mapping="%(Mapping)"',' ')</options>
|
| | | <options Condition="'@(loader_input)' != ''"
|
| | | >$(options) @(loader_input->'"%(InputFile)"',' ')</options>
|
| | | <options Condition="'@(loader)' != ''"
|
| | | >$(options) @(loader->'-o "%(QmlCacheLoaderFile)"')</options>
|
| | | <!--
|
| | | // $(run_parallel) ::= run qmlcachegen in a parallel process
|
| | | // $(run_single) ::= run qmlcachegen in single process mode -->
|
| | | <run_parallel Condition="'@(QtQmlCacheLoader)' != ''
|
| | | AND '%(loader.ParallelProcess)' == 'true' AND '$(SelectedFiles)' == ''">true</run_parallel>
|
| | | <run_single Condition="'@(QtQmlCacheLoader)' != ''
|
| | | AND ('%(loader.ParallelProcess)' != 'true' OR '$(SelectedFiles)' != '')">true</run_single>
|
| | | <!--
|
| | | // $(dependencies_changed) ::= source QRC files changed status
|
| | | // $(input_changed) ::= source QRC files input changed status -->
|
| | | <dependencies_changed>@(loader_input->'%(DependenciesChanged)')</dependencies_changed>
|
| | | <input_changed>@(loader_input->'%(InputChanged)')</input_changed>
|
| | | <input_changed Condition="!Exists('@(loader->'%(QmlCacheLoaderFile)')')">true</input_changed>
|
| | | <is_selected>@(loader_input->'%(IsSelected)')</is_selected>
|
| | |
|
| | | <!--// Get relative path to output -->
|
| | | <cache_loader_path>@(loader->'%(QmlCacheLoaderFile)')</cache_loader_path>
|
| | | <output_relative
|
| | | >$([MSBuild]::MakeRelative($(ProjectDir), $(cache_loader_path)).TrimStart('\'))</output_relative>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <!--
|
| | | // Create work item to generate QML cache loader -->
|
| | | <QtWork
|
| | | Include="qmlcachengen_loader"
|
| | | Condition="'@(loader_input)' != ''
|
| | | AND $(is_selected.Contains('true'))">
|
| | | <WorkType>qmlcachengen_loader</WorkType>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >$(QtToolsPath)\qmlcachegen.exe</ToolPath>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' != 'true'"
|
| | | >@(loader->'%(QTDIR)')\bin\qmlcachegen.exe</ToolPath>
|
| | | <Options>$(options)</Options>
|
| | | <OutputFile>@(loader->'%(QmlCacheLoaderFile)')</OutputFile>
|
| | | <Message>@(loader->'%(QmlCacheLoaderMessage)')</Message>
|
| | | <ParallelBuild Condition="'$(run_parallel)' == 'true'">true</ParallelBuild>
|
| | | <ParallelBuild Condition="'$(run_single)' == 'true'">false</ParallelBuild>
|
| | | <DisableLog>true</DisableLog>
|
| | | <DependenciesChanged>$(dependencies_changed.Contains('true'))</DependenciesChanged>
|
| | | <InputChanged>$(input_changed.Contains('true'))</InputChanged>
|
| | | <ClCompile Condition="'%(loader.DynamicSource)' != 'false'">$(output_relative)</ClCompile>
|
| | | <DependsOn>@(loader_input->'%(Inputs)')</DependsOn>
|
| | | </QtWork>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <loader_mapping_option Remove="@(mapping_option)"/>
|
| | | <loader_input_option Remove="@(loader_input_option)"/>
|
| | | <loader Remove="@(loader)"/>
|
| | | <QtRcc Remove="qmlcachengen_loader"/>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <options/>
|
| | | <run_parallel/>
|
| | | <run_single/>
|
| | | <dependencies_changed/>
|
| | | <input_changed/>
|
| | | <cache_loader_path/>
|
| | | <output_relative/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlSetModified
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set InputModified flag for modified files (i.e. Inputs newer than Outputs)
|
| | | // -->
|
| | | <Target Name="QtQmlSetModified" DependsOnTargets="QtQmlCachePrepare"
|
| | | Inputs="%(QtQmlCacheItem.FullPath);%(QtQmlCacheItem.AdditionalDependencies)"
|
| | | Outputs="@(QtQmlCacheItem->'%(OutputFile)')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtQmlSetModified %(QtQmlCacheItem.Identity) => @(QtQmlCacheItem->'%(OutputFile)')"/>
|
| | |
|
| | | <PropertyGroup>
|
| | | <input_changed/>
|
| | | </PropertyGroup>
|
| | | <CreateProperty Value="true">
|
| | | <Output TaskParameter="ValueSetByTask" PropertyName="input_changed" />
|
| | | </CreateProperty>
|
| | | <ItemGroup>
|
| | | <QtQmlCacheItem>
|
| | | <InputChanged>$(input_changed)</InputChanged>
|
| | | </QtQmlCacheItem>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <input_changed/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // TARGET QtQmlCacheItem
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // -->
|
| | | <Target Name="QtQmlCacheItem" DependsOnTargets="QtQmlSetModified"
|
| | | Inputs="%(QtQmlCacheItem.FullPath);%(QtQmlCacheItem.AdditionalDependencies);$(MSBuildProjectFile)"
|
| | | Outputs="@(QtQmlCacheItem->'%(OutputFile)')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## QtQmlCacheItem %(QtQmlCacheItem.Identity) => @(QtQmlCacheItem->'%(OutputFile)')" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set DependenciesChanged flag for modified files or dependencies
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <dependencies_changed/>
|
| | | </PropertyGroup>
|
| | | <CreateProperty Value="true">
|
| | | <Output TaskParameter="ValueSetByTask" PropertyName="dependencies_changed" />
|
| | | </CreateProperty>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate QML cache
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <!--
|
| | | // $(options) ::= qmlcachegen command line options -->
|
| | | <options Condition="'@(QtQmlCacheItem)' != ''"
|
| | | >$(options) --resource="%(ResourceFile)"</options>
|
| | | <options Condition="'@(QtQmlCacheItem)' != ''"
|
| | | >$(options) "%(FullPath)"</options>
|
| | | <options Condition="'@(QtQmlCacheItem)' != ''"
|
| | | >$(options) -o "%(OutputFile)"</options>
|
| | | <!--
|
| | | // $(run_parallel) ::= run qmlcachegen in a parallel process
|
| | | // $(run_single) ::= run qmlcachegen in single process mode -->
|
| | | <run_parallel Condition="'@(QtQmlCacheItem)' != ''
|
| | | AND '%(QtQmlCacheItem.ParallelProcess)' == 'true' AND '$(SelectedFiles)' == ''"
|
| | | >true</run_parallel>
|
| | | <run_single Condition="'@(QtQmlCacheItem)' != ''
|
| | | AND ('%(QtQmlCacheItem.ParallelProcess)' != 'true' OR '$(SelectedFiles)' != '')"
|
| | | >true</run_single>
|
| | |
|
| | | <!--// Get relative path to output -->
|
| | | <output_relative
|
| | | >$([MSBuild]::MakeRelative($(ProjectDir), %(QtQmlCacheItem.OutputFile)).TrimStart('\'))</output_relative>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <!--
|
| | | // Create work item to generate QML cache -->
|
| | | <QtWork
|
| | | Include="@(QtQmlCacheItem)"
|
| | | Condition="'@(QtQmlCacheItem)' != ''
|
| | | AND '%(QtQmlCacheItem.IsSelected)' == 'true'">
|
| | | <WorkType>qmlcachegen</WorkType>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | >$(QtToolsPath)\qmlcachegen.exe</ToolPath>
|
| | | <ToolPath Condition="'$(QtVsProjectSettings)' != 'true'"
|
| | | >%(QtQmlCacheItem.QTDIR)\bin\qmlcachegen.exe</ToolPath>
|
| | | <Options>$(options)</Options>
|
| | | <Message>%(QtQmlCacheItem.Message)</Message>
|
| | | <DependenciesChanged>$(dependencies_changed)</DependenciesChanged>
|
| | | <ParallelBuild Condition="'$(run_parallel)' == 'true'">true</ParallelBuild>
|
| | | <ParallelBuild Condition="'$(run_single)' == 'true'">false</ParallelBuild>
|
| | | <ClCompile Condition="'%(QtQmlCacheItem.DynamicSource)' != 'false'">$(output_relative)</ClCompile>
|
| | | </QtWork>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <dependencies_changed/>
|
| | | <options/>
|
| | | <run_parallel/>
|
| | | <run_single/>
|
| | | <output_relative/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <selected_files Remove="@(selected_files)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // TARGET QtQmlCache
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Root target of QML cache generation
|
| | | // -->
|
| | | <Target Name="QtQmlCache"
|
| | | DependsOnTargets="QtQmlCacheLoader;QtQmlCacheItem"
|
| | | BeforeTargets="QtRcc">
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="## QtQmlCache" />
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_AfterQmlCache)' != ''"
|
| | | Project="$(QtMsBuildTargets_AfterQmlCache)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild property definitions for QML static imports
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_BeforeQmlStatic)' != ''"
|
| | | Project="$(QtMsBuildProps_BeforeQmlStatic)"/>
|
| | |
|
| | | <PropertyGroup>
|
| | | <QtQmlPluginImportCpp>$(QtQmlIntDir)\qml_plugin_import.cpp</QtQmlPluginImportCpp>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildProps_AfterQmlStatic)' != ''"
|
| | | Project="$(QtMsBuildProps_AfterQmlStatic)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate imports of QML static plugins
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import pre-requisites
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_BeforeQmlStatic)' != ''"
|
| | | Project="$(QtMsBuildTargets_BeforeQmlStatic)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild global properties
|
| | | // * add QtQmlStatic to the list of targets to run during build
|
| | | // * add QtQmlStaticLink to the list of targets to run when calculating linker input
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtBuildTargets>$(QtBuildTargets);QtQmlStatic</QtBuildTargets>
|
| | | <ComputeLinkInputsTargets>$(ComputeLinkInputsTargets);QtQmlStaticLink</ComputeLinkInputsTargets>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlStaticLink
|
| | | /// => runs only once
|
| | | /// => always runs if building against a static build of Qt
|
| | | /// => targets that must run first: QtQmlStatic, ComputeCLGeneratedLinkInputs
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Add QML static plugin libs to Link input.
|
| | | // -->
|
| | | <Target
|
| | | Name="QtQmlStaticLink"
|
| | | Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
| | | DependsOnTargets="QtQmlStatic;ComputeCLGeneratedLinkInputs">
|
| | | <ItemGroup>
|
| | | <Link>
|
| | | <AdditionalDependencies Condition="'@(QtQmlImportLib)' != ''"
|
| | | >%(Link.AdditionalDependencies);@(QtQmlImportLib)</AdditionalDependencies>
|
| | | </Link>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlStatic
|
| | | /// => runs only once
|
| | | /// => always runs if building against a static build of Qt
|
| | | /// => targets that must run first: QtQmlImportsParseJson, QtQmlGetImportCpp
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Entry point for generating imports of QML static plugins.
|
| | | // -->
|
| | | <Target
|
| | | Name="QtQmlStatic"
|
| | | Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
| | | DependsOnTargets="QtQmlImportsParseJson;QtQmlGetImportCpp">
|
| | | <ItemGroup>
|
| | | <!-- for each required import, create a reference to the corresponding import lib -->
|
| | | <QtQmlImportLib
|
| | | Condition="'$(QtBuildConfig)' == 'debug'"
|
| | | Include="@(QtQmlImport->'%(Path)\%(Plugin)d.lib')"/>
|
| | | <QtQmlImportLib
|
| | | Condition="'$(QtBuildConfig)' != 'debug'"
|
| | | Include="@(QtQmlImport->'%(Path)\%(Plugin).lib')"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlGetImportCpp
|
| | | /// => runs only once
|
| | | /// => skipped if generated C++ is up-to-date, relative to all JSON output files
|
| | | /// => targets that must run first: QtQmlImportsParseJson
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate C++ source file with imports of QML static plugins.
|
| | | // -->
|
| | | <Target
|
| | | Name="QtQmlGetImportCpp"
|
| | | Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
| | | DependsOnTargets="QtQmlImportsParseJson"
|
| | | Inputs="@(QtQml->'%(ImportJson)')"
|
| | | Outputs="$(QtQmlPluginImportCpp)">
|
| | |
|
| | | <!-- file header -->
|
| | | <PropertyGroup>
|
| | | <QmlPluginImportCppHeader>
|
| | | <![CDATA[
|
| | | // This file is autogenerated by Qt/MSBuild. It imports static plugin classes for
|
| | | // static plugins used by QML imports.
|
| | | #include <QtPlugin>]]>
|
| | | </QmlPluginImportCppHeader>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- file contents: header + imports -->
|
| | | <ItemGroup>
|
| | | <QmlPluginImportCpp Include="$(QmlPluginImportCppHeader)" />
|
| | | <QmlPluginImportCpp Include="@(QtQmlImport->'Q_IMPORT_PLUGIN(%(ClassName))')" />
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- write .cpp file -->
|
| | | <WriteLinesToFile
|
| | | File="$(QtQmlPluginImportCpp)"
|
| | | Lines="@(QmlPluginImportCpp)" />
|
| | |
|
| | | <!-- clean-up -->
|
| | | <PropertyGroup>
|
| | | <QmlPluginImportCppHeader/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <QtQmlPluginImportCpp Remove="@(QtQmlPluginImportCpp)" />
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlImportsParseJson
|
| | | /// => runs only once
|
| | | /// => always runs if building agains a static build of Qt
|
| | | /// => targets that must run first: QtQmlScanImports
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Parse JSON output of qmlimportscanner.
|
| | | // * ATTN: "Naïve" parser: assumes JSON is formatted with each value in a single line
|
| | | // -->
|
| | | <Target
|
| | | Name="QtQmlImportsParseJson"
|
| | | Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
| | | DependsOnTargets="QtQmlScanImports">
|
| | |
|
| | | <!-- constants -->
|
| | | <PropertyGroup>
|
| | | <StrClassName>"classname": </StrClassName>
|
| | | <StrPath>"path": </StrPath>
|
| | | <StrPlugin>"plugin": </StrPlugin>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- load text of all JSON output files -->
|
| | | <ReadLinesFromFile File="%(QtQml.ImportJson)">
|
| | | <Output TaskParameter="Lines" ItemName="JsonText"/>
|
| | | </ReadLinesFromFile>
|
| | |
|
| | | <ItemGroup>
|
| | | <!-- list of all lines starting with '"classname": ' -->
|
| | | <JsonClassName
|
| | | Include="@(JsonText)"
|
| | | Condition="$([System.String]::Copy('%(JsonText.Identity)').StartsWith('$(StrClassName)'))" />
|
| | | <!-- extract value -->
|
| | | <JsonClassName>
|
| | | <ClassName>$([System.String]::Copy('%(JsonClassName.Identity)').Substring($(StrClassName.Length)).Trim(',').Trim('"'))</ClassName>
|
| | | </JsonClassName>
|
| | |
|
| | | <!-- list of all lines starting with '"path": ' -->
|
| | | <JsonPath
|
| | | Include="@(JsonText)"
|
| | | Condition="$([System.String]::Copy('%(JsonText.Identity)').StartsWith('$(StrPath)'))" />
|
| | | <!-- extract value -->
|
| | | <JsonPath>
|
| | | <Path>$([System.String]::Copy('%(JsonPath.Identity)').Substring($(StrPath.Length)).Trim(',').Trim('"'))</Path>
|
| | | </JsonPath>
|
| | |
|
| | | <!-- list of all lines starting with '"plugin": ' -->
|
| | | <JsonPlugin
|
| | | Include="@(JsonText)"
|
| | | Condition="$([System.String]::Copy('%(JsonText.Identity)').StartsWith('$(StrPlugin)'))" />
|
| | | <!-- extract value -->
|
| | | <JsonPlugin>
|
| | | <Plugin>$([System.String]::Copy('%(JsonPlugin.Identity)').Substring($(StrPlugin.Length)).Trim(',').Trim('"'))</Plugin>
|
| | | </JsonPlugin>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- join lists of extracted values into single list of imports -->
|
| | | <Join LeftItems="@(JsonClassName)" RightItems="@(JsonPath)" On="ROW_NUMBER">
|
| | | <Output TaskParameter="Result" ItemName="JsonAux"/>
|
| | | </Join>
|
| | | <Join LeftItems="@(JsonAux)" RightItems="@(JsonPlugin)" On="ROW_NUMBER">
|
| | | <Output TaskParameter="Result" ItemName="Json"/>
|
| | | </Join>
|
| | | <!-- remove duplicate import items -->
|
| | | <RemoveDuplicates Inputs="@(Json->'%(ClassName)')">
|
| | | <Output TaskParameter="Filtered" ItemName="QtQmlImport"/>
|
| | | </RemoveDuplicates>
|
| | |
|
| | | <!-- @(QtQmlImport) => list of required imports -->
|
| | |
|
| | | <!-- clean-up -->
|
| | | <PropertyGroup>
|
| | | <StrClassName/>
|
| | | <StrPath/>
|
| | | <StrPlugin/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <JsonText Remove="@(JsonText)" />
|
| | | <JsonClassName Remove="@(JsonClassName)"/>
|
| | | <JsonPath Remove="@(JsonPath)"/>
|
| | | <JsonPlugin Remove="@(JsonPlugin)"/>
|
| | | <JsonAux Remove="@(JsonAux)" />
|
| | | <Json Remove="@(Json)" />
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlScanImports
|
| | | /// => runs once for each QML file
|
| | | /// => skipped if corresponding JSON output file is up-to-date
|
| | | /// => targets that must run first: QtQmlStaticPrepare
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run qmlimportscanner tool.
|
| | | // -->
|
| | | <Target
|
| | | Name="QtQmlScanImports"
|
| | | Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
| | | DependsOnTargets="QtQmlStaticPrepare"
|
| | | Inputs="%(QtQml.Identity)"
|
| | | Outputs="%(QtQml.ImportJson)">
|
| | |
|
| | | <!-- create QML work dir -->
|
| | | <MakeDir Directories="$(QtQmlIntDir)" />
|
| | |
|
| | | <!-- map local paths to build host paths -->
|
| | | <ItemGroup>
|
| | | <LocalPath Include="QtQmlFile">
|
| | | <Name>Path</Name>
|
| | | <Item>%(QtQml.Identity)</Item>
|
| | | <Value>%(QtQml.Identity)</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="QtQmlImportJson">
|
| | | <Name>Path</Name>
|
| | | <Item>%(QtQml.ImportJson)</Item>
|
| | | <Value>%(QtQml.ImportJson)</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="QtInstallQml">
|
| | | <Name>Path</Name>
|
| | | <Item>$(QMake_QT_INSTALL_QML_)</Item>
|
| | | <Value>$(QMake_QT_INSTALL_QML_)</Value>
|
| | | </LocalPath>
|
| | | </ItemGroup>
|
| | | <HostTranslatePaths Items="@(LocalPath)" Names="Path">
|
| | | <Output TaskParameter="Result" ItemName="HostPath"/>
|
| | | </HostTranslatePaths>
|
| | | <ItemGroup>
|
| | | <QtQmlFile Include="@(HostPath->WithMetadataValue('Identity', 'QtQmlFile'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QtQmlFile>
|
| | | <QtQmlImportJson Include="@(HostPath->WithMetadataValue('Identity', 'QtQmlImportJson'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QtQmlImportJson>
|
| | | <QtInstallQml Include="@(HostPath->WithMetadataValue('Identity', 'QtInstallQml'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QtInstallQml>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- qmlimportscanner command line -->
|
| | | <PropertyGroup>
|
| | | <Cmd><![CDATA["$(QtToolsPath)/qmlimportscanner.exe"]]></Cmd>
|
| | | <Cmd><![CDATA[$(Cmd) -qmlFiles @(QtQmlFile->'%(HostPath)')]]></Cmd>
|
| | | <Cmd><![CDATA[$(Cmd) -importPath @(QtInstallQml->'%(HostPath)')]]></Cmd>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- run qmlimportscanner -->
|
| | | <HostExec
|
| | | Command="$(Cmd)" RedirectStdOut="@(QtQmlImportJson->'%(HostPath)')"
|
| | | Inputs="@(QtQmlFile->'%(HostPath)')"
|
| | | Outputs="@(QtQmlImportJson->'%(HostPath)')"
|
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | RemoteProjectDir="$(_ResolvedRemoteProjectDir)" />
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtQmlStaticPrepare
|
| | | /// => runs once for each QML file
|
| | | /// => skipped if $(QtStaticPlugins) is false
|
| | | /// => skipped if there are no QML files in the project
|
| | | /// => targets that must run first: QtQmlCreateItems
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Calculate path of .json file with the output of qmlimportscanner for each QML file.
|
| | | // * Format: <QML work dir> '\' SHA1(<path to QML file>) '_' <QML file name> '.json'
|
| | | // -->
|
| | | <Target
|
| | | Name="QtQmlStaticPrepare"
|
| | | Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
| | | DependsOnTargets="QtQmlCreateItems"
|
| | | Inputs="%(QtQml.Identity)"
|
| | | Outputs="@(QtQml->'####### Do not skip this target #######')">
|
| | | <!-- calculate SHA1 of QML file path, relative to project dir -->
|
| | | <Hash ItemsToHash="@(QtQml)">
|
| | | <Output TaskParameter="HashResult" PropertyName="QtQmlIdentityHash"/>
|
| | | </Hash>
|
| | | <!-- set path to corresponding JSON file -->
|
| | | <ItemGroup>
|
| | | <QtQml>
|
| | | <ImportJson>$([MSBuild]::MakeRelative(
|
| | | '$(ProjectDir)','$(QtQmlIntDir)\$(QtQmlIdentityHash)_%(Filename).json'))</ImportJson>
|
| | | </QtQml>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import dependants
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtMsBuildTargets_AfterQmlStatic)' != ''"
|
| | | Project="$(QtMsBuildTargets_AfterQmlStatic)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Fail-safe import of private definitions
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtPrivateLoaded)' != 'true'"
|
| | | Project="$(MSBuildThisFileDirectory)\qt_private.props"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Defaults for project version constants
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtVsProjectVersion
|
| | | Condition="'$(QtVsProjectVersion)' == ''"
|
| | | >0</QtVsProjectVersion>
|
| | | <QtVsProjectMinVersion_Settings
|
| | | Condition="'$(QtVsProjectMinVersion_Settings)' == ''"
|
| | | >0</QtVsProjectMinVersion_Settings>
|
| | | <QtVsProjectMinVersion_ClProperties
|
| | | Condition="'$(QtVsProjectMinVersion_ClProperties)' == ''"
|
| | | >0</QtVsProjectMinVersion_ClProperties>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt Common Targets
|
| | | // -->
|
| | | <Import Project="qt_globals.targets"/>
|
| | | <Import Project="qt_settings.targets"/>
|
| | | <Import Project="qt_tasks.targets"/>
|
| | | <Import Project="qt_vars.targets"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Import subfolder targets
|
| | | // -->
|
| | | <Import
|
| | | Project="$(QtMsBuildTargets)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Default values of Qt settings
|
| | | //
|
| | | // Preceding evaluation chain:
|
| | | // * Project global properties, incl. $(Keyword), $(WindowsTargetPlatformVersion), $(QtMsBuild)
|
| | | // * Microsoft.Cpp.Default.props
|
| | | // * Configuration properties, incl. $(ConfigurationType), $(PlatformToolset)
|
| | | //
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <PropertyGroup>
|
| | | <QtDefaultsLoaded>true</QtDefaultsLoaded>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- // Qt VS Project Format Version -->
|
| | | <PropertyGroup>
|
| | | <QtVsProjectVersion>0</QtVsProjectVersion>
|
| | | <QtVsProjectMinVersion_Settings>300</QtVsProjectMinVersion_Settings>
|
| | | <QtVsProjectMinVersion_ClProperties>300</QtVsProjectMinVersion_ClProperties>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Keyword)' != ''">
|
| | | <QtVsProjectVersion Condition="'$(Keyword)' == 'Qt4VSv1.0'">200</QtVsProjectVersion>
|
| | | <QtVsProjectVersion Condition="$(Keyword.StartsWith('QtVS_v'))"
|
| | | >$([System.Convert]::ToInt32($(Keyword.Substring(6))))</QtVsProjectVersion>
|
| | | <QtVsProjectSettings Condition="$(QtVsProjectVersion) >= $(QtVsProjectMinVersion_Settings)"
|
| | | >true</QtVsProjectSettings>
|
| | | <QtVsProjectSettings Condition="$(QtVsProjectVersion) < $(QtVsProjectMinVersion_Settings)"
|
| | | >false</QtVsProjectSettings>
|
| | | <QtVsProjectClProperties
|
| | | Condition="$(QtVsProjectVersion) >= $(QtVsProjectMinVersion_ClProperties)"
|
| | | >true</QtVsProjectClProperties>
|
| | | <QtVsProjectClProperties
|
| | | Condition="$(QtVsProjectVersion) < $(QtVsProjectMinVersion_ClProperties)"
|
| | | >false</QtVsProjectClProperties>
|
| | | </PropertyGroup>
|
| | |
|
| | | <PropertyGroup>
|
| | | <!--// Path of Qt binary files -->
|
| | | <QtPathBinaries>bin</QtPathBinaries>
|
| | | <QtPathLibraryExecutables>bin</QtPathLibraryExecutables>
|
| | |
|
| | | <!--// qmake template -->
|
| | | <QtQMakeTemplate>vcapp</QtQMakeTemplate>
|
| | |
|
| | | <!--// Extract Qt variables from qmake-generated Makefile
|
| | | // Syntax: < var_name > [ = [ makefile_name ] / < pattern > / < replace > / ] -->
|
| | | <QMake_Makefile>
|
| | | DEFINES=/-D([^\s=]+(=(\x22(\\\\|\\\x22|[^\x22])*\x22|\S+))?)/$1/;
|
| | | INCLUDEPATH=INCPATH/-(?:iquote|isystem|idirafter|I)\s*(\x22[^\x22]+\x22|[^\s]+)/$1/;
|
| | | LIBS=/(?:(?:\/LIBPATH:|-L)(?:\x22[^\x22]+\x22|[^\s]+))|(\x22[^\x22]+\x22|[^\s]+)/$1/;
|
| | | LIBPATH=LIBS/(?:\/LIBPATH:|-L)(\x22[^\x22]+\x22|[^\s]+)/$1/;
|
| | | </QMake_Makefile>
|
| | |
|
| | | <!--// Extract Qt variables from qmake-generated .vcxproj file
|
| | | // Syntax: < var_name > = < xpath_to_value > -->
|
| | | <QMake_MSBuild>
|
| | | DEFINES=/Project/ItemDefinitionGroup/ClCompile/PreprocessorDefinitions;
|
| | | INCLUDEPATH=/Project/ItemDefinitionGroup/ClCompile/AdditionalIncludeDirectories;
|
| | | STDCPP=/Project/ItemDefinitionGroup/ClCompile/LanguageStandard;
|
| | | CL_OPTIONS=/Project/ItemDefinitionGroup/ClCompile/AdditionalOptions;
|
| | | LIBS=/Project/ItemDefinitionGroup/Link/AdditionalDependencies;
|
| | | LINK_OPTIONS=/Project/ItemDefinitionGroup/Link/AdditionalOptions;
|
| | | </QMake_MSBuild>
|
| | |
|
| | | <!--// Default Qt version -->
|
| | | <QtVersionsRegKey Condition="'$(QtVersionsRegKey)' == ''"
|
| | | >HKEY_CURRENT_USER\Software\Digia\Versions</QtVersionsRegKey>
|
| | | <DefaultQtVersion Condition="'$(DefaultQtVersion)' == ''"
|
| | | >$([MSBuild]::GetRegistryValue('$(QtVersionsRegKey)','DefaultQtVersion'))</DefaultQtVersion>
|
| | |
|
| | | <!--// Qt build config -->
|
| | | <QtBuildConfig Condition="'$(Configuration)' == 'Debug'">debug</QtBuildConfig>
|
| | | <QtBuildConfig Condition="'$(Configuration)' != 'Debug'">release</QtBuildConfig>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Read subfolder dependencies (qt_import.props)
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <SubFolder>$([System.IO.Directory]::GetDirectories('$(MSBuildThisFileDirectory)'))</SubFolder>
|
| | | <SubFolderImports Condition="'$(SubFolder)' != ''"
|
| | | >
|
| | | $([System.String]::Join(
|
| | | '\qt_import.props;',
|
| | | $(SubFolder.Split(';'))))\qt_import.props
|
| | | </SubFolderImports>
|
| | | <QtImports>$(SubFolderImports.Split(';'))</QtImports>
|
| | | <SubFolder/>
|
| | | <SubFolderImports/>
|
| | | </PropertyGroup>
|
| | | <Import
|
| | | Project="$(QtImports)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// Qt/MSBuild global definitions
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Build dependencies
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <BuildDependsOn>
|
| | | QtVersion;
|
| | | $(BuildDependsOn);
|
| | | Qt
|
| | | </BuildDependsOn>
|
| | | <CleanDependsOn>
|
| | | $(CleanDependsOn);
|
| | | QtClean
|
| | | </CleanDependsOn>
|
| | | <DesignTimeBuildInitTargets>
|
| | | $(DesignTimeBuildInitTargets);
|
| | | Qt
|
| | | </DesignTimeBuildInitTargets>
|
| | | <ComputeCompileInputsTargets>
|
| | | $(ComputeCompileInputsTargets);
|
| | | Qt
|
| | | </ComputeCompileInputsTargets>
|
| | | <BeforeClCompileTargets>
|
| | | $(BeforeClCompileTargets);
|
| | | Qt
|
| | | </BeforeClCompileTargets>
|
| | | <ComputeLinkInputsTargets>
|
| | | $(ComputeLinkInputsTargets);
|
| | | Qt
|
| | | </ComputeLinkInputsTargets>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild global properties
|
| | | // -->
|
| | | <Import Project="..\version.targets" Condition="Exists('..\version.targets')"/>
|
| | | <PropertyGroup>
|
| | | <QtMsBuildVersion>$(QtVSToolsVersion)</QtMsBuildVersion>
|
| | | <QtDebug Condition="'$(QtDebug)' == ''">false</QtDebug>
|
| | | <QtLogFilePath Condition="'$(QtLogFilePath)' == ''"
|
| | | >$([System.IO.Path]::Combine($(ProjectDir),$(IntDir)qt_work.log))</QtLogFilePath>
|
| | | <QtMaxProcs Condition="'$(QtMaxProcs)' == ''"
|
| | | >$([System.Environment]::ProcessorCount)</QtMaxProcs>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtGetDefaultClCompile
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Get default C++ properties
|
| | | // -->
|
| | | <Target Name="QtGetDefaultClCompile">
|
| | | <ItemGroup>
|
| | | <ClCompile Include="DefaultClCompile"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtClean
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up from previous build
|
| | | // -->
|
| | | <Target Name="QtClean">
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="## Qt Clean"/>
|
| | | <Delete Files="$(QtLogFilePath)"/>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtVersion
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Print debug message with Qt/MSBuild version
|
| | | // -->
|
| | | <Target Name="QtVersion">
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="Qt/MSBuild v$(QtMsBuildVersion) ($(MSBuildThisFileDirectory))"/>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtPrepare
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Prepare Qt build: read and parse work log file
|
| | | // -->
|
| | | <Target Name="QtPrepare"
|
| | | Condition="'$(QtSkipWork)' != 'true'"
|
| | | DependsOnTargets="$(QtDependsOn)"
|
| | | BeforeTargets="QtWorkPrepare">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="#### QtPrepare"/>
|
| | | <CriticalSection Lock="true" Name="$(ProjectGuid)" />
|
| | |
|
| | | <ReadLinesFromFile File="$(QtLogFilePath)">
|
| | | <Output TaskParameter="Lines" ItemName="QtLogData"/>
|
| | | </ReadLinesFromFile>
|
| | | <ItemGroup Condition="'@(QtLogData)' != ''">
|
| | | <QtWorkLog
|
| | | Include="@(QtLogData->'$([System.String]::Copy('%(QtLogData.Identity)').Split('|')[0])')">
|
| | | <Hash>$([System.String]::Copy('%(QtLogData.Identity)').Split('|')[1])</Hash>
|
| | | </QtWorkLog>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtWorkPrepare
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Analyze work request and decide if the Qt tool needs to be called or if the output from the
|
| | | // previous call is still valid.
|
| | | // -->
|
| | | <Target Name="QtWorkPrepare" DependsOnTargets="$(QtDependsOn);$(QtBuildTargets)"
|
| | | Condition="'$(QtSkipWork)' != 'true'"
|
| | | Inputs="%(QtWork.WorkType)(%(QtWork.Identity))"
|
| | | Outputs="@(QtWork->'####### Don't skip this target #######')">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true' AND '@(QtWork)' != ''"
|
| | | Text="## QtWorkPrepare %(QtWork.Identity)" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Calculate hash for the requested work item, based on its associated tool and options
|
| | | // -->
|
| | | <GetItemHash Condition="'@(QtWork)' != ''"
|
| | | Item="@(QtWork)" Keys="Identity;WorkType;ToolPath;Options">
|
| | | <Output TaskParameter="Hash" PropertyName="work_hash" />
|
| | | </GetItemHash>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Try to find entry in Qt work log for the requested work item; get logged hash
|
| | | // -->
|
| | | <PropertyGroup Condition="'@(QtWork)' != ''">
|
| | | <work_key>@(QtWork->'%(WorkType)(%(Identity))')</work_key>
|
| | | <dependencies_changed>@(QtWork->'%(DependenciesChanged)')</dependencies_changed>
|
| | | <input_changed>@(QtWork->'%(InputChanged)')</input_changed>
|
| | | <project_changed
|
| | | Condition="'$(dependencies_changed)' == 'true' AND '$(input_changed)' != 'true'"
|
| | | >true</project_changed>
|
| | | </PropertyGroup>
|
| | |
|
| | | <FindInList Condition="'@(QtWork)' != '' AND '$(input_changed)' != 'true'"
|
| | | CaseSensitive="false" List="@(QtWorkLog)" ItemSpecToFind="$(work_key)">
|
| | | <Output TaskParameter="ItemFound" ItemName="log_entry"/>
|
| | | </FindInList>
|
| | |
|
| | | <PropertyGroup Condition="'@(QtWork)' != ''">
|
| | | <log_hash Condition="'@(log_entry)' != ''">@(log_entry->'%(Hash)')</log_hash>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip work item if:
|
| | | // * work is not needed:
|
| | | // - input was not modified
|
| | | // - AND project was not modified OR command line did not change (i.e. hashes are the same)
|
| | | // * OR we're in a design-time build
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <do_work
|
| | | Condition="'$(input_changed)' == 'true'
|
| | | OR ('$(project_changed)' == 'true' AND '$(log_hash)' != '$(work_hash)')"
|
| | | >true</do_work>
|
| | | <skip_work
|
| | | Condition="'$(do_work)' != 'true' OR '$(DesignTimeBuild)' == 'true'"
|
| | | >true</skip_work>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Skip work item
|
| | | // -->
|
| | | <ItemGroup Condition="'@(QtWork)' != '' AND '$(skip_work)' == 'true'">
|
| | | <QtWorkResult Include="@(QtWork)">
|
| | | <ExitCode>0</ExitCode>
|
| | | <Skipped>true</Skipped>
|
| | | </QtWorkResult>
|
| | | <QtWork Remove="@(QtWork)" />
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate new work log entry and ensure path to output exists
|
| | | // -->
|
| | | <ItemGroup Condition="'@(QtWork)' != '' AND '$(skip_work)' != 'true'">
|
| | | <QtWorkLog Remove="$(work_key)"/>
|
| | | <QtWorkLog Include="$(work_key)">
|
| | | <Hash>$(work_hash)</Hash>
|
| | | </QtWorkLog>
|
| | | </ItemGroup>
|
| | |
|
| | | <MakeDir Condition="'@(QtWork)' != '' AND '$(skip_work)' != 'true'"
|
| | | Directories="$([System.IO.Path]::GetDirectoryName(%(QtWork.OutputFile)))"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <work_key/>
|
| | | <log_hash/>
|
| | | <dependencies_changed/>
|
| | | <input_changed/>
|
| | | <project_changed/>
|
| | | <do_work/>
|
| | | <skip_work/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <log_entry Remove="@(log_entry)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtWork
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run Qt tools and add dynamic C++ sources to build
|
| | | // -->
|
| | | <Target Name="QtWork"
|
| | | Condition="'$(QtSkipWork)' != 'true'"
|
| | | DependsOnTargets="QtWorkPrepare;QtGetDefaultClCompile">
|
| | |
|
| | | <Message Importance="High" Condition="'$(QtDebug)' == 'true'"
|
| | | Text="## Qt Build $(QtBuildTargets.Replace(';',' ').Trim())" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run work locally in parallel processes
|
| | | // -->
|
| | | <QtRunWork
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
|
| | | AND '%(QtWork.ParallelBuild)' == 'true'
|
| | | AND '$(DesignTimeBuild)' != 'true'"
|
| | | QtWork="@(QtWork)" QtMaxProcs="$(QtMaxProcs)" QtDebug="$(QtDebug)">
|
| | | <Output TaskParameter="Result" ItemName="QtWorkResult" />
|
| | | </QtRunWork>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run work locally in a single process
|
| | | // -->
|
| | | <QtRunWork
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
|
| | | AND '%(QtWork.ParallelBuild)' != 'true'
|
| | | AND '$(DesignTimeBuild)' != 'true'"
|
| | | QtWork="@(QtWork)" QtMaxProcs="1" QtDebug="$(QtDebug)">
|
| | | <Output TaskParameter="Result" ItemName="QtWorkResult" />
|
| | | </QtRunWork>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run work in build host
|
| | | // -->
|
| | | <!-- // Translate local paths to host paths -->
|
| | | <Flatten
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | Items="@(QtWork)" Metadata="ResourceFiles">
|
| | | <Output TaskParameter="Result" ItemName="ResourceFiles"/>
|
| | | </Flatten>
|
| | | <ItemGroup
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
|
| | | <LocalPath Include="%(QtWork.Identity)">
|
| | | <Name>InputPath</Name>
|
| | | <Item>%(QtWork.Identity)</Item>
|
| | | <Value>%(QtWork.Identity)</Value>
|
| | | </LocalPath>
|
| | | <LocalPath
|
| | | Condition="'%(ResourceFiles.Identity)' != ''"
|
| | | Include="@(ResourceFiles->'%(Item)')">
|
| | | <Name>InputPath</Name>
|
| | | <Item>@(ResourceFiles->'%(Value)')</Item>
|
| | | <Value>@(ResourceFiles->'%(Value)')</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="%(QtWork.Identity)">
|
| | | <Name>OutputPath</Name>
|
| | | <Item>%(QtWork.OutputFile)</Item>
|
| | | <Value>%(QtWork.OutputFile)</Value>
|
| | | </LocalPath>
|
| | | </ItemGroup>
|
| | | <HostTranslatePaths
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | Items="@(LocalPath)" Names="InputPath;OutputPath">
|
| | | <Output TaskParameter="Result" ItemName="HostPath"/>
|
| | | </HostTranslatePaths>
|
| | | <ItemGroup>
|
| | | <InputPath Include="@(HostPath->WithMetadataValue('Name', 'InputPath'))" />
|
| | | <OutputPath Include="@(HostPath->WithMetadataValue('Name', 'OutputPath'))" />
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- // Run command -->
|
| | | <HostExec
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '%(Identity)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | Message="@(QtWork->'%(WorkType) %(Identity)')"
|
| | | Command="@(QtWork->'%(ToolPath) %(Options)')"
|
| | | Inputs="@(InputPath)"
|
| | | Outputs="@(OutputPath)"
|
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | RemoteProjectDir="$(_ResolvedRemoteProjectDir)">
|
| | | </HostExec>
|
| | |
|
| | | <!-- // Generate result item -->
|
| | | <ItemGroup
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
|
| | | <QtWorkResult Include="@(QtWork)">
|
| | | <ExitCode>0</ExitCode>
|
| | | </QtWorkResult>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Save tracking log of files read during build; used by VS to check the up-to-date status
|
| | | // -->
|
| | | <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
|
| | | <read_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.AdditionalDependencies)"
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
|
| | | <WorkType>%(QtWorkResult.WorkType)</WorkType>
|
| | | </read_log>
|
| | | <read_log>
|
| | | <Path Condition="$([System.String]::Copy('%(Identity)').StartsWith('^'))">%(Identity)</Path>
|
| | | <Path Condition="!$([System.String]::Copy('%(Identity)').StartsWith('^'))"
|
| | | >$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)','%(Identity)'))</Path>
|
| | | </read_log>
|
| | | </ItemGroup>
|
| | |
|
| | | <WriteLinesToFile
|
| | | Condition="'@(read_log)' != ''"
|
| | | File="$(TLogLocation)%(read_log.WorkType).read.1u.tlog"
|
| | | Lines="@(read_log->MetaData('Path')->ToUpperInvariant());"
|
| | | Overwrite="true"
|
| | | Encoding="Unicode"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Save tracking log of files written during build; used by VS to check the up-to-date status
|
| | | // -->
|
| | | <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
|
| | | <write_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.OutputFile)"
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
|
| | | <WorkType>%(QtWorkResult.WorkType)</WorkType>
|
| | | </write_log>
|
| | | <write_log>
|
| | | <Path Condition="$([System.String]::Copy('%(Identity)').StartsWith('^'))">%(Identity)</Path>
|
| | | <Path Condition="!$([System.String]::Copy('%(Identity)').StartsWith('^'))"
|
| | | >$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)','%(Identity)'))</Path>
|
| | | </write_log>
|
| | | </ItemGroup>
|
| | |
|
| | | <WriteLinesToFile Condition="'@(write_log)' != ''"
|
| | | File="$(TLogLocation)%(write_log.WorkType).write.1u.tlog"
|
| | | Lines="@(write_log->MetaData('Path')->ToUpperInvariant());"
|
| | | Overwrite="true" Encoding="Unicode"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Log output files; this is used by VS to determine what files to delete on "Clean"
|
| | | // -->
|
| | | <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
|
| | | <clean_log Include="%(QtWorkResult.OutputFile)"
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0'">
|
| | | <Source>@(QtWorkResult, '|')</Source>
|
| | | </clean_log>
|
| | | </ItemGroup>
|
| | |
|
| | | <WriteLinesToFile Condition="'@(clean_log)' != ''"
|
| | | File="$(TLogLocation)$(ProjectName).write.1u.tlog"
|
| | | Lines="^%(clean_log.Source);@(clean_log->'%(Fullpath)')"
|
| | | Encoding="Unicode"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Log calls to Qt tools; used in QtWorkPrepare to detect changes to the options of Qt tools
|
| | | // -->
|
| | | <WriteLinesToFile Condition="'@(QtWorkLog)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | File="$(QtLogFilePath)"
|
| | | Lines="@(QtWorkLog->'%(Identity)|%(Hash)')"
|
| | | Overwrite="true" Encoding="Unicode"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Generate build error if a Qt tool did not terminate correctly
|
| | | // -->
|
| | | <Error
|
| | | Condition="'%(QtWorkResult.ExitCode)' != ''
|
| | | AND '%(QtWorkResult.ExitCode)' != '0'
|
| | | AND '$(DesignTimeBuild)' != 'true'"
|
| | | File="%(QtWorkResult.Identity)" Code="%(QtWorkResult.ExitCode)"
|
| | | Text="%(QtWorkResult.WorkType) (%(QtWorkResult.ToolPath))"/>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Add dynamic C++ sources to build
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <QtWork_ClCompile
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.ClCompile)' != ''"
|
| | | Include="@(QtWorkResult->'%(ClCompile)')"/>
|
| | | <QtWork_ClCompile
|
| | | Condition="Exists('$(QtVarsOutputDir)\qtvars_plugin_import.cpp')"
|
| | | Include="$(QtVarsOutputDir)\qtvars_plugin_import.cpp"/>
|
| | | <!-- Add QML static plugins -->
|
| | | <QtWork_ClCompile
|
| | | Condition="Exists('$(QtQmlPluginImportCpp)')"
|
| | | Include="$(QtQmlPluginImportCpp)"/>
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(ApplicationType)' == 'Linux'">
|
| | | <QtWork_ClCompile Condition="'%(QtWork_ClCompile.ObjectFileName)' == ''">
|
| | | <ObjectFileName>$(IntDir)%(Filename).o</ObjectFileName>
|
| | | </QtWork_ClCompile>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- // Copy default C++ compiler properties -->
|
| | | <Expand Condition="'@(QtWork_ClCompile)' != ''"
|
| | | Items="@(QtWork_ClCompile)"
|
| | | BaseItem="@(ClCompile->WithMetadataValue('Identity', 'DefaultClCompile'))">
|
| | | <Output TaskParameter="Result" ItemName="QtWork_ClCompile_Expanded"/>
|
| | | </Expand>
|
| | |
|
| | | <!-- // Force pre-compiled header include -->
|
| | | <ItemGroup Condition="'$(ApplicationType)' != 'Linux'">
|
| | | <QtWork_ClCompile_Expanded>
|
| | | <AdditionalIncludeDirectories
|
| | | >$(ProjectDir);%(QtWork_ClCompile_Expanded.AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <ForcedIncludeFiles Condition="'%(PrecompiledHeader)' == 'Use'"
|
| | | >%(PrecompiledHeaderFile)</ForcedIncludeFiles>
|
| | | <AdditionalOptions>$([System.String]::Copy(
|
| | | '%(QtWork_ClCompile_Expanded.AdditionalOptions) %(QtWork_ClCompile_Expanded.AdditionalCppOptions)')
|
| | | .Trim())</AdditionalOptions>
|
| | | </QtWork_ClCompile_Expanded>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- // Add C++ source items and clean-up temp items -->
|
| | | <ItemGroup>
|
| | | <ClCompile Include="@(QtWork_ClCompile_Expanded)"/>
|
| | | <QtWork_ClCompile_Expanded Remove="@(QtWork_ClCompile_Expanded)"/>
|
| | | <QtWork_ClCompile Remove="@(QtWork_ClCompile)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// If sources were manually selected (e.g. by the 'Compile' option in the context menu for
|
| | | // project items), add generated C++ sources to the list of selected files -->
|
| | | <PropertyGroup Condition="'$(SelectedFiles)' != ''">
|
| | | <SelectedClCompile>@(QtWorkResult->'%(ClCompile)')</SelectedClCompile>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(SelectedClCompile)' != ''">
|
| | | <SelectedFiles>$(SelectedFiles);$(SelectedClCompile)</SelectedFiles>
|
| | | </PropertyGroup>
|
| | | <ItemGroup Condition="'$(SelectedClCompile)' != ''">
|
| | | <SelectedFiles Include="$(SelectedClCompile)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Update C++ sources with generated information
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtIncludePath>@(QtIncludePath->Distinct())</QtIncludePath>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <ClCompile_Updated Include="@(ClCompile)">
|
| | | <AdditionalIncludeDirectories
|
| | | >$(QtIncludePath);%(ClCompile.AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | </ClCompile_Updated>
|
| | | <ClCompile Remove="@(ClCompile)"/>
|
| | | <ClCompile Include="@(ClCompile_Updated)"/>
|
| | | <ClCompile_Updated Remove="@(ClCompile_Updated)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Clean-up
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <QtWork Remove="@(QtWork)"/>
|
| | | <QtWorkResult Remove="@(QtWorkResult)"/>
|
| | | <QtWorkLog Remove="@(QtWorkLog)"/>
|
| | | <read_log Remove="@(read_log)"/>
|
| | | <write_log Remove="@(write_log)"/>
|
| | | <clean_log Remove="@(clean_log)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET Qt
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Root Qt target
|
| | | // -->
|
| | | <Target Name="Qt" DependsOnTargets="QtPrepare;QtWork" BeforeTargets="FixupCLCompileOptions">
|
| | | <ItemGroup>
|
| | | <ClCompile Remove="DefaultClCompile" />
|
| | | </ItemGroup>
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtOuterBuild
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run targets in $(QtOuterBuildDependsOn) and then recursively invoke build
|
| | | // -->
|
| | | <Target Name="QtOuterBuild" DependsOnTargets="$(QtOuterBuildDependsOn)">
|
| | | <!--// Invoke inner build: recursive build in second MSBuild instance -->
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="Build"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | </MSBuild>
|
| | | <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
|
| | | </Target>
|
| | |
|
| | | <PropertyGroup
|
| | | Condition="'$(QtInnerBuild)' == '' AND '$(DesignTimeBuild)' != 'true'">
|
| | | <!--// Outer build: invoke inner build -->
|
| | | <BuildDependsOn>
|
| | | $(QtOuterBuildPrepare);
|
| | | QtOuterBuild;
|
| | | $(QtOuterBuildFinalize)
|
| | | </BuildDependsOn>
|
| | | <QtInnerBuild>$(MSBuildProjectFullPath)</QtInnerBuild>
|
| | | <RandomFileName>$([System.IO.Path]::GetRandomFileName())</RandomFileName>
|
| | | </PropertyGroup>
|
| | |
|
| | | <PropertyGroup
|
| | | Condition="'$(QtInnerBuild)' != '$(MSBuildProjectFullPath)' AND '$(DesignTimeBuild)' != 'true'">
|
| | | <!--// Dependent project inner build: skip build -->
|
| | | <BuildDependsOn>$(QtOuterBuildPrepare);$(QtOuterBuildFinalize)</BuildDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtEnterCriticalSection_... / QtLeaveCriticalSection_InitializeBuildStatus
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Synchronize calls to InitializeBuildStatus
|
| | | // -->
|
| | | <Target Name="QtEnterCriticalSection_InitializeBuildStatus" BeforeTargets="InitializeBuildStatus">
|
| | | <CriticalSection Lock="true" Name="$(ProjectGuid)" />
|
| | | </Target>
|
| | | <Target Name="QtLeaveCriticalSection_InitializeBuildStatus" AfterTargets="InitializeBuildStatus">
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | </Target>
|
| | | <PropertyGroup>
|
| | | <!--// Schedule critical section enter/leave targets around InitializeBuildStatus -->
|
| | | <QtSync_InitializeBuildStatus>
|
| | | QtEnterCriticalSection_InitializeBuildStatus;
|
| | | InitializeBuildStatus;
|
| | | QtLeaveCriticalSection_InitializeBuildStatus
|
| | | </QtSync_InitializeBuildStatus>
|
| | | <!--// Replace 'InitializeBuildStatus' with '$(QtSync_InitializeBuildStatus)' -->
|
| | | <BuildDependsOn>
|
| | | $([MSBuild]::Unescape(
|
| | | $([System.Text.RegularExpressions.Regex]::Replace(' $(BuildDependsOn) ',
|
| | | '(?<!\w)InitializeBuildStatus(?!\w)', $(QtSync_InitializeBuildStatus)))))
|
| | | </BuildDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtEnterCriticalSection_... / QtLeaveCriticalSection_FinalizeBuildStatus
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Synchronize calls to FinalizeBuildStatus
|
| | | // -->
|
| | | <Target Name="QtEnterCriticalSection_FinalizeBuildStatus" BeforeTargets="FinalizeBuildStatus">
|
| | | <CriticalSection Lock="true" Name="$(ProjectGuid)" />
|
| | | </Target>
|
| | | <Target Name="QtLeaveCriticalSection_FinalizeBuildStatus" AfterTargets="FinalizeBuildStatus">
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | </Target>
|
| | | <PropertyGroup>
|
| | | <!--// Schedule critical section enter/leave targets around FinalizeBuildStatus -->
|
| | | <QtSync_FinalizeBuildStatus>
|
| | | QtEnterCriticalSection_FinalizeBuildStatus;
|
| | | FinalizeBuildStatus;
|
| | | QtLeaveCriticalSection_FinalizeBuildStatus
|
| | | </QtSync_FinalizeBuildStatus>
|
| | | <!--// Replace 'FinalizeBuildStatus' with '$(QtSync_FinalizeBuildStatus)' -->
|
| | | <BuildDependsOn>
|
| | | $([MSBuild]::Unescape(
|
| | | $([System.Text.RegularExpressions.Regex]::Replace(' $(BuildDependsOn) ',
|
| | | '(?<!\w)FinalizeBuildStatus(?!\w)', $(QtSync_FinalizeBuildStatus)))))
|
| | | </BuildDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtLeaveCriticalSection_OnError
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Fail-safe release of critical section lock, to be used in OnError tasks
|
| | | // -->
|
| | | <Target Name="QtLeaveCriticalSection_OnError">
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | </Target>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Evaluation of Qt properties
|
| | | //
|
| | | // Preceding evaluation chain:
|
| | | // * Project global properties, incl. $(Keyword), $(WindowsTargetPlatformVersion), $(QtMsBuild)
|
| | | // * Microsoft.Cpp.Default.props
|
| | | // * Configuration properties, incl. $(ConfigurationType), $(PlatformToolset)
|
| | | // * qt_defaults.props
|
| | | // * Qt build settings, incl. $(QtInstall), $(QtModules)
|
| | | // * Property sheets preceding Qt.props
|
| | | //
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <PropertyGroup>
|
| | | <QtPrivateLoaded>true</QtPrivateLoaded>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Fail-safe import of default values
|
| | | // -->
|
| | | <Import
|
| | | Condition="'$(QtDefaultsLoaded)' != 'true'"
|
| | | Project="$(MSBuildThisFileDirectory)\qt_defaults.props"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Setup Qt installation path
|
| | | // -->
|
| | | <PropertyGroup Condition="'$(QtVsProjectSettings)' == 'true'">
|
| | | <QtInstallDir Condition="Exists('$(QtInstall)')">$(QtInstall)</QtInstallDir>
|
| | | <QtInstallRegKey Condition="'$(QtInstall)' != ''"
|
| | | >$(QtVersionsRegKey)\$(QtInstall)</QtInstallRegKey>
|
| | | <QtInstallRegDir Condition="'$(QtInstallDir)' == '' AND '$(QtInstallRegKey)' != ''"
|
| | | >$([MSBuild]::GetRegistryValue('$(QtInstallRegKey)','InstallDir'))</QtInstallRegDir>
|
| | | <QtInstallDir
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND '$(QtInstallDir)' == ''
|
| | | AND Exists('$(QtInstallRegDir)')"
|
| | | >$(QtInstallRegDir)</QtInstallDir>
|
| | | <QtInstallDir
|
| | | Condition="'$(ApplicationType)' == 'Linux' AND '$(QtInstallDir)' == ''
|
| | | AND ( $(QtInstallRegDir.StartsWith('SSH:')) OR $(QtInstallRegDir.StartsWith('WSL:')) )"
|
| | | >$(QtInstallRegDir.Split(':')[1])</QtInstallDir>
|
| | | <QtInstallDir
|
| | | Condition="'$(ApplicationType)' == 'Linux' AND '$(QtInstallDir)' == ''"
|
| | | >$(QtInstall)</QtInstallDir>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(QtInstallDir)' != ''">
|
| | | <QtToolsPath Condition="'$(QtToolsPath)' == ''"
|
| | | >$([System.IO.Path]::Combine('$(QtInstallDir)','$(QtPathBinaries)').Replace('\', '/'))</QtToolsPath>
|
| | | <QtDllPath Condition="'$(QtDllPath)' == ''"
|
| | | >$([System.IO.Path]::Combine('$(QtInstallDir)','$(QtPathLibraryExecutables)').Replace('\', '/'))</QtDllPath>
|
| | | <QTDIR>$(QtInstallDir)</QTDIR>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt Variables Expansion
|
| | | // -->
|
| | | <PropertyGroup Condition="'$(QtVsProjectSettings)' == 'true'">
|
| | |
|
| | | <!--// Path to Qt variables property file -->
|
| | | <QtVarsOutputDir Condition="'$(QtVarsOutputDir)' == ''"
|
| | | >$([System.IO.Path]::Combine('$(ProjectDir)', '$(IntDir)', 'qmake'))</QtVarsOutputDir>
|
| | | <QtVarsFileName Condition="'$(QtVarsFileName)' == ''"
|
| | | >qtvars_$(Platform.Replace(' ','_'))_$(Configuration.Replace(' ','_')).props</QtVarsFileName>
|
| | | <QtVarsFilePath Condition="'$(QtVarsFilePath)' == ''"
|
| | | >$(QtVarsOutputDir)\$(QtVarsFileName)</QtVarsFilePath>
|
| | |
|
| | | <!--// Path to temp work folder -->
|
| | | <QtVarsWorkDirName
|
| | | >temp</QtVarsWorkDirName>
|
| | | <QtVarsWorkDir
|
| | | >$([System.IO.Path]::Combine('$(QtVarsOutputDir)','$(QtVarsWorkDirName)'))</QtVarsWorkDir>
|
| | | <QtVarsWorkPath
|
| | | >$(QtVarsWorkDir)\$(QtVarsFileName)</QtVarsWorkPath>
|
| | | <QtVarsIndexPathDesignTime
|
| | | >$(QtVarsWorkDir)\$(ProjectGuid.Replace('{','').Replace('}','')).$(ProjectName).designtime.idx</QtVarsIndexPathDesignTime>
|
| | | <QtVarsDesignTime Condition="Exists('$(QtVarsIndexPathDesignTime)')"
|
| | | >$([System.String]::Copy($([System.IO.File]::ReadAllText('$(QtVarsIndexPathDesignTime)'))).Replace('
',''))</QtVarsDesignTime>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Import Qt variables (full build) -->
|
| | | <Import
|
| | | Condition="'$(DesignTimeBuild)' != 'true' AND Exists('$(QtVarsFilePath)')"
|
| | | Project="$(QtVarsFilePath)"/>
|
| | |
|
| | | <!--// Import Qt variables (design-time build) -->
|
| | | <Import
|
| | | Condition="'$(DesignTimeBuild)' == 'true' AND Exists('$(QtVarsDesignTime)')"
|
| | | Project="$(QtVarsDesignTime)"/>
|
| | |
|
| | | <!--// Import Qt variables (fall-back) -->
|
| | | <Import
|
| | | Condition=
|
| | | "'$(DesignTimeBuild)' == 'true' AND !Exists('$(QtVarsDesignTime)') AND Exists('$(QtVarsFilePath)')"
|
| | | Project="$(QtVarsFilePath)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Add Qt DLL path to debugger definitions
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <LocalDebuggerEnvironment Condition="'$(QtDllPath)' != ''"
|
| | | >PATH=%PATH%;$(QtDllPath)
$(LocalDebuggerEnvironment)
|
| | | </LocalDebuggerEnvironment>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // QML debugging
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QmlDebug Condition="'$(QtQMLDebugEnable)' == 'true'"
|
| | | >-qmljsdebugger=file:$(ProjectGuid),block</QmlDebug>
|
| | | <LocalDebuggerCommandArguments
|
| | | >$(QmlDebug)</LocalDebuggerCommandArguments>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Outer build
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtOuterBuildPrepare Condition="'$(QtOuterBuildPrepare)' == ''"
|
| | | >ResolveReferences;PrepareForBuild;InitializeBuildStatus</QtOuterBuildPrepare>
|
| | | <QtOuterBuildFinalize Condition="'$(QtOuterBuildFinalize)' == ''"
|
| | | >FinalizeBuildStatus</QtOuterBuildFinalize>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Extract Qt build settings from qmake-generated project files
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtVars
|
| | | Condition="'$(QtQMakeTemplate)' == 'app'"
|
| | | >$(QMake_Makefile)</QtVars>
|
| | | <QtVars
|
| | | Condition="'$(QtQMakeTemplate)' == 'vcapp'"
|
| | | >$(QMake_MSBuild);</QtVars>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Default item metadata
|
| | | // -->
|
| | | <ItemDefinitionGroup>
|
| | |
|
| | | <!--// C++ -->
|
| | | <ClCompile>
|
| | | <PreprocessorDefinitions Condition="'$(Qt_DEFINES_)' != ''"
|
| | | >$(Qt_DEFINES_);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <PreprocessorDefinitions Condition="'$(QtQMLDebugEnable)' == 'true'"
|
| | | >QT_QML_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <AdditionalIncludeDirectories Condition="'$(Qt_INCLUDEPATH_)' != ''"
|
| | | >$(Qt_INCLUDEPATH_);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | <LanguageStandard Condition="'$(Qt_STDCPP_)' != ''"
|
| | | >$(Qt_STDCPP_)</LanguageStandard>
|
| | | <AdditionalOptions Condition="'$(Qt_CL_OPTIONS_)' != ''"
|
| | | >$(Qt_CL_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
|
| | | </ClCompile>
|
| | |
|
| | | <!--// Linker (.obj files) -->
|
| | | <Link>
|
| | | <AdditionalDependencies Condition="'$(Qt_LIBS_)' != ''"
|
| | | >$(Qt_LIBS_);%(AdditionalDependencies)</AdditionalDependencies>
|
| | | <AdditionalLibraryDirectories Condition="'$(Qt_LIBPATH_)' != ''"
|
| | | >$(Qt_LIBPATH_);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
| | | <SharedLibrarySearchPath Condition="'$(Qt_LIBPATH_)' != ''"
|
| | | >$(Qt_LIBPATH_);%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
|
| | | <AdditionalOptions Condition="'$(Qt_LINK_OPTIONS_)' != ''"
|
| | | >$(Qt_LINK_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
|
| | | </Link>
|
| | | </ItemDefinitionGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Check static plugin import:
|
| | | // * If qmake generated a platform plugin import, assume QML plugins are also required.
|
| | | // -->
|
| | | <PropertyGroup Condition="Exists('$(QtVarsWorkDir)\qtvars_plugin_import.cpp')">
|
| | | <QtStaticPlugins>true</QtStaticPlugins>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Exclude Qt headers from code analysis
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <CAExcludePath>$(CAExcludePath);$(Qt_INCLUDEPATH_)</CAExcludePath>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Evaluate subfolder properties
|
| | | // -->
|
| | | <Import
|
| | | Project="$(QtMsBuildProps)"/>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Add property page for Qt settings
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <ItemGroup Condition="'$(QtVsProjectSettings)' == 'true'">
|
| | | <PropertyPageSchema
|
| | | Include="$(MSBuildThisFileDirectory)qt_settings.xml">
|
| | | <Context>Project;PropertySheet</Context>
|
| | | </PropertyPageSchema>
|
| | | </ItemGroup>
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <Rule
|
| | | Name="QtRule10_Settings"
|
| | | DisplayName="Qt Project Settings"
|
| | | PageTemplate="generic"
|
| | | Description="Qt Project Settings"
|
| | | Order="8"
|
| | | xmlns="http://schemas.microsoft.com/build/2009/properties">
|
| | | <Rule.DataSource>
|
| | | <DataSource Persistence="ProjectFile" Label="QtSettings" HasConfigurationCondition="true"/>
|
| | | </Rule.DataSource>
|
| | | <Rule.Categories>
|
| | | <Category Name="QtSettings_01_General" DisplayName="General"/>
|
| | | <Category Name="QtSettings_02_Paths" DisplayName="Paths"/>
|
| | | <Category Name="QtSettings_03_QMake" DisplayName="qmake"/>
|
| | | <Category Name="QtSettings_04_QML" DisplayName="QML"/>
|
| | | </Rule.Categories>
|
| | | <EnumProperty
|
| | | Name="Keyword"
|
| | | DisplayName="Qt VS Project Format Version"
|
| | | Category="QtSettings_01_General"
|
| | | ReadOnly="true"
|
| | | Description="Version of the format of this Qt Visual Studio project.">
|
| | | <EnumProperty.DataSource>
|
| | | <DataSource Persistence="ProjectFile" Label="Globals" />
|
| | | </EnumProperty.DataSource>
|
| | | <EnumValue Name="Qt4VSv1.0" DisplayName="Version 2.0"/>
|
| | | <EnumValue Name="QtVS_v300" DisplayName="Version 3.0"/>
|
| | | <EnumValue Name="QtVS_v301" DisplayName="Version 3.1"/>
|
| | | <EnumValue Name="QtVS_v302" DisplayName="Version 3.2"/>
|
| | | <EnumValue Name="QtVS_v303" DisplayName="Version 3.3"/>
|
| | | <EnumValue Name="QtVS_v304" DisplayName="Version 3.4"/>
|
| | | </EnumProperty>
|
| | | <StringProperty
|
| | | Name="QtLastBackgroundBuild"
|
| | | DisplayName="Last Background Build"
|
| | | Category="QtSettings_01_General"
|
| | | Visible="False">
|
| | | <StringProperty.DataSource>
|
| | | <DataSource Persistence="UserFile" Label="QtSettings" HasConfigurationCondition="true"/>
|
| | | </StringProperty.DataSource>
|
| | | </StringProperty>
|
| | | <DynamicEnumProperty
|
| | | Name="QtInstall"
|
| | | DisplayName="Qt Installation"
|
| | | Category="QtSettings_01_General"
|
| | | EnumProvider="QtVersionProvider"
|
| | | Description=
|
| | | "Select Qt installation; can be either a path to an installation directory or a version name registered through the Qt Visual Studio Tools (v2.4 or above).">
|
| | | </DynamicEnumProperty>
|
| | | <StringListProperty
|
| | | Name="QtModules"
|
| | | Category="QtSettings_01_General"
|
| | | DisplayName="Qt Modules">
|
| | | <StringListProperty.ValueEditors>
|
| | | <ValueEditor EditorType="QtModulesEditor" DisplayName="<Select Modules...>" />
|
| | | </StringListProperty.ValueEditors>
|
| | | </StringListProperty>
|
| | | <EnumProperty
|
| | | Name="QtBuildConfig"
|
| | | Category="QtSettings_01_General"
|
| | | DisplayName="Build Config"
|
| | | Description="Select whether to use debug or release.">
|
| | | <EnumValue Name="debug" DisplayName="Debug"/>
|
| | | <EnumValue Name="release" DisplayName="Release"/>
|
| | | </EnumProperty>
|
| | | <BoolProperty
|
| | | Name="QtDeploy"
|
| | | Category="QtSettings_01_General"
|
| | | DisplayName="Run Deployment Tool"
|
| | | Description="Select whether Qt for Windows Deployment Tool (windeployqt) should be called after build."/>
|
| | | <StringProperty
|
| | | Name="QtPathBinaries"
|
| | | Category="QtSettings_02_Paths"
|
| | | DisplayName="Qt Binaries"
|
| | | Description=
|
| | | "Path to folder containing executables of Qt tools (qmake, moc, etc.) When a non-rooted path is specified, it will be considered relative to the Qt installation directory."/>
|
| | | <StringProperty
|
| | | Name="QtPathLibraryExecutables"
|
| | | Category="QtSettings_02_Paths"
|
| | | DisplayName="Qt Library Executables"
|
| | | Description=
|
| | | "Path to folder containing executable files of Qt modules. When a non-rooted path is specified, it will be considered relative to the Qt installation directory."/>
|
| | | <StringListProperty
|
| | | Name="QtHeaderSearchPath"
|
| | | Category="QtSettings_02_Paths"
|
| | | DisplayName="Additional Qt header search paths" />
|
| | | <StringListProperty
|
| | | Name="QtLibrarySearchPath"
|
| | | Category="QtSettings_02_Paths"
|
| | | DisplayName="Additional Qt library search paths" />
|
| | | <EnumProperty
|
| | | Name="QtQMakeTemplate"
|
| | | Category="QtSettings_03_QMake"
|
| | | DisplayName="Template"
|
| | | Description="Template of generated project files for extraction of Qt build settings.">
|
| | | <EnumValue Name="vcapp" DisplayName="MSBuild" />
|
| | | <EnumValue Name="app" DisplayName="Makefile" />
|
| | | </EnumProperty>
|
| | | <StringListProperty
|
| | | Name="QtVars"
|
| | | Category="QtSettings_03_QMake"
|
| | | DisplayName="Extract Variables"
|
| | | Visible="False" />
|
| | | <StringListProperty
|
| | | Name="QMakeExtraArgs"
|
| | | Category="QtSettings_03_QMake"
|
| | | DisplayName="Additional Command Arguments" />
|
| | | <StringListProperty
|
| | | Name="QMakeCodeLines"
|
| | | Category="QtSettings_03_QMake"
|
| | | DisplayName="Additional Project Settings" />
|
| | | <BoolProperty
|
| | | Name="QtQMLDebugEnable"
|
| | | Category="QtSettings_04_QML"
|
| | | DisplayName="Enable QML Debugging"
|
| | | Description="Select whether to launch a QML session when debugging.">
|
| | | </BoolProperty>
|
| | | </Rule>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | *****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | *****************************************************************************
|
| | | <#@output extension="targets" #>
|
| | | <#@include file="$(SolutionDir)\common.tt" #>
|
| | | ** <#=WARNING_GENERATED_FILE#>
|
| | | *****************************************************************************
|
| | | -->
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Helper inline tasks used by the Qt/MSBuild targets
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | |
|
| | | <!-- BEGIN Generated code <#=XML_COMMENT_END#><#
|
| | |
|
| | | // Parse .cs files and generate inline MSBuild tasks using C# code
|
| | | //
|
| | | var files = Directory.GetFiles(Path.Combine(SolutionDir, "QtMsBuild", "Tasks"), "*.cs");
|
| | | foreach(var file in files) {
|
| | | var text = File.ReadAllText(file);
|
| | | var result = TaskParser.Parse(text);
|
| | | var commentLines = (result.GetValues<string>("COMMENT")
|
| | | .FirstOrDefault() ?? "")
|
| | | .TrimEnd('\r', '\n').Split(new[] {"\r\n"}, StringSplitOptions.None);
|
| | | var taskAttribs = result.GetValues<string>("ATTRIBS")
|
| | | .FirstOrDefault() ?? "";
|
| | | var namespaces = result.GetValues<List<string>>("USING")
|
| | | .FirstOrDefault() ?? new List<string>();
|
| | | var parameters = (result.GetValues<List<ParamDecl>>("PARAMS")
|
| | | .FirstOrDefault() ?? new List<ParamDecl>())
|
| | | .Where((ParamDecl p) => !string.IsNullOrEmpty(p.name))
|
| | | .OrderBy((ParamDecl p) => p.isOut)
|
| | | .ThenBy((ParamDecl p) => p.isOptional);
|
| | | var taskCode = result.GetValues<string>("CODE")
|
| | | .FirstOrDefault()?.TrimEnd('\r', '\n') ?? "";
|
| | | var assemblyRefs = (result.GetValues<List<string>>("REFERENCE")
|
| | | .FirstOrDefault() ?? new List<string>())
|
| | | .Select(assemblyRef => assemblyRef.Trim());
|
| | |
|
| | | WriteLine(string.Format(
|
| | | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | @"
|
| | | {0}
|
| | | {1}
|
| | | {2}
|
| | | <UsingTask {3}
|
| | | TaskFactory=""CodeTaskFactory""
|
| | | AssemblyFile=""$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"">
|
| | | <ParameterGroup>{4}
|
| | | </ParameterGroup>
|
| | | <Task>{5}{6}
|
| | | <Code Type=""Fragment"" Language=""cs"">
|
| | | <![CDATA[
|
| | | {7}
|
| | | ]]>
|
| | | </Code>
|
| | | </Task>
|
| | | </UsingTask>",
|
| | | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /*{0}*/ XML_COMMENT_BEGIN,
|
| | | /*{1}*/ string.Join("\r\n ", commentLines),
|
| | | /*{2}*/ XML_COMMENT_END,
|
| | | /*{3}*/ taskAttribs,
|
| | | /*{4}*/ string.Join("", parameters.Select(param => string.Format(
|
| | | @"
|
| | | <{0} ParameterType=""{1}""{2}{3}/>",
|
| | | /*{0}*/ param.name,
|
| | | /*{1}*/ param.type,
|
| | | /*{2}*/ param.isOut ? @" Output=""true""" : "",
|
| | | /*{3}*/ !param.isOut && !param.isOptional ? @" Required=""true""" : ""))),
|
| | | /*{5}*/ string.Join("", assemblyRefs.Select(assemblyRef => string.Format(
|
| | | @"
|
| | | <Reference Include=""{0}""/>",
|
| | | /*{0}*/ assemblyRef))),
|
| | | /*{6}*/ string.Join("", namespaces.Select(nameSpc => string.Format(
|
| | | @"
|
| | | <Using Namespace=""{0}""/>",
|
| | | /*{0}*/ nameSpc))),
|
| | | /*{7}*/ taskCode));
|
| | | }
|
| | | #>
|
| | | <#=XML_COMMENT_BEGIN#> END Generated code -->
|
| | |
|
| | | </Project>
|
| | | <!--<#=XML_COMMENT_END#>
|
| | | <#@assembly Name="$(SolutionDir)\QtVsTools.RegExpr\bin\$(Configuration)\QtVsTools.RegExpr.dll" #>
|
| | | <#@import namespace="static QtVsTools.SyntaxAnalysis.RegExpr" #>
|
| | | <#+
|
| | | class ParamDecl {
|
| | | public string name;
|
| | | public string type;
|
| | | public bool isOptional;
|
| | | public bool isOut;
|
| | | }
|
| | |
|
| | | Parser InitTaskParser()
|
| | | {
|
| | | var name
|
| | | = CharSet[CharWord + Chars['.']].Repeat();
|
| | |
|
| | | var assemblyRef
|
| | | = StartOfLine & HorizSpace & "//" & new Token("REF", HorizSpace, Line) & LineBreak;
|
| | |
|
| | | var usingStmt
|
| | | = new Token("using")
|
| | | & new Token("NAMESPACE", new Token("static").Optional() & name)
|
| | | & new Token(";");
|
| | |
|
| | | var paramDecl = new Token("PARAM",
|
| | | new Token("PARAM_OUT", "out").Optional()
|
| | | & new Token("PARAM_TYPE", name & new Token("[]").Optional())
|
| | | & new Token("PARAM_NAME", Word)
|
| | | & new Token("PARAM_OPTIONAL", "="
|
| | | & (new Token("null") | new Token("0") | new Token("false"))).Optional()
|
| | | & new Token(CharSet[',', ')']))
|
| | | {
|
| | | new Rule<ParamDecl>
|
| | | {
|
| | | Update("PARAM_NAME", (ParamDecl p, string value) => p.name = value),
|
| | | Update("PARAM_TYPE", (ParamDecl p, string value) => p.type = value),
|
| | | Update("PARAM_OUT", (ParamDecl p, string value) => p.isOut = true),
|
| | | Update("PARAM_OPTIONAL", (ParamDecl p, string value) => p.isOptional = true),
|
| | | }
|
| | | };
|
| | |
|
| | | var regionReference
|
| | | = StartOfLine & HorizSpace & "#region Reference" & Line & LineBreak
|
| | | & new Token("REFERENCE", SkipWs_Disable, assemblyRef.Repeat())
|
| | | {
|
| | | new Rule<List<string>>
|
| | | {
|
| | | Update("REF", (List<string> list, string refName) => list.Add(refName))
|
| | | }
|
| | | };
|
| | |
|
| | | var regionUsing
|
| | | = StartOfLine & HorizSpace & "#region Using" & Line & LineBreak
|
| | | & new Token("USING", usingStmt.Repeat())
|
| | | {
|
| | | new Rule<List<string>>
|
| | | {
|
| | | Update("NAMESPACE", (List<string> list, string nameSpc) => list.Add(nameSpc))
|
| | | }
|
| | | };
|
| | |
|
| | | var regionComment
|
| | | = StartOfLine & HorizSpace & "#region Comment" & Line & LineBreak
|
| | | & new Token("COMMENT", SkipWs_Disable,
|
| | | (!LookAhead[StartOfLine & HorizSpace & "#endregion"]
|
| | | & StartOfLine & HorizSpace & Line & LineBreak).Repeat());
|
| | |
|
| | | var regionParameters
|
| | | = StartOfLine & HorizSpace & "#region Parameters" & Line & LineBreak
|
| | | & new Token("PARAMS", paramDecl.Repeat())
|
| | | {
|
| | | new Rule<List<ParamDecl>>
|
| | | {
|
| | | Update("PARAM", (List<ParamDecl> list, ParamDecl param) => list.Add(param))
|
| | | }
|
| | | };
|
| | |
|
| | | var regionCode
|
| | | = StartOfLine & HorizSpace & "#region Code" & Line & LineBreak
|
| | | & new Token("CODE", SkipWs_Disable,
|
| | | (!LookAhead[StartOfLine & HorizSpace & "#endregion"]
|
| | | & StartOfLine & HorizSpace & Line & LineBreak).Repeat());
|
| | |
|
| | | var task
|
| | | = StartOfLine & HorizSpace & "#region Task" & new Token("ATTRIBS", Line) & LineBreak
|
| | | & ( regionReference
|
| | | | regionUsing
|
| | | | regionComment
|
| | | | regionParameters
|
| | | | regionCode
|
| | | | (Line & LineBreak)
|
| | | ).Repeat();
|
| | |
|
| | | return task.Render(Space);
|
| | | }
|
| | |
|
| | | Parser _TaskParser;
|
| | | Parser TaskParser => _TaskParser ?? (
|
| | | _TaskParser = InitTaskParser());
|
| | | //-->#>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2019 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Read Qt Build Variables
|
| | | // -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | |
|
| | | <PropertyGroup Condition="'$(QtVsProjectSettings)' == 'true'">
|
| | | <QtOuterBuildDependsOn>QtVarsPrepare;QtVars;$(QtDependsOn)</QtOuterBuildDependsOn>
|
| | | <CleanDependsOn>$(CleanDependsOn);QtVarsClean</CleanDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <Target Name="ResolveHost" DependsOnTargets="ResolveRemoteDir"
|
| | | Condition="'$(ApplicationType)' == 'Linux' AND '$(PlatformToolset)' != 'WSL_1_0'">
|
| | | <ResolveRemoteDir
|
| | | Condition="'$(_ResolvedRemoteProjectDir)' == ''"
|
| | | RemoteProjectDir="$(RemoteProjectDir)"
|
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | ProjectDir="$(ProjectDir)"
|
| | | IntermediateDir="$(IntDir)"
|
| | | RemoteProjectDirFile="$(RemoteProjectDirFile)">
|
| | | <Output TaskParameter="ResolvedRemoteProjectDir" PropertyName="_ResolvedRemoteProjectDir"/>
|
| | | </ResolveRemoteDir>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtVars
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Call qmake with generated .pro file to export Qt variables into MSBuild .props file
|
| | | // -->
|
| | | <Target
|
| | | Name="QtVars"
|
| | | Condition="'$(QtVsProjectSettings)' == 'true'"
|
| | | DependsOnTargets="QtMocInit;QtUicInit;ResolveHost"
|
| | | Inputs="$(MSBuildProjectFile)" Outputs="$(QtVarsFilePath)">
|
| | |
|
| | | <!--// Check if qmake is in the tools path -->
|
| | | <Error Condition="'$(QtToolsPath)' == ''" Text="There's no Qt version assigned to project $(MSBuildProjectFile) for configuration $(Configuration)/$(Platform).
Please set a Qt installation in 'Project|Properties|Configuration Properties|Qt Project Settings|Qt Installation'."/>
|
| | | <Error
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND !Exists('$(QtToolsPath)\qmake.exe')"
|
| | | Text="qmake not found in $(QtToolsPath) when building project $(MSBuildProjectFile)"/>
|
| | |
|
| | | <!--// Ensure C++ compiler in PATH -->
|
| | | <Exec
|
| | | Condition="'$(ApplicationType)' != 'Linux'"
|
| | | Command="WHERE /Q cl.exe" IgnoreExitCode="true">
|
| | | <Output TaskParameter="ExitCode" PropertyName="ErrorLevel"/>
|
| | | </Exec>
|
| | | <SetEnv
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND '$(ErrorLevel)' != '0'"
|
| | | Name="PATH" Prefix="true" Value="$(ExecutablePath)"/>
|
| | |
|
| | | <!--// Set-up temp directory -->
|
| | | <RemoveDir
|
| | | Directories="$(QtVarsWorkDir)"/>
|
| | | <MakeDir
|
| | | Directories="$(QtVarsWorkDir)"/>
|
| | |
|
| | | <!--// Translate local paths to build host paths -->
|
| | | <ItemGroup>
|
| | | <LocalPath Include="WorkDir">
|
| | | <Name>Path</Name>
|
| | | <Item>$(QtVarsWorkDir)</Item>
|
| | | <Value>$(QtVarsWorkDir)</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="QMakeProps">
|
| | | <Name>Path</Name>
|
| | | <Item>$(QtVarsWorkDir)\props.txt</Item>
|
| | | <Value>$(QtVarsWorkDir)\props.txt</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="QMakeLog">
|
| | | <Name>Path</Name>
|
| | | <Item>$(QtVarsWorkDir)\qtvars.log</Item>
|
| | | <Value>$(QtVarsWorkDir)\qtvars.log</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="QMakeProj">
|
| | | <Name>Path</Name>
|
| | | <Item>$(QtVarsWorkDir)\qtvars.pro</Item>
|
| | | <Value>$(QtVarsWorkDir)\qtvars.pro</Value>
|
| | | </LocalPath>
|
| | | <LocalPath Include="QtMakefile">
|
| | | <Name>Path</Name>
|
| | | <Item>$(QtVarsWorkDir)\Makefile</Item>
|
| | | <Value>$(QtVarsWorkDir)\Makefile</Value>
|
| | | </LocalPath>
|
| | | </ItemGroup>
|
| | | <HostTranslatePaths Items="@(LocalPath)" Names="Path">
|
| | | <Output TaskParameter="Result" ItemName="HostPath"/>
|
| | | </HostTranslatePaths>
|
| | | <ItemGroup>
|
| | | <WorkDir Include="@(HostPath->WithMetadataValue('Identity', 'WorkDir'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </WorkDir>
|
| | | <QMakeProps Include="@(HostPath->WithMetadataValue('Identity', 'QMakeProps'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QMakeProps>
|
| | | <QMakeLog Include="@(HostPath->WithMetadataValue('Identity', 'QMakeLog'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QMakeLog>
|
| | | <QMakeProj Include="@(HostPath->WithMetadataValue('Identity', 'QMakeProj'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QMakeProj>
|
| | | <QtMakefile Include="@(HostPath->WithMetadataValue('Identity', 'QtMakefile'))">
|
| | | <LocalPath>%(Item)</LocalPath>
|
| | | <HostPath>%(Value)</HostPath>
|
| | | </QtMakefile>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// Run qmake: query properties -->
|
| | | <PropertyGroup>
|
| | | <Cmd><![CDATA["$(QtToolsPath)/qmake" -query]]></Cmd>
|
| | | </PropertyGroup>
|
| | | <HostExec
|
| | | Command="$(Cmd)" RedirectStdOut="props.txt"
|
| | | WorkingDirectory="@(WorkDir->'%(HostPath)')"
|
| | | Outputs="@(QMakeProps)"
|
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | RemoteProjectDir="$(_ResolvedRemoteProjectDir)" />
|
| | | <ReadLinesFromFile
|
| | | File="@(QMakeProps->'%(LocalPath)')">
|
| | | <Output TaskParameter="Lines" ItemName="QMakeQueryResult"/>
|
| | | </ReadLinesFromFile>
|
| | |
|
| | | <!--// Parse qmake query result -->
|
| | | <ItemGroup>
|
| | | <QMakeQueryResult>
|
| | | <SepIdx>$([System.String]::Copy('%(Identity)').IndexOf(':'))</SepIdx>
|
| | | </QMakeQueryResult>
|
| | | <QMakeQueryResult>
|
| | | <ValueIdx>$([MSBuild]::Add(%(SepIdx), 1))</ValueIdx>
|
| | | </QMakeQueryResult>
|
| | | <QMakeQueryResult>
|
| | | <Name>$([System.String]::Copy('%(Identity)').Substring(0, %(SepIdx)).Replace('/', "SLASH"))</Name>
|
| | | <Value>$([System.String]::Copy('%(Identity)').Substring(%(ValueIdx)))</Value>
|
| | | </QMakeQueryResult>
|
| | | <QMakeProperty
|
| | | Include="@(QMakeQueryResult->'%(Name)')"
|
| | | RemoveMetadata="Name;SepIdx;ValueIdx"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// Parse Qt version -->
|
| | | <PropertyGroup Condition="'@(QMakeProperty)' != ''">
|
| | | <QtVersionMajor>0</QtVersionMajor>
|
| | | <QtVersionMinor>0</QtVersionMinor>
|
| | | <QtVersionPatch>0</QtVersionPatch>
|
| | | <QtVersionParts>0</QtVersionParts>
|
| | | <QtVersion
|
| | | >@(QMakeProperty->WithMetadataValue('Identity', 'QT_VERSION')->'%(Value)')</QtVersion>
|
| | | <QtVersionParts
|
| | | Condition="'$(QtVersion)' != ''">$(QtVersion.Split('.').Length)</QtVersionParts>
|
| | | <QtVersionMajor Condition="$(QtVersionParts) >= 1">$(QtVersion.Split('.')[0])</QtVersionMajor>
|
| | | <QtVersionMinor Condition="$(QtVersionParts) >= 2">$(QtVersion.Split('.')[1])</QtVersionMinor>
|
| | | <QtVersionPatch Condition="$(QtVersionParts) >= 3">$(QtVersion.Split('.')[2])</QtVersionPatch>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Workaround for 5.13.2 NDEBUG obsession -->
|
| | | <PropertyGroup
|
| | | Condition="$(QtVersionMajor) > 5
|
| | | OR ($(QtVersionMajor) == 5 AND ($(QtVersionMinor) > 13
|
| | | OR ($(QtVersionMinor) == 13 AND ($(QtVersionPatch) >= 2))))">
|
| | | <QMakeOptionEarly>true</QMakeOptionEarly>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// qmake command line arguments -->
|
| | | <ItemGroup>
|
| | | <QMakeArgsList Condition="'$(QMakeOptionEarly)' == 'true'" Include="-early"/>
|
| | | <QMakeArgsList Include="CONFIG -= debug release debug_and_release"/>
|
| | | <QMakeArgsList Include="CONFIG += $(QtBuildConfig)"/>
|
| | | <QMakeArgsList Include="$(QMakeExtraArgs)"/>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <QMakeArgsList>
|
| | | <Escaped>%(Identity)</Escaped>
|
| | | <Escaped Condition="$([System.String]::Copy('%(Identity)').Contains(' '))
|
| | | OR $([System.String]::Copy('%(Identity)').Contains('"'))"
|
| | | >"$([System.String]::Copy('%(Identity)').Replace('"','\"'))"</Escaped>
|
| | | </QMakeArgsList>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <QMakeArgs>@(QMakeArgsList->'%(Escaped)', ' ')</QMakeArgs>
|
| | | <QMakeArgs Condition="'$(QtQMakeTemplate)' == 'vcapp'"> -tp vc $(QMakeArgs)</QMakeArgs>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Modules and additional .pro file lines -->
|
| | | <ItemGroup>
|
| | | <QtModuleList Include="$(QtModules)"/>
|
| | | <QMakeCodeLine Include="$(QMakeCodeLines)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// Generate INCLUDEPATH value -->
|
| | | <ItemGroup>
|
| | | <QtIncludesList Include="$(QtHeaderSearchPath)"/>
|
| | | <QtIncludes Include=
|
| | | "$([System.IO.Path]::Combine($(QtInstallDir),$([System.String]::Copy('%(QtIncludesList.Identity)'))))"/>
|
| | | <QtIncludesList Remove="@(QtIncludesList)"/>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <QtIncludes>@(QtIncludes->'"%(Identity)"', ' ')</QtIncludes>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Generate LIBS value -->
|
| | | <ItemGroup>
|
| | | <QtLibsList Include="$(QtLibrarySearchPath)"/>
|
| | | <QtLibs Include=
|
| | | "$([System.IO.Path]::Combine($(QtInstallDir),$([System.String]::Copy('%(QtLibsList.Identity)'))))"/>
|
| | | <QtLibsList Include="@(QtLibsList)"/>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <QtLibs>@(QtLibs->'"-L%(Identity)"', ' ')</QtLibs>
|
| | | </PropertyGroup>
|
| | |
|
| | | <Message
|
| | | Importance="high"
|
| | | Text="Reading Qt configuration ($(QtToolsPath)/qmake)"/>
|
| | |
|
| | | <PropertyGroup>
|
| | |
|
| | | <!--// .pro file configuration -->
|
| | | <QtVarsProFileConfig>
|
| | | CONFIG += no_fixpath
|
| | | </QtVarsProFileConfig>
|
| | |
|
| | | <!--// .pro file input parameters -->
|
| | | <QtVarsProFileInput>
|
| | | <!--
|
| | | # Selected Qt modules -->
|
| | | QT += @(QtModuleList->'%(Identity)', ' ')
|
| | | <!--
|
| | | # Custom additional .pro file code (from property page) -->
|
| | | @(QMakeCodeLine->'%(Identity)','%0D%0A')
|
| | | </QtVarsProFileInput>
|
| | | <!--
|
| | | # Custom additional header search paths (from property page) -->
|
| | | <QtVarsProFileInput Condition="'$(QtHeaderSearchPath)' != ''">
|
| | | $(QtVarsProFileInput)
|
| | | INCLUDEPATH += $(QtIncludes)
|
| | | </QtVarsProFileInput>
|
| | | <!--
|
| | | # Custom additional library search paths (from property page) -->
|
| | | <QtVarsProFileInput Condition="'$(QtLibrarySearchPath)' != ''">
|
| | | $(QtVarsProFileInput)
|
| | | LIBS += $(QtLibs)
|
| | | </QtVarsProFileInput>
|
| | | <!--
|
| | | # Undef UNICODE macro if project is configured with multi-byte char set -->
|
| | | <QtVarsProFileInput Condition="'$(CharacterSet)' == 'MultiByte'">
|
| | | $(QtVarsProFileInput)
|
| | | DEFINES -= UNICODE _UNICODE
|
| | | </QtVarsProFileInput>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Write .pro file to temp path -->
|
| | | <WriteLinesToFile
|
| | | File="$(QtVarsWorkDir)\qtvars.pro"
|
| | | Lines="$(QtVarsProFileConfig)
|
| | | ;$(QtVarsProFileInput)"/>
|
| | |
|
| | | <!--// Write start of Qt vars data file:
|
| | | // * Open property group tag -->
|
| | | <PropertyGroup>
|
| | | <!--
|
| | | ######## BEGIN generated XML (.props) ##############################################################
|
| | | ## -->
|
| | | <QtVarsDataFileText>
|
| | | <![CDATA[
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | | <PropertyGroup>
|
| | | ]]>
|
| | | </QtVarsDataFileText>
|
| | | <!--
|
| | | ##
|
| | | ######## END generated XML (.props) ################################################################
|
| | | -->
|
| | | </PropertyGroup>
|
| | | <WriteLinesToFile File="$(QtVarsWorkPath)" Lines="$(QtVarsDataFileText)" Overwrite="true"/>
|
| | |
|
| | | <!--// Run qmake: convert Makefile vars to .props (XML) file -->
|
| | | <PropertyGroup>
|
| | | <Cmd><![CDATA["$(QtToolsPath)/qmake" $(QMakeArgs) qtvars.pro]]></Cmd>
|
| | | </PropertyGroup>
|
| | | <HostExec
|
| | | Command="$(Cmd)" RedirectStdOut="qtvars.log" RedirectStdErr="STDOUT"
|
| | | WorkingDirectory="@(WorkDir->'%(HostPath)')"
|
| | | Inputs="@(QMakeProj)"
|
| | | Outputs="@(QtMakefile);@(QMakeLog)"
|
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | RemoteProjectDir="$(_ResolvedRemoteProjectDir)"
|
| | | IgnoreExitCode="true">
|
| | | <Output TaskParameter="ExitCode" PropertyName="ErrorLevel"/>
|
| | | </HostExec>
|
| | |
|
| | | <!--// Check qmake result -->
|
| | | <PropertyGroup
|
| | | Condition="'$(ErrorLevel)' != '0'
|
| | | OR ( '$(QtQMakeTemplate)' == 'app' AND !Exists('$(QtVarsWorkDir)\Makefile') )
|
| | | OR ( '$(QtQMakeTemplate)' == 'vcapp' AND !Exists('$(QtVarsWorkDir)\qtvars.vcxproj') )">
|
| | | <QMakeError>true</QMakeError>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Get qmake console output -->
|
| | | <ItemGroup>
|
| | | <QMakeError Include="($(QtToolsPath)/qmake)"/>
|
| | | <QMakeError Include="%24PWD=$(QtVarsWorkDir)"/>
|
| | | </ItemGroup>
|
| | | <ReadLinesFromFile
|
| | | File="$(QtVarsWorkDir)\qtvars.log">
|
| | | <Output TaskParameter="Lines" ItemName="QMakeError"/>
|
| | | </ReadLinesFromFile>
|
| | | <ItemGroup>
|
| | | <QMakeError
|
| | | Condition="$([System.String]::Copy('%(Identity)').StartsWith('Info: creating stash file'))"
|
| | | Remove="@(QMakeError)"/>
|
| | | <QMakeError
|
| | | Condition="'$(QtQMakeTemplate)' == 'app' AND !Exists('$(QtVarsWorkDir)\Makefile')"
|
| | | Include="Error creating Makefile"/>
|
| | | <QMakeError
|
| | | Condition="'$(QtQMakeTemplate)' == 'vcapp' AND !Exists('$(QtVarsWorkDir)\qtvars.vcxproj')"
|
| | | Include="Error creating .vcxproj file"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// If error, show qmake console output and stop build -->
|
| | | <Error
|
| | | Condition="'$(QMakeError)' == 'true'"
|
| | | File="$(MSBuildProjectFile)"
|
| | | Text="ERROR running qmake%0D%0Aqmake: @(QMakeError->'%(Identity)','%0D%0Aqmake: ')%0D%0A"/>
|
| | | <Message
|
| | | Importance="high"
|
| | | Condition="'$(QMakeError)' != 'true' AND '$(QtVarsDebug)' == 'true'"
|
| | | Text="qmake: @(QMakeError->'%(Identity)','%0D%0Aqmake: ')"/>
|
| | |
|
| | |
|
| | | <!--//// Extract Qt vars from Makefile
|
| | | // -->
|
| | | <!--// Parse variable definition expressions for Makefile -->
|
| | | <ParseVarDefs
|
| | | Condition="'$(QtQMakeTemplate)' == 'app' AND '$(QtVars)' != ''"
|
| | | QtVars="$(QtVars)">
|
| | | <Output TaskParameter="OutVarDefs" ItemName="QMake_Makefile_VarDef"/>
|
| | | </ParseVarDefs>
|
| | |
|
| | | <!--// Read variables from Makefile -->
|
| | | <GetVarsFromMakefile
|
| | | Condition="'$(QtQMakeTemplate)' == 'app'"
|
| | | Makefile="$(QtVarsWorkDir)\Makefile" VarDefs="@(QMake_Makefile_VarDef)"
|
| | | ExcludeValues="$(QtVarsWorkDir)">
|
| | | <Output TaskParameter="OutVars" ItemName="QtVar"/>
|
| | | </GetVarsFromMakefile>
|
| | |
|
| | | <!--//// Extract Qt vars from .vcxproj file
|
| | | // -->
|
| | | <!--// Parse variable definition expressions for .vcxproj file -->
|
| | | <ItemGroup Condition="'$(QtQMakeTemplate)' == 'vcapp'">
|
| | | <QMake_MSBuild_VarDef Include="$(QMake_MSBuild)"/>
|
| | | <QMake_MSBuild_VarDef>
|
| | | <Name>$([System.String]::Copy('%(Identity)').Split('=')[0].Trim())</Name>
|
| | | <XPath>$([System.String]::Copy('%(Identity)').Split('=')[1].Trim())</XPath>
|
| | | </QMake_MSBuild_VarDef>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// Read variables from .vcxproj file -->
|
| | | <GetVarsFromMSBuild
|
| | | Condition="'$(QtQMakeTemplate)' == 'vcapp'"
|
| | | Project="$(QtVarsWorkDir)\qtvars.vcxproj"
|
| | | VarDefs="@(QMake_MSBuild_VarDef)"
|
| | | ExcludeValues="$(QtVarsWorkDir)">
|
| | | <Output TaskParameter="OutVars" ItemName="QtVar"/>
|
| | | </GetVarsFromMSBuild>
|
| | |
|
| | | <!--// Write variables as MSBuild properties to .props file -->
|
| | | <PropertyGroup>
|
| | | <QtMakefileVars Condition="'@(QtVar)' != ''">
|
| | | <![CDATA[@(QtVar->'<Qt_%(Identity)_>%(Value)</Qt_%(Identity)_>','%0D%0A')]]>
|
| | | </QtMakefileVars>
|
| | | </PropertyGroup>
|
| | | <WriteLinesToFile Condition="'$(QtMakefileVars)' != ''"
|
| | | File="$(QtVarsWorkPath)" Lines="$([System.String]::Copy($(QtMakefileVars)))"/>
|
| | |
|
| | | <!--// Write qmake properties as MSBuild properties to .props file -->
|
| | | <PropertyGroup>
|
| | | <QMakeProps Condition="'@(QtVar)' != ''">
|
| | | <![CDATA[@(QMakeProperty->'<QMake_%(Identity)_>%(Value)</QMake_%(Identity)_>','%0D%0A')]]>
|
| | | </QMakeProps>
|
| | | </PropertyGroup>
|
| | | <WriteLinesToFile Condition="'$(QMakeProps)' != ''"
|
| | | File="$(QtVarsWorkPath)" Lines="$([System.String]::Copy($(QMakeProps)))"/>
|
| | |
|
| | | <!--// Qt settings list for backup -->
|
| | | <ItemGroup>
|
| | | <QtInstall Include="$(QtInstall)"/>
|
| | | <QtModules Include="$(QtModules)"/>
|
| | | <QtPathBinaries Include="$(QtPathBinaries)"/>
|
| | | <QtPathLibraryExecutables Include="$(QtPathLibraryExecutables)"/>
|
| | | <QtHeaderSearchPath Include="$(QtHeaderSearchPath)"/>
|
| | | <QtLibrarySearchPath Include="$(QtLibrarySearchPath)"/>
|
| | | <QtVariables Include="$(QtVars)"/>
|
| | | <QMakeCodeLines Include="$(QMakeCodeLines)"/>
|
| | | <QtBuildConfig Include="$(QtBuildConfig)"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!--// Write end of .props (XML) file
|
| | | // * Add Qt tools output directories to include path
|
| | | // * Save settings backup
|
| | | // * Close property group tag
|
| | | // * Create QtVar items to export Qt variables to the calling instance of MSBuild
|
| | | // * Close project tag -->
|
| | | <PropertyGroup>
|
| | | <!--
|
| | | ######## BEGIN generated XML (.props) ##############################################################
|
| | | ## -->
|
| | | <QtVarsDataFileText>
|
| | | <![CDATA[
|
| | | <Qt_INCLUDEPATH_
|
| | | >%24(Qt_INCLUDEPATH_)%3B@(QtIncludePath->Distinct(),'%3B')</Qt_INCLUDEPATH_>
|
| | | <QtBkup_QtInstall
|
| | | >@(QtInstall,'%3B')</QtBkup_QtInstall>
|
| | | <QtBkup_QtModules
|
| | | >@(QtModules,'%3B')</QtBkup_QtModules>
|
| | | <QtBkup_QtPathBinaries
|
| | | >@(QtPathBinaries,'%3B')</QtBkup_QtPathBinaries>
|
| | | <QtBkup_QtPathLibraryExecutables
|
| | | >@(QtPathLibraryExecutables,'%3B')</QtBkup_QtPathLibraryExecutables>
|
| | | <QtBkup_QtHeaderSearchPath
|
| | | >@(QtHeaderSearchPath,'%3B')</QtBkup_QtHeaderSearchPath>
|
| | | <QtBkup_QtLibrarySearchPath
|
| | | >@(QtLibrarySearchPath,'%3B')</QtBkup_QtLibrarySearchPath>
|
| | | <QtBkup_QtVars
|
| | | >@(QtVariables,'%3B')</QtBkup_QtVars>
|
| | | <QtBkup_QMakeCodeLines
|
| | | >@(QMakeCodeLines,'%3B')</QtBkup_QMakeCodeLines>
|
| | | <QtBkup_QtBuildConfig
|
| | | >@(QtBuildConfig,'%3B')</QtBkup_QtBuildConfig>
|
| | | <QtVersion>$(QtVersion)</QtVersion>
|
| | | <QtVersionMajor>$(QtVersionMajor)</QtVersionMajor>
|
| | | <QtVersionMinor>$(QtVersionMinor)</QtVersionMinor>
|
| | | <QtVersionPatch>$(QtVersionPatch)</QtVersionPatch>
|
| | | </PropertyGroup>
|
| | | </Project>
|
| | | ]]>
|
| | | </QtVarsDataFileText>
|
| | | <!--
|
| | | ##
|
| | | ######## END generated XML (.props) ################################################################
|
| | | -->
|
| | | </PropertyGroup>
|
| | | <WriteLinesToFile File="$(QtVarsWorkPath)" Lines="$(QtVarsDataFileText)"/>
|
| | |
|
| | | <!--// Create $(QtVarsOutputDir) -->
|
| | | <MakeDir Directories="$(QtVarsOutputDir)"/>
|
| | |
|
| | | <!--// Copy generated .props to $(QtVarsOutputDir) -->
|
| | | <Delete
|
| | | Condition="'$(ErrorLevel)' == '0'"
|
| | | Files="$(QtVarsFilePath)"/>
|
| | | <Copy
|
| | | Condition="'$(ErrorLevel)' == '0'"
|
| | | SourceFiles="$(QtVarsWorkPath)" DestinationFiles="$(QtVarsFilePath)"/>
|
| | |
|
| | | <!--// Copy generated qtvars_plugin_import.cpp to $(QtVarsOutputDir) -->
|
| | | <Delete
|
| | | Condition="'$(ErrorLevel)' == '0'"
|
| | | Files="$(QtVarsOutputDir)\qtvars_plugin_import.cpp"/>
|
| | | <Copy
|
| | | Condition="'$(ErrorLevel)' == '0' AND Exists('$(QtVarsWorkDir)\qtvars_plugin_import.cpp')"
|
| | | SourceFiles="$(QtVarsWorkDir)\qtvars_plugin_import.cpp"
|
| | | DestinationFiles="$(QtVarsOutputDir)\qtvars_plugin_import.cpp"/>
|
| | |
|
| | | <!--// In design-time, copy generated .props to randomly named file -->
|
| | | <PropertyGroup>
|
| | | <QtVarsDesignTimeNew
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
|
| | | >$([System.IO.Path]::Combine('$(TEMP)','$([System.IO.Path]::GetRandomFileName()).designtime.props'))
|
| | | </QtVarsDesignTimeNew>
|
| | | </PropertyGroup>
|
| | | <Copy
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
|
| | | SourceFiles="$(QtVarsFilePath)" DestinationFiles="$(QtVarsDesignTimeNew)"/>
|
| | | <WriteLinesToFile
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
|
| | | File="$(QtVarsIndexPathDesignTime)" Overwrite="true" Lines="$(QtVarsDesignTimeNew)"/>
|
| | |
|
| | | <!--// Clean-up -->
|
| | | <ItemGroup>
|
| | | <QtModuleList Remove="@(QtModuleList)"/>
|
| | | <QMakeCodeLine Remove="@(QMakeCodeLine)"/>
|
| | | <QtIncludes Remove="@(QtIncludes)"/>
|
| | | <QtLibs Remove="@(QtLibs)"/>
|
| | | <QMakeError Remove="@(QMakeError)"/>
|
| | | <QtInstall Remove="@(QtInstall)"/>
|
| | | <QtModules Remove="@(QtModules)"/>
|
| | | <QtPathBinaries Remove="@(QtPathBinaries)"/>
|
| | | <QtPathLibraryExecutables Remove="@(QtPathLibraryExecutables)"/>
|
| | | <QtHeaderSearchPath Remove="@(QtHeaderSearchPath)"/>
|
| | | <QtLibrarySearchPath Remove="@(QtLibrarySearchPath)"/>
|
| | | <QtVariables Remove="@(QtVariables)"/>
|
| | | <QMakeCodeLines Remove="@(QMakeCodeLines)"/>
|
| | | <QtBuildConfig Remove="@(QtBuildConfig)"/>
|
| | | <QMake_Makefile_VarDef Remove="@(QMake_Makefile_VarDef)"/>
|
| | | <QMake_MSBuild_VarDef Remove="@(QMake_MSBuild_VarDef)"/>
|
| | | <QtVar Remove="@(QtVar)"/>
|
| | | </ItemGroup>
|
| | | <PropertyGroup>
|
| | | <QtIncludes/>
|
| | | <QtLibs/>
|
| | | <QtVarsProFileConfig/>
|
| | | <QtVarsProFileInput/>
|
| | | <QtVarsDataFileText/>
|
| | | <Cmd/>
|
| | | <QtMakefileVars/>
|
| | | </PropertyGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtVarsPrepare
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Force QtVars target to run when Qt settings have changed
|
| | | // -->
|
| | | <Target Name="QtVarsPrepare" BeforeTargets="QtVars" Condition="Exists('$(QtVarsFilePath)')">
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtInstall)' != '$(QtInstall)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtModules)' != '$(QtModules)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtPathBinaries)' != '$(QtPathBinaries)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtPathLibraryExecutables)' != '$(QtPathLibraryExecutables)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtHeaderSearchPath)' != '$(QtHeaderSearchPath)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtLibrarySearchPath)' != '$(QtLibrarySearchPath)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtVars)' != '$(QtVars)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QMakeCodeLines)' != '$(QMakeCodeLines)'" />
|
| | | <Delete Files="$(QtVarsFilePath)" Condition="Exists('$(QtVarsFilePath)')
|
| | | AND '$(QtBkup_QtBuildConfig)' != '$(QtBuildConfig)'" />
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtVarsClean
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Delete all files generated by the QtVars target
|
| | | // -->
|
| | | <Target Name="QtVarsClean">
|
| | | <RemoveDir Directories="$(QtVarsOutputDir)"/>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtVarsDesignTime
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Force QtVars target to run (called when project properties change)
|
| | | // -->
|
| | | <Target Name="QtVarsDesignTime">
|
| | | <CallTarget Targets="QtVarsClean"/>
|
| | | <CallTarget Targets="QtVars"/>
|
| | | </Target>
|
| | |
|
| | | </Project>
|
QtMSBuild/QtMsBuild/rcc/qt_import.props
QtMSBuild/QtMsBuild/rcc/qtrcc.props
QtMSBuild/QtMsBuild/rcc/qtrcc.targets
QtMSBuild/QtMsBuild/rcc/qtrcc.xml
QtMSBuild/QtMsBuild/rcc/qtrcc_cl.targets_TT
QtMSBuild/QtMsBuild/rcc/qtrcc_v3.xml_TT
QtMSBuild/QtMsBuild/repc/qt_import.props
QtMSBuild/QtMsBuild/repc/qtrepc.props
QtMSBuild/QtMsBuild/repc/qtrepc.targets
QtMSBuild/QtMsBuild/repc/qtrepc.xml
QtMSBuild/QtMsBuild/repc/qtrepc_cl.targets_TT
QtMSBuild/QtMsBuild/repc/qtrepc_v3.xml_TT
QtMSBuild/QtMsBuild/translation/qt_import.props
QtMSBuild/QtMsBuild/translation/qttranslation.props
QtMSBuild/QtMsBuild/translation/qttranslation.targets
QtMSBuild/QtMsBuild/translation/qttranslation.xml
QtMSBuild/QtMsBuild/uic/qt_import.props
QtMSBuild/QtMsBuild/uic/qtuic.props
QtMSBuild/QtMsBuild/uic/qtuic.targets
QtMSBuild/QtMsBuild/uic/qtuic.xml
QtMSBuild/QtMsBuild/uic/qtuic_v3.xml
QtMSBuild/Tasks/CriticalSection.cs
QtMSBuild/Tasks/DumpItems.cs
QtMSBuild/Tasks/Expand.cs
QtMSBuild/Tasks/Flatten.cs
QtMSBuild/Tasks/GetItemHash.cs
QtMSBuild/Tasks/GetVarsFromMSBuild.cs
QtMSBuild/Tasks/GetVarsFromMakefile.cs
QtMSBuild/Tasks/HostExec_LinuxSSL.cs
QtMSBuild/Tasks/HostExec_LinuxWSL.cs
QtMSBuild/Tasks/HostExec_LinuxWSL_Error.cs
QtMSBuild/Tasks/HostExec_Windows.cs
QtMSBuild/Tasks/HostTranslatePaths_LinuxSSL.cs
QtMSBuild/Tasks/HostTranslatePaths_LinuxWSL.cs
QtMSBuild/Tasks/HostTranslatePaths_LinuxWSL_Error.cs
QtMSBuild/Tasks/HostTranslatePaths_Windows.cs
QtMSBuild/Tasks/Join.cs
QtMSBuild/Tasks/ListQrc.cs
QtMSBuild/Tasks/ParseVarDefs.cs
QtMSBuild/Tasks/QtRunWork.cs
QtTmLanguage/qt/LICENSE
QtTmLanguage/qt/pri.pro.tmLanguage
QtVsTest/Macro.cs
QtVsTest/MacroClient.h
QtVsTest/MacroParser.cs
QtVsTest/MacroServer.cs
QtVsTest/Properties/AssemblyInfo.cs
QtVsTest/QtVsTest.cs
QtVsTest/QtVsTest.csproj
QtVsTest/Resources/QtVsTest.ico
QtVsTest/csmacro.tmLanguage_TT
QtVsTest/csmacro.tmTheme_TT
QtVsTest/source.extension.vsixmanifest_TT
QtVsTools.Core/BuildConfig.cs
QtVsTools.Core/CommandLineParser.cs
QtVsTools.Core/Common/EnumExt.cs
QtVsTools.Core/CompilerToolWrapper.cs
QtVsTools.Core/CxxStreamReader.cs
QtVsTools.Core/ExportProjectDialog.cs
QtVsTools.Core/ExportProjectDialog.resx
QtVsTools.Core/Extensions.cs
QtVsTools.Core/FakeFilter.cs
QtVsTools.Core/FilesToList.cs
QtVsTools.Core/Filters.cs
QtVsTools.Core/HelperFunctions.cs
QtVsTools.Core/ImageButton.cs
QtVsTools.Core/LinkerToolWrapper.cs
QtVsTools.Core/MainWinWrapper.cs
QtVsTools.Core/Messages.cs
QtVsTools.Core/MocCmdChecker.cs
QtVsTools.Core/MsBuildProject.cs
QtVsTools.Core/Observable.cs
QtVsTools.Core/ProFileContent.cs
QtVsTools.Core/ProFileOption.cs
QtVsTools.Core/ProSolution.cs
QtVsTools.Core/ProjectExporter.cs
QtVsTools.Core/ProjectImporter.cs
QtVsTools.Core/ProjectMacros.cs
QtVsTools.Core/Properties/AssemblyInfo.cs
QtVsTools.Core/QMake.cs
QtVsTools.Core/QMakeConf.cs
QtVsTools.Core/QMakeQuery.cs
QtVsTools.Core/QrcItem.cs
QtVsTools.Core/QrcParser.cs
QtVsTools.Core/QrcPrefix.cs
QtVsTools.Core/QtConfig.cs
QtVsTools.Core/QtModule.cs
QtVsTools.Core/QtModules.cs
QtVsTools.Core/QtMsBuild.cs
QtVsTools.Core/QtProject.cs
QtVsTools.Core/QtVSException.cs
QtVsTools.Core/QtVSIPSettings.cs
QtVsTools.Core/QtVersionManager.cs
QtVsTools.Core/QtVsTools.Core.csproj
QtVsTools.Core/QtVsTools.Core.ico
QtVsTools.Core/RccOptions.cs
QtVsTools.Core/Resources.cs
QtVsTools.Core/Resources.resx
QtVsTools.Core/Resources/delete.png
QtVsTools.Core/Resources/delete_d.png
QtVsTools.Core/Resources/newitem.png
QtVsTools.Core/Resources/newitem_d.png
QtVsTools.Core/SR.cs
QtVsTools.Core/TemplateType.cs
QtVsTools.Core/VersionInformation.cs
QtVsTools.Core/VisualStudio/IProjectTracker.cs
QtVsTools.Core/VisualStudio/VsServiceProvider.cs
QtVsTools.Core/WaitDialog.cs
QtVsTools.Package/Common/Concurrent.cs
QtVsTools.Package/Common/ConcurrentStopwatch.cs
QtVsTools.Package/Common/Disposable.cs
QtVsTools.Package/Common/Json/DeferredObject.cs
QtVsTools.Package/Common/Json/Serializable.cs
QtVsTools.Package/Common/Json/SerializableEnum.cs
QtVsTools.Package/Common/Json/Serializer.cs
QtVsTools.Package/Common/NativeAPI.cs
QtVsTools.Package/Common/PriorityQueue.cs
QtVsTools.Package/Common/Prototyped.cs
QtVsTools.Package/Common/PunisherQueue.cs
QtVsTools.Package/Common/Timestamp.cs
QtVsTools.Package/Common/VsToolsDialogWindow.cs
QtVsTools.Package/Editors/Editor.QtDesigner.cs
QtVsTools.Package/Editors/Editor.QtLinguist.cs
QtVsTools.Package/Editors/Editor.QtResourceEditor.cs
QtVsTools.Package/Editors/Editor.cs
QtVsTools.Package/Language/LICENSE.APACHE
QtVsTools.Package/Language/qml.qmlproject.tmLanguage
QtVsTools.Package/Marketplace/Overview.html_TT
QtVsTools.Package/Options/QtLegacyOptionsPage.cs
QtVsTools.Package/Options/QtOptionsPage.cs
QtVsTools.Package/Options/QtVersionsPage.cs
QtVsTools.Package/Options/QtVersionsTable.cs
QtVsTools.Package/Options/QtVersionsTable.xaml
QtVsTools.Package/Package/AddTranslationDialog.cs
QtVsTools.Package/Package/AddTranslationDialog.resx
QtVsTools.Package/Package/ChangeFor.cs
QtVsTools.Package/Package/DteEventsHandler.cs
QtVsTools.Package/Package/ExtLoader.cs
QtVsTools.Package/Package/FormChangeQtVersion.Designer.cs
QtVsTools.Package/Package/FormChangeQtVersion.cs
QtVsTools.Package/Package/FormChangeQtVersion.resx
QtVsTools.Package/Package/FormProjectQtSettings.Designer.cs
QtVsTools.Package/Package/FormProjectQtSettings.cs
QtVsTools.Package/Package/FormProjectQtSettings.resx
QtVsTools.Package/Package/ProjectQtSettings.cs
QtVsTools.Package/Package/QMakeWrapper.cs
QtVsTools.Package/Package/QtHelp.cs
QtVsTools.Package/Package/QtHelpLinkChooser.xaml
QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
QtVsTools.Package/Package/QtItemContextMenu.cs
QtVsTools.Package/Package/QtMainMenu.cs
QtVsTools.Package/Package/QtMsBuildConverter.cs
QtVsTools.Package/Package/QtProjectContextMenu.cs
QtVsTools.Package/Package/QtSolutionContextMenu.cs
QtVsTools.Package/Package/SR.cs
QtVsTools.Package/Package/Translation.cs
QtVsTools.Package/Package/TranslationItem.cs
QtVsTools.Package/Package/Version.cs
QtVsTools.Package/Properties/AssemblyInfo.cs
QtVsTools.Package/QML/Classification/QmlAsyncClassifier.cs
QtVsTools.Package/QML/Classification/QmlClassificationFormat.cs
QtVsTools.Package/QML/Classification/QmlErrorClassifier.cs
QtVsTools.Package/QML/Classification/QmlExpressionEvalClassifier.cs
QtVsTools.Package/QML/Classification/QmlSyntaxClassifier.cs
QtVsTools.Package/QML/Classification/QmlTag.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7BoilerPlate.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Breakpoint.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7CodeContext.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Engine.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Enums.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Events.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Expression.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7InfoHelpers.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Program.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Property.cs
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7StackFrame.cs
QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs
QtVsTools.Package/QML/Debugging/QmlDebugger.cs
QtVsTools.Package/QML/Debugging/QmlFileSystem.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Backtrace.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Break.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4ClearBreakpoint.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Connect.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Continue.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Disconnect.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Evaluate.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Exception.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Frame.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsObject.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsValue.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Lookup.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Message.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Scope.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4SetBreakpoint.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4SetExceptionBreak.cs
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Version.cs
QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Client.cs
QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Protocol.cs
QtVsTools.Package/QML/Parser/QmlParserDiagnostics.cs
QtVsTools.Package/QML/Parser/QmlParserInterop.cs
QtVsTools.Package/QML/Syntax/QmlAst.cs
QtVsTools.Package/QML/Syntax/QmlSyntax.cs
QtVsTools.Package/QtMenus.vsct_TT
QtVsTools.Package/QtMsBuild/QtModulesEditor.cs
QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml
QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml.cs
QtVsTools.Package/QtMsBuild/QtProjectBuild.cs
QtVsTools.Package/QtMsBuild/QtProjectIntelliSense.cs
QtVsTools.Package/QtMsBuild/QtProjectLogger.cs
QtVsTools.Package/QtMsBuild/QtProjectTracker.cs
QtVsTools.Package/QtMsBuild/QtVersionProvider.cs
QtVsTools.Package/QtVsTools.Package.csproj
QtVsTools.Package/QtVsTools.Qml.Debug.pkgdef
QtVsTools.Package/QtVsTools.ico
QtVsTools.Package/QtVsToolsPackage.cs
QtVsTools.Package/Resources.resx
QtVsTools.Package/Resources/menuimages.png
QtVsTools.Package/Resources/qt.ico
QtVsTools.Package/VSPackage.resx
QtVsTools.Package/VisualStudio/VsShell.cs
QtVsTools.Package/preview.png
QtVsTools.Package/qt.ico
QtVsTools.Package/qt5.natvis.xml
QtVsTools.Package/qt6.natvis.xml
QtVsTools.Package/qtmodules.xml
QtVsTools.Package/source.extension.vsixmanifest_TT
QtVsTools.RegExpr/Properties/AssemblyInfo.cs
QtVsTools.RegExpr/QtVsTools.RegExpr.csproj
QtVsTools.RegExpr/README
QtVsTools.RegExpr/expression/CharClassLiteral.cs
QtVsTools.RegExpr/expression/CharClassRange.cs
QtVsTools.RegExpr/expression/CharClassSet.cs
QtVsTools.RegExpr/expression/RegExpr.cs
QtVsTools.RegExpr/expression/RegExprAssert.cs
QtVsTools.RegExpr/expression/RegExprChoice.cs
QtVsTools.RegExpr/expression/RegExprLiteral.cs
QtVsTools.RegExpr/expression/RegExprRepeat.cs
QtVsTools.RegExpr/expression/RegExprSequence.cs
QtVsTools.RegExpr/expression/RegExprToken.cs
QtVsTools.RegExpr/expression/Renderer.cs
QtVsTools.RegExpr/parser/ParseTree.cs
QtVsTools.RegExpr/parser/Parser.cs
QtVsTools.RegExpr/production/Production.cs
QtVsTools.RegExpr/production/ProductionRule.cs
QtVsTools.RegExpr/production/ProductionRuleAction.cs
QtVsTools.RegExpr/utils/Consts.cs
QtVsTools.RegExpr/utils/Utils.cs
QtVsTools.Wizards/Properties/AssemblyInfo.cs
QtVsTools.Wizards/QtVsTools.Wizards.csproj
QtVsTools.Wizards/Resources/ExpanderStyle.xaml
QtVsTools.Wizards/Resources/Qt-logo-small.png
QtVsTools.Wizards/Resources/QtProjectWizard.ico
QtVsTools.Wizards/Resources/medium.png
QtVsTools.Wizards/Resources/small.png
QtVsTools.Wizards/Wizards/ClassWizard/AddClassPage.xaml
QtVsTools.Wizards/Wizards/ClassWizard/AddClassPage.xaml.cs
QtVsTools.Wizards/Wizards/ClassWizard/AddClassWizard.cs
QtVsTools.Wizards/Wizards/ClassWizard/Class.cs
QtVsTools.Wizards/Wizards/ClassWizard/ClassKind.cs
QtVsTools.Wizards/Wizards/ClassWizard/Core/CoreClassPage.xaml
QtVsTools.Wizards/Wizards/ClassWizard/Core/CoreClassPage.xaml.cs
QtVsTools.Wizards/Wizards/ClassWizard/Core/CoreClassWizard.cs
QtVsTools.Wizards/Wizards/ClassWizard/Gui/GuiClassPage.xaml
QtVsTools.Wizards/Wizards/ClassWizard/Gui/GuiClassPage.xaml.cs
QtVsTools.Wizards/Wizards/ClassWizard/Gui/GuiClassWizard.cs
QtVsTools.Wizards/Wizards/ClassWizard/IClassWizard.cs
QtVsTools.Wizards/Wizards/ClassWizard/UiClassInclusion.cs
QtVsTools.Wizards/Wizards/ProjectWizard/ConfigPage.xaml
QtVsTools.Wizards/Wizards/ProjectWizard/ConfigPage.xaml.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Console/ConsoleWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Designer/DesignerPage.xaml
QtVsTools.Wizards/Wizards/ProjectWizard/Designer/DesignerPage.xaml.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Designer/DesignerWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Empty/EmptyWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Gui/GuiPage.xaml
QtVsTools.Wizards/Wizards/ProjectWizard/Gui/GuiPage.xaml.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Gui/GuiWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Library/LibraryClassPage.xaml
QtVsTools.Wizards/Wizards/ProjectWizard/Library/LibraryClassPage.xaml.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Library/LibraryWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/ProjectTemplateWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Quick/QuickWizard.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Server/ServerPage.xaml
QtVsTools.Wizards/Wizards/ProjectWizard/Server/ServerPage.xaml.cs
QtVsTools.Wizards/Wizards/ProjectWizard/Server/ServerWizard.cs
QtVsTools.Wizards/Wizards/Util/ClassNameValidationRule.cs
QtVsTools.Wizards/Wizards/Util/FileExistsInFilterValidationRule.cs
QtVsTools.Wizards/Wizards/Util/FileNameValidationRule.cs
QtVsTools.Wizards/Wizards/Util/NativeMethods.cs
QtVsTools.Wizards/Wizards/Util/SortComboBoxItem.cs
QtVsTools.Wizards/Wizards/Util/UnsafeNativeMethods.cs
QtVsTools.Wizards/Wizards/Util/VCLanguageManagerValidationRule.cs
QtVsTools.Wizards/Wizards/WizardData.cs
QtVsTools.Wizards/Wizards/WizardIntroPage.xaml
QtVsTools.Wizards/Wizards/WizardIntroPage.xaml.cs
QtVsTools.Wizards/Wizards/WizardPage.cs
QtVsTools.Wizards/Wizards/WizardResult.cs
QtVsTools.Wizards/Wizards/WizardWindow.xaml
QtVsTools.Wizards/Wizards/WizardWindow.xaml.cs
README.md
Templates/console/Properties/AssemblyInfo.cs
Templates/console/QtTemplate.Project.Console.csproj
Templates/console/console.ico
Templates/console/console.vcxproj
Templates/console/console.vcxproj.filters
Templates/console/console.vstemplate_TT
Templates/console/main.cpp
Templates/designer/Properties/AssemblyInfo.cs
Templates/designer/QtTemplate.Project.Designer.csproj
Templates/designer/designer.ico
Templates/designer/designer.vcxproj
Templates/designer/designer.vcxproj.filters
Templates/designer/designer.vstemplate_TT
Templates/designer/plugin.cpp
Templates/designer/plugin.h
Templates/designer/plugin.json
Templates/designer/stdafx.cpp
Templates/designer/stdafx.h
Templates/designer/widget.cpp
Templates/designer/widget.h
Templates/dialogbuttonbottom/Properties/AssemblyInfo.cs
Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj
Templates/dialogbuttonbottom/dialogbuttonbottom.ico
Templates/dialogbuttonbottom/dialogbuttonbottom.ui
Templates/dialogbuttonbottom/dialogbuttonbottom.vstemplate
Templates/dialogbuttonright/Properties/AssemblyInfo.cs
Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj
Templates/dialogbuttonright/dialogbuttonright.ico
Templates/dialogbuttonright/dialogbuttonright.ui
Templates/dialogbuttonright/dialogbuttonright.vstemplate
Templates/empty/Properties/AssemblyInfo.cs
Templates/empty/QtTemplate.Project.Empty.csproj
Templates/empty/empty.ico
Templates/empty/empty.vcxproj
Templates/empty/empty.vcxproj.filters
Templates/empty/empty.vstemplate_TT
Templates/gui/Properties/AssemblyInfo.cs
Templates/gui/QtTemplate.Project.Gui.csproj
Templates/gui/gui.ico
Templates/gui/gui.vcxproj
Templates/gui/gui.vcxproj.filters
Templates/gui/gui.vstemplate_TT
Templates/gui/main.cpp
Templates/gui/stdafx.cpp
Templates/gui/stdafx.h
Templates/gui/widget.cpp
Templates/gui/widget.h
Templates/gui/widget.ui
Templates/lib/Properties/AssemblyInfo.cs
Templates/lib/QtTemplate.Project.Lib.csproj
Templates/lib/global.h
Templates/lib/header.h
Templates/lib/lib.ico
Templates/lib/lib.vcxproj
Templates/lib/lib.vcxproj.filters
Templates/lib/lib.vstemplate_TT
Templates/lib/source.cpp
Templates/lib/stdafx.cpp
Templates/lib/stdafx.h
Templates/mainwindow/Properties/AssemblyInfo.cs
Templates/mainwindow/QtTemplate.Item.MainWindow.csproj
Templates/mainwindow/mainwindow.ico
Templates/mainwindow/mainwindow.ui
Templates/mainwindow/mainwindow.vstemplate
Templates/qml/NewFile.qml
Templates/qml/Properties/AssemblyInfo.cs
Templates/qml/QtTemplate.Item.QMLFile.csproj
Templates/qml/qml.ico
Templates/qml/qml.vstemplate
Templates/qmldir/Properties/AssemblyInfo.cs
Templates/qmldir/QtTemplate.Item.QMLDir.csproj
Templates/qmldir/qml.ico
Templates/qmldir/qmldir
Templates/qmldir/qmldir.vstemplate
Templates/quick/Properties/AssemblyInfo.cs
Templates/quick/QtTemplate.Project.Quick.csproj
Templates/quick/main.cpp
Templates/quick/main.qml
Templates/quick/qml.qrc
Templates/quick/quick.ico
Templates/quick/quick.vcxproj
Templates/quick/quick.vcxproj.filters
Templates/quick/quick.vstemplate_TT
Templates/resource/Properties/AssemblyInfo.cs
Templates/resource/QtTemplate.Item.Resource.csproj
Templates/resource/resource.ico
Templates/resource/resource.qrc
Templates/resource/resource.vstemplate
Templates/server/Properties/AssemblyInfo.cs
Templates/server/QtTemplate.Project.Server.csproj
Templates/server/header.h
Templates/server/server.def
Templates/server/server.ico
Templates/server/server.rc
Templates/server/server.vcxproj
Templates/server/server.vcxproj.filters
Templates/server/server.vstemplate_TT
Templates/server/source.cpp
Templates/server/stdafx.cpp
Templates/server/stdafx.h
Templates/server/widget.ui
Templates/widget/Properties/AssemblyInfo.cs
Templates/widget/QtTemplate.Item.Widget.csproj
Templates/widget/widget.ico
Templates/widget/widget.ui
Templates/widget/widget.vstemplate
Tests/BigSolution/generator/App.config
Tests/BigSolution/generator/Program.cs
Tests/BigSolution/generator/Properties/AssemblyInfo.cs
Tests/BigSolution/generator/generator.csproj
Tests/BigSolution/generator/generator.sln
Tests/BigSolution/template/BigProjectNNN/BigClassNNN.cpp
Tests/BigSolution/template/BigProjectNNN/BigClassNNN.h
Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.qrc
Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.ui
Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj
Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj.filters
Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.cpp
Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h
Tests/BigSolution/template/BigProjectNNN/bigprojectnnn_global.h
Tests/BigSolution/template/BigSolution.sln
Tests/SampleTest/Macros.qrc
Tests/SampleTest/SampleTest.pro
Tests/SampleTest/SampleTest.sln
Tests/SampleTest/SampleTest.vcxproj
Tests/SampleTest/SampleTest.vcxproj.filters
Tests/SampleTest/Test_CreateGuiApp.csmacro
Tests/SampleTest/Test_DebugGuiApp.csmacro
Tests/SampleTest/Test_ImportProFile.csmacro
Tests/SampleTest/Test_QtVsToolsLoaded.csmacro
Tests/SampleTest/Test_RebuildSolution.csmacro
Tests/SampleTest/main.cpp
Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs
Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs
Tests/Test_QtMsBuild.Tasks/Test_Join.cs
Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj
Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs
Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj
Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs
Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs
Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj
Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs
Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs
Tests/concurrency/Solution1/MyPropertySheet.props
Tests/concurrency/Solution1/QtClassLibrary1/QtClass.cpp
Tests/concurrency/Solution1/QtClassLibrary1/QtClass.h
Tests/concurrency/Solution1/QtClassLibrary1/QtClassLibrary1.cpp
Tests/concurrency/Solution1/QtClassLibrary1/QtClassLibrary1.h
Tests/concurrency/Solution1/QtClassLibrary1/QtClassLibrary1.vcxproj
Tests/concurrency/Solution1/QtClassLibrary1/QtClassLibrary1.vcxproj.filters
Tests/concurrency/Solution1/QtClassLibrary1/qtclasslibrary1_global.h
Tests/concurrency/Solution1/QtWidgetsApplication1/QtWidgetsApplication1.cpp
Tests/concurrency/Solution1/QtWidgetsApplication1/QtWidgetsApplication1.h
Tests/concurrency/Solution1/QtWidgetsApplication1/QtWidgetsApplication1.qrc
Tests/concurrency/Solution1/QtWidgetsApplication1/QtWidgetsApplication1.ui
Tests/concurrency/Solution1/QtWidgetsApplication1/QtWidgetsApplication1.vcxproj
Tests/concurrency/Solution1/QtWidgetsApplication1/QtWidgetsApplication1.vcxproj.filters
Tests/concurrency/Solution1/QtWidgetsApplication1/main.cpp
Tests/concurrency/Solution1/QtWidgetsApplication2/QtWidgetsApplication2.cpp
Tests/concurrency/Solution1/QtWidgetsApplication2/QtWidgetsApplication2.h
Tests/concurrency/Solution1/QtWidgetsApplication2/QtWidgetsApplication2.qrc
Tests/concurrency/Solution1/QtWidgetsApplication2/QtWidgetsApplication2.ui
Tests/concurrency/Solution1/QtWidgetsApplication2/QtWidgetsApplication2.vcxproj
Tests/concurrency/Solution1/QtWidgetsApplication2/QtWidgetsApplication2.vcxproj.filters
Tests/concurrency/Solution1/QtWidgetsApplication2/main.cpp
Tests/concurrency/Solution1/Solution1.sln
Tests/concurrency/Solution1/StaticLib1/Header.h
Tests/concurrency/Solution1/StaticLib1/StaticLib1.cpp
Tests/concurrency/Solution1/StaticLib1/StaticLib1.vcxproj
Tests/concurrency/Solution1/StaticLib1/StaticLib1.vcxproj.filters
Tests/concurrency/loop_msbuild.bat
VsQml/README
VsQml/astvisitor.cpp
VsQml/astvisitor.h
VsQml/vsqml.cpp
VsQml/vsqml.h
VsQml/vsqml.vcxproj
VsQml/vsqml.vcxproj.filters
VsQml/vsqml_global.h
VsQml/vsqmldebugclient.cpp
VsQml/vsqmldebugclient.h
common.tt
doc/config/macros.qdocconf
doc/config/qtvstools-project.qdocconf
doc/config/style/qt5-sidebar.html
doc/doc.pri
doc/images/qtvstools-addressbook-adddialog.png
doc/images/qtvstools-addressbook-mainwindow.png
doc/images/qtvstools-export-project.png
doc/images/qtvstools-minus.png
doc/images/qtvstools-plus.png
doc/images/qtvstools-qrc-editor.png
doc/images/qtvstools-qt-project-settings.png
doc/images/qtvstools-qt-versions.png
doc/images/qtvstools-qt-widget-class-wizard.png
doc/images/qtvstools-widgets-app-class.png
doc/images/qtvstools-widgets-app-modules.png
doc/qtvstools-online.qdocconf
doc/qtvstools.qdocconf
doc/src/externallinks.qdoc
doc/src/qtvstools.qdoc
doc/tutorial/AddressBook/AddressBook.ico
doc/tutorial/AddressBook/AddressBook.pro
doc/tutorial/AddressBook/AddressBook.rc
doc/tutorial/AddressBook/adddialog.cpp
doc/tutorial/AddressBook/adddialog.h
doc/tutorial/AddressBook/adddialog.ui
doc/tutorial/AddressBook/addressbook.cpp
doc/tutorial/AddressBook/addressbook.h
doc/tutorial/AddressBook/addressbook.ui
doc/tutorial/AddressBook/main.cpp
references.props
transform.targets
version.targets
version.tt
vstools.bat
vstools.pri_TT
vstools.pro
vstools.sln |