]> git.cworth.org Git - apitrace/blob - cli/cli_trace.cpp
Make file_exists as os::Path method.
[apitrace] / cli / cli_trace.cpp
1 /*********************************************************************
2  *
3  * Copyright 2011 Intel Corporation
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use, copy,
10  * modify, merge, publish, distribute, sublicense, and/or sell copies
11  * of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  *
26  *********************************************************************/
27
28 #include <iostream>
29
30 #include "cli.hpp"
31
32 #include "os_path.hpp"
33
34
35 static int verbose = 1;
36
37 static const char *synopsis = "Generate a new trace by executing the given program.";
38
39 static void
40 usage(void)
41 {
42     std::cout << "usage: apitrace trace <program> [<args> ...]\n"
43         << synopsis << "\n"
44         "\n"
45         "    The given program will be executed with the given arguments.\n"
46         "    During execution, all OpenGL calls will be captured to a trace\n"
47         "    file named <program>.trace. That trace file can then be used\n"
48         "    with other apitrace utilities for replay or analysis.\n";
49 }
50
51 /* We only support "apitrace trace" on POSIX-like systems (not WIN32) */
52 #ifndef _WIN32
53
54
55 #ifdef __APPLE__
56 #define CLI_TRACE_VARIABLE "DYLD_LIBRARY_PATH"
57 #define CLI_TRACE_WRAPPER  "OpenGL"
58 #else
59 #define CLI_TRACE_VARIABLE "LD_PRELOAD"
60 #define CLI_TRACE_WRAPPER  "glxtrace.so"
61 #endif
62
63 static os::Path
64 find_wrapper(const char *filename)
65 {
66     os::Path complete;
67
68     /* First look in the same directory from which this process is
69      * running, (to support developers running a compiled program that
70      * has not been installed. */
71 #if 1
72     os::Path process_dir = os::getProcessName();
73
74     process_dir.trimFilename();
75
76     complete = process_dir;
77     complete.join("wrappers");
78     complete.join(filename);
79 #else
80     complete = APITRACE_BINARY_DIR "/wrappers";
81     complete.join(filename);
82 #endif
83
84     if (complete.exists())
85         return complete;
86
87     /* Second, look in the directory for installed wrappers. */
88     complete = APITRACE_WRAPPER_INSTALL_DIR;
89     complete.join(filename);
90
91     if (complete.exists())
92         return complete;
93
94     std::cerr << "error: cannot find " << filename << " (looked in " <<
95         APITRACE_WRAPPER_INSTALL_DIR << ")\n";
96     exit(1);
97
98     return "";
99 }
100
101 static int
102 do_trace_posix(int argc, char *argv[])
103 {
104     os::Path binary = find_wrapper(CLI_TRACE_WRAPPER);
105
106     /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the
107      * directory, not the file. */
108 #ifdef __APPLE__
109     binary.trimFilename();
110 #endif
111
112     if (verbose) {
113         std::cerr << CLI_TRACE_VARIABLE << "=" << binary.str() << "\n";
114     }
115
116     setenv(CLI_TRACE_VARIABLE, binary.str(), 1);
117
118     if (verbose) {
119         const char *sep = "";
120         for (char **arg = argv; *arg; ++arg) {
121             std::cerr << *arg << sep;
122             sep = " ";
123         }
124         std::cerr << "\n";
125     }
126
127     execvp(argv[0], argv);
128
129     std::cerr << "Error: Failed to execute " << argv[0] << "\n";
130
131     return 1;
132 }
133
134 #endif
135
136 static int
137 command(int argc, char *argv[])
138 {
139
140 #ifdef _WIN32
141
142     std::cerr <<
143         "The 'apitrace trace' command is not supported for this operating system.\n"
144         "Instead, you will need to copy opengl32.dll, d3d8.dll, or d3d9.dll from\n"
145         APITRACE_WRAPPER_INSTALL_DIR "\n"
146         "to the directory with the application to trace, then run the application.\n";
147     return 1;
148
149 #else
150
151     int i;
152
153     for (i = 0; i < argc; ++i) {
154         const char *arg = argv[i];
155
156         if (arg[0] != '-') {
157             break;
158         }
159
160         if (!strcmp(arg, "--")) {
161             i++;
162             break;
163         } else if (!strcmp(arg, "--help")) {
164             usage();
165             return 0;
166         } else {
167             std::cerr << "error: unknown option " << arg << "\n";
168             usage();
169             return 1;
170         }
171     }
172
173     if (i == argc) {
174         std::cerr << "Error: Need a command name to execute (see 'apitrace trace --help')\n";
175         return 1;
176     }
177
178     return do_trace_posix(argc - i, argv + i);
179
180 #endif
181 }
182
183 const Command trace_command = {
184     "trace",
185     synopsis,
186     usage,
187     command
188 };