1+ use std:: env;
2+ use std:: path:: { Path , PathBuf } ;
3+ use std:: process:: Command ;
4+
5+ use crate :: handle_failed_output;
6+
7+ /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available
8+ /// at `$LLVM_BIN_DIR/llvm-readobj`.
9+ pub fn llvm_readobj ( ) -> LlvmReadobj {
10+ LlvmReadobj :: new ( )
11+ }
12+
13+ /// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available
14+ /// at `$LLVM_BIN_DIR/llvm-profdata`.
15+ pub fn llvm_profdata ( ) -> LlvmProfdata {
16+ LlvmProfdata :: new ( )
17+ }
18+
19+ /// A `llvm-readobj` invocation builder.
20+ #[ derive( Debug ) ]
21+ pub struct LlvmReadobj {
22+ cmd : Command ,
23+ }
24+
25+ /// A `llvm-profdata` invocation builder.
26+ #[ derive( Debug ) ]
27+ pub struct LlvmProfdata {
28+ cmd : Command ,
29+ }
30+
31+ crate :: impl_common_helpers!( LlvmReadobj ) ;
32+
33+ /// Generate the path to the bin directory of LLVM.
34+ pub fn llvm_bin_dir ( ) -> PathBuf {
35+ let llvm_bin_dir = env:: var ( "LLVM_BIN_DIR" )
36+ . expect ( "`LLVM_BIN_DIR` not specified, but this is required to find `llvm-readobj`" ) ;
37+ PathBuf :: from ( llvm_bin_dir) ;
38+ }
39+
40+ impl LlvmReadobj {
41+ /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available
42+ /// at `$LLVM_BIN_DIR/llvm-readobj`.
43+ pub fn new ( ) -> Self {
44+ let llvm_readobj = llvm_bin_dir ( ) . join ( "llvm-readobj" ) ;
45+ let cmd = Command :: new ( llvm_readobj) ;
46+ Self { cmd }
47+ }
48+
49+ /// Provide an input file.
50+ pub fn input < P : AsRef < Path > > ( & mut self , path : P ) -> & mut Self {
51+ self . cmd . arg ( path. as_ref ( ) ) ;
52+ self
53+ }
54+
55+ /// Pass `--file-header` to display file headers.
56+ pub fn file_header ( & mut self ) -> & mut Self {
57+ self . cmd . arg ( "--file-header" ) ;
58+ self
59+ }
60+
61+ /// Get the [`Output`][::std::process::Output] of the finished process.
62+ #[ track_caller]
63+ pub fn command_output ( & mut self ) -> :: std:: process:: Output {
64+ self . cmd . output ( ) . expect ( "failed to get output of finished process" )
65+ }
66+ }
67+
68+ impl LlvmProfdata {
69+ /// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available
70+ /// at `$LLVM_BIN_DIR/llvm-profdata`.
71+ pub fn new ( ) -> Self {
72+ let llvm_profdata = llvm_bin_dir ( ) . join ( "llvm-profdata" ) ;
73+ let cmd = Command :: new ( llvm_profdata) ;
74+ Self { cmd }
75+ }
76+
77+ /// Provide an input file.
78+ pub fn input < P : AsRef < Path > > ( & mut self , path : P ) -> & mut Self {
79+ self . cmd . arg ( "-o" ) ;
80+ self . cmd . arg ( path. as_ref ( ) ) ;
81+ self
82+ }
83+
84+ /// Specify the output file path.
85+ pub fn output < P : AsRef < Path > > ( & mut self , path : P ) -> & mut Self {
86+ self . cmd . arg ( path. as_ref ( ) ) ;
87+ self
88+ }
89+
90+ /// Take several profile data files generated by PGO instrumentation and merge them
91+ /// together into a single indexed profile data file.
92+ pub fn merge ( & mut self ) -> & mut Self {
93+ self . cmd . arg ( "merge" ) ;
94+ self
95+ }
96+
97+ /// Get the [`Output`][::std::process::Output] of the finished process.
98+ #[ track_caller]
99+ pub fn command_output ( & mut self ) -> :: std:: process:: Output {
100+ self . cmd . output ( ) . expect ( "failed to get output of finished process" )
101+ }
102+ }
0 commit comments