as.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright (c) 2015-2016 The Khronos Group Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <cassert>
  15. #include <cstdio>
  16. #include <cstring>
  17. #include <vector>
  18. #include "source/spirv_target_env.h"
  19. #include "spirv-tools/libspirv.h"
  20. #include "tools/io.h"
  21. #include "tools/util/flags.h"
  22. constexpr auto kDefaultTarget = SPV_ENV_UNIVERSAL_1_6;
  23. static const std::string kHelpText =
  24. R"(%s - Create a SPIR-V binary module from SPIR-V assembly text
  25. Usage: %s [options] [<filename>]
  26. The SPIR-V assembly text is read from <filename>. If no file is specified,
  27. or if the filename is "-", then the assembly text is read from standard input.
  28. The SPIR-V binary module is written to file "out.spv", unless the -o option
  29. is used.
  30. Options:
  31. -h, --help Print this help.
  32. -o <filename> Set the output filename. Use '-' to mean stdout.
  33. --version Display assembler version information.
  34. --preserve-numeric-ids
  35. Numeric IDs in the binary will have the same values as in the
  36. source. Non-numeric IDs are allocated by filling in the gaps,
  37. starting with 1 and going up.
  38. --target-env %s
  39. Use specified environment.
  40. )";
  41. // clang-format off
  42. // flag name= default_value= required=
  43. FLAG_SHORT_bool( h, false, false);
  44. FLAG_LONG_bool( help, false, false);
  45. FLAG_LONG_bool( version, false, false);
  46. FLAG_LONG_bool( preserve_numeric_ids, false, false);
  47. FLAG_SHORT_string(o, "", false);
  48. FLAG_LONG_string( target_env, "", false);
  49. // clang-format on
  50. int main(int, const char** argv) {
  51. if (!flags::Parse(argv)) {
  52. return 1;
  53. }
  54. if (flags::h.value() || flags::help.value()) {
  55. const std::string target_env_list = spvTargetEnvList(19, 80);
  56. printf(kHelpText.c_str(), argv[0], argv[0], target_env_list.c_str());
  57. return 0;
  58. }
  59. if (flags::version.value()) {
  60. printf("%s\n", spvSoftwareVersionDetailsString());
  61. printf("Target: %s\n", spvTargetEnvDescription(kDefaultTarget));
  62. return 0;
  63. }
  64. std::string outFile = flags::o.value();
  65. if (outFile.empty()) {
  66. outFile = "out.spv";
  67. }
  68. uint32_t options = 0;
  69. if (flags::preserve_numeric_ids.value()) {
  70. options |= SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS;
  71. }
  72. if (flags::positional_arguments.size() != 1) {
  73. fprintf(stderr, "error: exactly one input file must be specified.\n");
  74. return 1;
  75. }
  76. std::string inFile = flags::positional_arguments[0];
  77. std::vector<char> contents;
  78. if (!ReadTextFile(inFile.c_str(), &contents)) return 1;
  79. // Can only deduce target after the file has been read
  80. spv_target_env target_env;
  81. if (flags::target_env.value().empty()) {
  82. if (!spvReadEnvironmentFromText(contents, &target_env)) {
  83. // Revert to default version since deduction failed
  84. target_env = kDefaultTarget;
  85. }
  86. } else if (!spvParseTargetEnv(flags::target_env.value().c_str(),
  87. &target_env)) {
  88. fprintf(stderr, "error: Unrecognized target env: %s\n",
  89. flags::target_env.value().c_str());
  90. return 1;
  91. }
  92. spv_binary binary;
  93. spv_diagnostic diagnostic = nullptr;
  94. spv_context context = spvContextCreate(target_env);
  95. spv_result_t error = spvTextToBinaryWithOptions(
  96. context, contents.data(), contents.size(), options, &binary, &diagnostic);
  97. spvContextDestroy(context);
  98. if (error) {
  99. spvDiagnosticPrint(diagnostic);
  100. spvDiagnosticDestroy(diagnostic);
  101. return error;
  102. }
  103. if (!WriteFile<uint32_t>(outFile.c_str(), "wb", binary->code,
  104. binary->wordCount)) {
  105. spvBinaryDestroy(binary);
  106. return 1;
  107. }
  108. spvBinaryDestroy(binary);
  109. return 0;
  110. }