Skip to content

Commit ae6ac77

Browse files
authored
[CRTP] Target getter (#156)
1 parent 2a27135 commit ae6ac77

File tree

11 files changed

+169
-58
lines changed

11 files changed

+169
-58
lines changed

buildcc/lib/target/cmake/mock_target.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ add_library(mock_target STATIC
1717
src/api/copy_api.cpp
1818

1919
src/api/target_info_getter.cpp
20-
20+
src/api/target_getter.cpp
2121

2222
# Generator
2323
src/generator/generator_loader.cpp

buildcc/lib/target/cmake/target.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ set(TARGET_SRCS
3535
include/target/api/copy_api.h
3636

3737
src/api/target_info_getter.cpp
38+
src/api/target_getter.cpp
3839
include/target/api/target_info_getter.h
40+
include/target/api/target_getter.h
3941

4042
# Generator
4143
src/generator/generator_loader.cpp
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2021 Niket Naidu. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef TARGET_API_TARGET_GETTER_H_
18+
#define TARGET_API_TARGET_GETTER_H_
19+
20+
#include <filesystem>
21+
#include <string>
22+
23+
#include "target/common/target_type.h"
24+
25+
#include "toolchain/toolchain.h"
26+
27+
#include "taskflow/taskflow.hpp"
28+
29+
namespace fs = std::filesystem;
30+
31+
namespace buildcc::base {
32+
33+
template <typename T> class TargetGetter {
34+
public:
35+
const std::string &GetName() const;
36+
const Toolchain &GetToolchain() const;
37+
TargetType GetType() const;
38+
39+
const fs::path &GetTargetPath() const;
40+
const fs::path &GetBinaryPath() const;
41+
42+
const fs::path &GetPchHeaderPath() const;
43+
const fs::path &GetPchCompilePath() const;
44+
45+
const std::string &GetCompileCommand(const fs::path &source) const;
46+
const std::string &GetLinkCommand() const;
47+
48+
tf::Taskflow &GetTaskflow();
49+
};
50+
51+
}; // namespace buildcc::base
52+
53+
#endif

buildcc/lib/target/include/target/generator_loader.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,15 @@ namespace buildcc::internal {
3232
class GeneratorLoader : public LoaderInterface {
3333
public:
3434
GeneratorLoader(const std::string &name, const fs::path &absolute_path)
35-
: name_(name), path_(absolute_path) {}
35+
: name_(name), path_(absolute_path) {
36+
binary_path_ = absolute_path / fmt::format("{}.bin", name);
37+
}
3638

3739
GeneratorLoader(const GeneratorLoader &loader) = delete;
3840

3941
bool Load() override;
4042

4143
// Getters
42-
fs::path GetBinaryPath() const override {
43-
return path_ / fmt::format("{}.bin", name_);
44-
}
45-
4644
const internal::path_unordered_set &GetLoadedInputFiles() const {
4745
return loaded_input_files_;
4846
}

buildcc/lib/target/include/target/loader_interface.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ namespace buildcc::internal {
2626
class LoaderInterface {
2727
public:
2828
virtual bool Load() = 0;
29-
virtual fs::path GetBinaryPath() const = 0;
3029

30+
const fs::path &GetBinaryPath() const { return binary_path_; };
3131
bool IsLoaded() const { return loaded_; };
3232

3333
protected:
3434
bool loaded_{false};
35+
fs::path binary_path_;
3536
};
3637

3738
} // namespace buildcc::internal

buildcc/lib/target/include/target/target.h

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "target/builder_interface.h"
3232

3333
// API
34+
#include "target/api/target_getter.h"
3435
#include "target/target_info.h"
3536

3637
// Common
@@ -61,7 +62,9 @@ namespace buildcc::base {
6162
// of the inheritance pattern
6263
// NOTE, base::Target is meant to be a blank slate which can be customized by
6364
// the specialized target-toolchain classes
64-
class Target : public BuilderInterface, public TargetInfo {
65+
class Target : public BuilderInterface,
66+
public TargetInfo,
67+
public TargetGetter<Target> {
6568

6669
public:
6770
explicit Target(const std::string &name, TargetType type,
@@ -82,57 +85,12 @@ class Target : public BuilderInterface, public TargetInfo {
8285
// Builders
8386
void Build() override;
8487

85-
// Getters (GENERIC)
86-
87-
// NOTE, We are constructing the path
88-
fs::path GetBinaryPath() const { return loader_.GetBinaryPath(); }
89-
const fs::path &GetTargetPath() const { return link_target_.GetOutput(); }
90-
const fs::path &GetPchHeaderPath() const {
91-
return compile_pch_.GetHeaderPath();
92-
}
93-
const fs::path &GetPchCompilePath() const {
94-
return compile_pch_.GetCompilePath();
95-
}
96-
97-
// Const references
98-
99-
// TODO, Shift getters to source file as well
100-
const std::string &GetName() const { return name_; }
101-
const Toolchain &GetToolchain() const { return toolchain_; }
102-
TargetType GetType() const { return type_; }
103-
104-
//
105-
106-
// Getters (state_.ExpectsLock)
107-
108-
const std::string &GetCompileCommand(const fs::path &source) const {
109-
state_.ExpectsLock();
110-
return compile_object_.GetObjectData(source).command;
111-
}
112-
const std::string &GetLinkCommand() const {
113-
state_.ExpectsLock();
114-
return link_target_.GetCommand();
115-
}
116-
117-
tf::Taskflow &GetTaskflow() {
118-
state_.ExpectsLock();
119-
return tf_;
120-
}
121-
122-
// TODO, Add more getters
123-
12488
private:
12589
friend class CompilePch;
12690
friend class CompileObject;
12791
friend class LinkTarget;
12892

129-
friend class CopyApi<Target>;
130-
friend class SourceApi<Target>;
131-
friend class IncludeApi<Target>;
132-
friend class LibApi<Target>;
133-
friend class PchApi<Target>;
134-
friend class FlagApi<Target>;
135-
friend class DepsApi<Target>;
93+
friend class TargetGetter<Target>;
13694

13795
private:
13896
void Initialize();

buildcc/lib/target/include/target/target_loader.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class TargetLoader : public LoaderInterface {
3232
public:
3333
explicit TargetLoader(const std::string &name, const fs::path &relative_path)
3434
: name_(name), relative_path_(relative_path) {
35+
binary_path_ = relative_path / fmt::format("{}.bin", name);
3536
Initialize();
3637
}
3738

@@ -41,10 +42,6 @@ class TargetLoader : public LoaderInterface {
4142
bool Load() override;
4243

4344
// Getters
44-
fs::path GetBinaryPath() const override {
45-
return relative_path_ / fmt::format("{}.bin", name_);
46-
}
47-
4845
const path_unordered_set &GetLoadedSources() const { return loaded_sources_; }
4946
const path_unordered_set &GetLoadedHeaders() const { return loaded_headers_; }
5047
const path_unordered_set &GetLoadedPchs() const { return loaded_pchs_; }
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2021 Niket Naidu. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "target/api/target_getter.h"
18+
19+
#include "target/target.h"
20+
21+
namespace buildcc::base {
22+
23+
template <typename T> const fs::path &TargetGetter<T>::GetBinaryPath() const {
24+
const T &t = static_cast<const T &>(*this);
25+
26+
return t.loader_.GetBinaryPath();
27+
}
28+
29+
template <typename T> const fs::path &TargetGetter<T>::GetTargetPath() const {
30+
const T &t = static_cast<const T &>(*this);
31+
32+
return t.link_target_.GetOutput();
33+
}
34+
35+
template <typename T>
36+
const fs::path &TargetGetter<T>::GetPchHeaderPath() const {
37+
const T &t = static_cast<const T &>(*this);
38+
39+
return t.compile_pch_.GetHeaderPath();
40+
}
41+
42+
template <typename T>
43+
const fs::path &TargetGetter<T>::GetPchCompilePath() const {
44+
const T &t = static_cast<const T &>(*this);
45+
46+
return t.compile_pch_.GetCompilePath();
47+
}
48+
49+
template <typename T> const std::string &TargetGetter<T>::GetName() const {
50+
const T &t = static_cast<const T &>(*this);
51+
52+
return t.name_;
53+
}
54+
55+
template <typename T> const Toolchain &TargetGetter<T>::GetToolchain() const {
56+
const T &t = static_cast<const T &>(*this);
57+
58+
return t.toolchain_;
59+
}
60+
61+
template <typename T> TargetType TargetGetter<T>::GetType() const {
62+
const T &t = static_cast<const T &>(*this);
63+
64+
return t.type_;
65+
}
66+
67+
template <typename T>
68+
const std::string &
69+
TargetGetter<T>::GetCompileCommand(const fs::path &source) const {
70+
const T &t = static_cast<const T &>(*this);
71+
72+
t.state_.ExpectsLock();
73+
return t.compile_object_.GetObjectData(source).command;
74+
}
75+
76+
template <typename T>
77+
const std::string &TargetGetter<T>::GetLinkCommand() const {
78+
const T &t = static_cast<const T &>(*this);
79+
80+
t.state_.ExpectsLock();
81+
return t.link_target_.GetCommand();
82+
}
83+
84+
template <typename T> tf::Taskflow &TargetGetter<T>::GetTaskflow() {
85+
T &t = static_cast<T &>(*this);
86+
87+
t.state_.ExpectsLock();
88+
return t.tf_;
89+
}
90+
91+
template class TargetGetter<Target>;
92+
93+
} // namespace buildcc::base

buildcc/lib/target/test/target/test_base_target.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ TEST(TargetBaseTestGroup, TargetConfig_BadCompileCommand) {
6464
config.compile_command = "{invalid_compile_string}";
6565
buildcc::base::Target simple(NAME, buildcc::base::TargetType::Executable,
6666
gcc, "data", config);
67+
CHECK(simple.GetType() == buildcc::base::TargetType::Executable);
6768
simple.AddSource("dummy_main.c");
6869
CHECK_THROWS(std::exception, simple.Build());
6970
}

buildcc/lib/target/test/target/test_target_lock.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ TEST(TargetTestLock, Unlock_APIs) {
101101
CHECK_THROWS(std::exception,
102102
exe.GetCompileCommand(exe.GetTargetRootDir() / "dummy_main.c"));
103103
CHECK_THROWS(std::exception, exe.GetLinkCommand());
104+
CHECK_THROWS(std::exception, exe.GetTaskflow());
104105

105106
exe.AddSource("dummy_main.c");
106107
buildcc::m::CommandExpect_Execute(1, true);
@@ -110,6 +111,7 @@ TEST(TargetTestLock, Unlock_APIs) {
110111

111112
exe.GetCompileCommand(exe.GetTargetRootDir() / "dummy_main.c");
112113
exe.GetLinkCommand();
114+
exe.GetTaskflow();
113115
}
114116

115117
int main(int ac, char **av) {

buildcc/lib/target/test/target/test_target_pch.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ TEST(TargetPchTestGroup, Target_AddPch_Build) {
5656
bool exists = fs::exists(target.GetPchHeaderPath());
5757
CHECK_TRUE(exists);
5858

59+
// Save file
60+
buildcc::env::SaveFile(target.GetPchCompilePath().string().c_str(), "",
61+
false);
62+
exists = fs::exists(target.GetPchHeaderPath());
63+
CHECK_TRUE(exists);
64+
5965
mock().checkExpectations();
6066
}
6167

0 commit comments

Comments
 (0)