mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2025-01-12 09:20:15 +00:00
Linker usability improvements (#4084)
* tools/linker: Error out on unrecognized options Fixes #4083. * tools/linker: Use early returns when parsing options This was already the case for some linker options, and other tools were doing so for all of their options. * tools/linker: Rework the usage output * The new formatting for long options taking a value makes it explicit that there is no equal sign between the option name and the value. * The options are sorted by lexicographical order. * Change the option formatting from 90 columns to 80, to match the other tools. * tools/linker: Change the default environment to spv1.5 * tools/linker: Change the default output to spv.out Instead of writing to the standard output when the "-o" option is not specified, the resulting linked SPIR-V binary will be written to "spv.out". One can still have the output sent to the standard output by specifying "-o -". * tools/linker: Update the reported target for --version Running `spirv-link --version` will now report the currently selected environment. * tools/linker: Sort header includes * linker: Improve module-related error messages * Use 1-based indexing of modules; * Say which module could not be built; * Use the correct total number of input modules in the error message when one fails to build.
This commit is contained in:
parent
7bbe1a3164
commit
b1507d0d2b
@ -676,14 +676,15 @@ spv_result_t Link(const Context& context, const uint32_t* const* binaries,
|
||||
if (schema != 0u) {
|
||||
position.index = 4u;
|
||||
return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
|
||||
<< "Schema is non-zero for module " << i << ".";
|
||||
<< "Schema is non-zero for module " << i + 1 << ".";
|
||||
}
|
||||
|
||||
std::unique_ptr<IRContext> ir_context = BuildModule(
|
||||
c_context->target_env, consumer, binaries[i], binary_sizes[i]);
|
||||
if (ir_context == nullptr)
|
||||
return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
|
||||
<< "Failed to build a module out of " << ir_contexts.size() << ".";
|
||||
<< "Failed to build module " << i + 1 << " out of " << num_binaries
|
||||
<< ".";
|
||||
modules.push_back(ir_context->module());
|
||||
ir_contexts.push_back(std::move(ir_context));
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "spirv-tools/linker.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
@ -19,42 +21,56 @@
|
||||
#include "source/spirv_target_env.h"
|
||||
#include "source/table.h"
|
||||
#include "spirv-tools/libspirv.hpp"
|
||||
#include "spirv-tools/linker.hpp"
|
||||
#include "tools/io.h"
|
||||
|
||||
void print_usage(char* argv0) {
|
||||
std::string target_env_list = spvTargetEnvList(27, 95);
|
||||
namespace {
|
||||
|
||||
const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;
|
||||
|
||||
void print_usage(const char* program) {
|
||||
std::string target_env_list = spvTargetEnvList(16, 80);
|
||||
// NOTE: Please maintain flags in lexicographical order.
|
||||
printf(
|
||||
R"(%s - Link SPIR-V binary files together.
|
||||
|
||||
USAGE: %s [options] <filename> [<filename> ...]
|
||||
USAGE: %s [options] [-o <output>] <input>...
|
||||
|
||||
The SPIR-V binaries are read from the different <filename>.
|
||||
The SPIR-V binaries are read from the different <input>(s).
|
||||
The SPIR-V resulting linked binary module is written to the file "out.spv"
|
||||
unless the -o option is used; if <output> is "-", it is written to the standard
|
||||
output.
|
||||
|
||||
NOTE: The linker is a work in progress.
|
||||
|
||||
Options:
|
||||
-h, --help Print this help.
|
||||
-o Name of the resulting linked SPIR-V binary.
|
||||
--create-library Link the binaries into a library, keeping all exported symbols.
|
||||
--allow-partial-linkage Allow partial linkage by accepting imported symbols to be unresolved.
|
||||
--verify-ids Verify that IDs in the resulting modules are truly unique.
|
||||
--version Display linker version information
|
||||
--target-env {%s}
|
||||
Use validation rules from the specified environment.
|
||||
Options (in lexicographical order):
|
||||
--allow-partial-linkage
|
||||
Allow partial linkage by accepting imported symbols to be
|
||||
unresolved.
|
||||
--create-library
|
||||
Link the binaries into a library, keeping all exported symbols.
|
||||
-h, --help
|
||||
Print this help.
|
||||
--target-env <env>
|
||||
Set the target environment. Without this flag the target
|
||||
environment defaults to spv1.5. <env> must be one of
|
||||
{%s}
|
||||
--verify-ids
|
||||
Verify that IDs in the resulting modules are truly unique.
|
||||
--version
|
||||
Display linker version information
|
||||
)",
|
||||
argv0, argv0, target_env_list.c_str());
|
||||
program, program, target_env_list.c_str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::vector<const char*> inFiles;
|
||||
const char* outFile = nullptr;
|
||||
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_0;
|
||||
spv_target_env target_env = kDefaultEnvironment;
|
||||
spvtools::LinkerOptions options;
|
||||
bool continue_processing = true;
|
||||
int return_code = 0;
|
||||
|
||||
for (int argi = 1; continue_processing && argi < argc; ++argi) {
|
||||
for (int argi = 1; argi < argc; ++argi) {
|
||||
const char* cur_arg = argv[argi];
|
||||
if ('-' == cur_arg[0]) {
|
||||
if (0 == strcmp(cur_arg, "-o")) {
|
||||
@ -63,55 +79,48 @@ int main(int argc, char** argv) {
|
||||
outFile = argv[++argi];
|
||||
} else {
|
||||
fprintf(stderr, "error: More than one output file specified\n");
|
||||
continue_processing = false;
|
||||
return_code = 1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "error: Missing argument to %s\n", cur_arg);
|
||||
continue_processing = false;
|
||||
return_code = 1;
|
||||
return 1;
|
||||
}
|
||||
} else if (0 == strcmp(cur_arg, "--create-library")) {
|
||||
options.SetCreateLibrary(true);
|
||||
} else if (0 == strcmp(cur_arg, "--verify-ids")) {
|
||||
options.SetVerifyIds(true);
|
||||
} else if (0 == strcmp(cur_arg, "--allow-partial-linkage")) {
|
||||
options.SetAllowPartialLinkage(true);
|
||||
} else if (0 == strcmp(cur_arg, "--version")) {
|
||||
printf("%s\n", spvSoftwareVersionDetailsString());
|
||||
// TODO(dneto): Add OpenCL 2.2 at least.
|
||||
printf("Targets:\n %s\n %s\n %s\n",
|
||||
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_1),
|
||||
spvTargetEnvDescription(SPV_ENV_VULKAN_1_0),
|
||||
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_2));
|
||||
continue_processing = false;
|
||||
return_code = 0;
|
||||
} else if (0 == strcmp(cur_arg, "--create-library")) {
|
||||
options.SetCreateLibrary(true);
|
||||
} else if (0 == strcmp(cur_arg, "--help") || 0 == strcmp(cur_arg, "-h")) {
|
||||
print_usage(argv[0]);
|
||||
continue_processing = false;
|
||||
return_code = 0;
|
||||
return 0;
|
||||
} else if (0 == strcmp(cur_arg, "--target-env")) {
|
||||
if (argi + 1 < argc) {
|
||||
const auto env_str = argv[++argi];
|
||||
if (!spvParseTargetEnv(env_str, &target_env)) {
|
||||
fprintf(stderr, "error: Unrecognized target env: %s\n", env_str);
|
||||
continue_processing = false;
|
||||
return_code = 1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "error: Missing argument to --target-env\n");
|
||||
continue_processing = false;
|
||||
return_code = 1;
|
||||
return 1;
|
||||
}
|
||||
} else if (0 == strcmp(cur_arg, "--verify-ids")) {
|
||||
options.SetVerifyIds(true);
|
||||
} else if (0 == strcmp(cur_arg, "--version")) {
|
||||
printf("%s\n", spvSoftwareVersionDetailsString());
|
||||
printf("Target: %s\n", spvTargetEnvDescription(target_env));
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "error: Unrecognized option: %s\n\n", argv[argi]);
|
||||
print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
inFiles.push_back(cur_arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Exit if command line parsing was not successful.
|
||||
if (!continue_processing) {
|
||||
return return_code;
|
||||
if (!outFile) {
|
||||
outFile = "out.spv";
|
||||
}
|
||||
|
||||
if (inFiles.empty()) {
|
||||
|
Loading…
Reference in New Issue
Block a user