Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: support lib.cc #1035

Merged
merged 33 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ba22565
initial library building support
Nov 14, 2024
aef5ee2
remove debug print
Nov 14, 2024
8026e26
fmt
Nov 14, 2024
d7963cf
Merge pull request #1 from poac-dev/main
Lazauya Nov 14, 2024
739474c
Merge remote-tracking branch 'refs/remotes/origin/main' into lib-buil…
Nov 14, 2024
8765dcc
merge master
Nov 14, 2024
3cb0dc7
rollback formatting
Nov 14, 2024
bac7f94
rollback something
Nov 14, 2024
47f8ec8
use format for lib build command
Nov 15, 2024
9cc8c6e
Merge branch 'poac-dev:main' into main
Lazauya Nov 15, 2024
d75857a
Merge remote-tracking branch 'origin/main' into lib-building
Nov 15, 2024
f12e007
formatting, fix uninitialized vars
Nov 15, 2024
3967984
formatting, fix uninitialized vars
Nov 15, 2024
7fc1152
fix lint errors
Nov 15, 2024
a32a4a6
change to fmt::format
Nov 15, 2024
b822f85
format
Nov 15, 2024
b00868f
Merge branch 'poac-dev:main' into main
Lazauya Nov 16, 2024
344be4c
Merge remote-tracking branch 'origin/main' into lib-building
Nov 16, 2024
911d6e0
format
Nov 16, 2024
b28f9a9
fix build
Nov 16, 2024
9e58bf4
refactor build command into function
Nov 16, 2024
0ed1788
preallocate commands vec and make const
Nov 16, 2024
a2bebc9
change var names, introduce library name variables
Nov 21, 2024
e2da2be
Merge branch 'poac-dev:main' into main
Lazauya Nov 23, 2024
48c07e4
Merge remote-tracking branch 'refs/remotes/origin/main' into lib-buil…
Nov 23, 2024
1bc082f
move libname to BuildConfig and fix formatting
Nov 23, 2024
1452d25
combine defineLib/LinkTarget into single func, rename executable to b…
Nov 30, 2024
8aa24f5
Merge branch 'poac-dev:main' into main
Lazauya Dec 5, 2024
f272a04
Merge remote-tracking branch 'origin/main' into lib-building
Dec 5, 2024
fae6c1b
update archive build command, make command constants
Dec 5, 2024
38711a7
fix library name for already prefixed names. e.g. libpoac no longer b…
Dec 7, 2024
60920f2
change to references
Dec 12, 2024
fced6bc
Merge branch 'main' into lib-building
ken-matsui Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 82 additions & 14 deletions src/BuildConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ operator<<(std::ostream& os, VarType type) {

BuildConfig::BuildConfig(const std::string& packageName, const bool isDebug)
: packageName{ packageName }, isDebug{ isDebug } {
ken-matsui marked this conversation as resolved.
Show resolved Hide resolved
libName = fmt::format("lib{}.a", packageName);
const fs::path projectBasePath = getProjectBasePath();
if (isDebug) {
outBasePath = projectBasePath / "poac-out" / "debug";
Expand Down Expand Up @@ -489,11 +490,22 @@ void
BuildConfig::defineLinkTarget(
const std::string& binTarget, const std::unordered_set<std::string>& deps
) {
std::vector<std::string> commands;
commands.emplace_back("$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@");
const std::vector<std::string> commands = {
"$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@"
};
defineTarget(binTarget, commands, deps);
}

void
BuildConfig::defineLibTarget(
const std::string& libTarget, const std::unordered_set<std::string>& deps
) {
const std::vector<std::string> commands = {
fmt::format("ar rcs {} $^", libName)
};
defineTarget(libTarget, commands, deps);
}

// Map a path to header file to the corresponding object file.
//
// e.g., src/path/to/header.h -> poac.d/path/to/header.o
Expand Down Expand Up @@ -791,6 +803,9 @@ BuildConfig::configureBuild() {
const auto isMainSource = [](const fs::path& file) {
return file.filename().stem() == "main";
};
const auto isLibSource = [](const fs::path& file) {
return file.filename().stem() == "lib";
};
fs::path mainSource;
for (const auto& entry : fs::directory_iterator(srcDir)) {
const fs::path& path = entry.path();
Expand All @@ -802,13 +817,34 @@ BuildConfig::configureBuild() {
}
if (mainSource.empty()) {
mainSource = path;
executable = true;
} else {
throw PoacError("multiple main sources were found");
}
}

if (mainSource.empty()) {
throw PoacError(fmt::format("src/main{} was not found", SOURCE_FILE_EXTS));
fs::path libSource;
for (const auto& entry : fs::directory_iterator(srcDir)) {
const fs::path& path = entry.path();
if (!SOURCE_FILE_EXTS.contains(path.extension())) {
continue;
}
if (!isLibSource(path)) {
continue;
}
if (libSource.empty()) {
libSource = path;
library = true;
} else {
throw PoacError("multiple lib sources were found");
}
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
}

if (!executable && !library) {
throw PoacError(fmt::format(
"neither src/main{} nor src/lib{} was not found", SOURCE_FILE_EXTS,
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
SOURCE_FILE_EXTS
));
}

if (!fs::exists(outBasePath)) {
Expand All @@ -817,8 +853,16 @@ BuildConfig::configureBuild() {

setVariables();

std::unordered_set<std::string> allTargets = {};
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
if (executable) {
allTargets.insert(packageName);
}
if (library) {
allTargets.insert(libName);
}

// Build rules
setAll({ packageName });
setAll(allTargets);
addPhony("all");

std::vector<fs::path> sourceFilePaths = listSourceFilePaths(srcDir);
Expand All @@ -832,7 +876,16 @@ BuildConfig::configureBuild() {
"Move it directly to 'src/' if intended as such.",
sourceFilePath.string()
);
} else if (sourceFilePath != libSource && isLibSource(sourceFilePath)) {
logger::warn(
"source file `{}` is named `lib` but is not located directly in the "
"`src/` directory. "
"This file will not be treated as a library. "
"Move it directly to 'src/' if intended as such.",
sourceFilePath.string()
);
}

srcs += ' ' + sourceFilePath.string();
}

Expand All @@ -842,16 +895,31 @@ BuildConfig::configureBuild() {
const std::unordered_set<std::string> buildObjTargets =
processSources(sourceFilePaths);

// Project binary target.
const std::string mainObjTarget = buildOutPath / "main.o";
std::unordered_set<std::string> projTargetDeps = { mainObjTarget };
collectBinDepObjs(
projTargetDeps, "",
targets.at(mainObjTarget).remDeps, // we don't need sourceFile
buildObjTargets
);
if (executable) {
// Project binary target.
const std::string mainObjTarget = buildOutPath / "main.o";
std::unordered_set<std::string> projTargetDeps = { mainObjTarget };

defineLinkTarget(outBasePath / packageName, projTargetDeps);
collectBinDepObjs(
projTargetDeps, "",
targets.at(mainObjTarget).remDeps, // we don't need sourceFile
buildObjTargets
);

Lazauya marked this conversation as resolved.
Show resolved Hide resolved
defineLinkTarget(outBasePath / packageName, projTargetDeps);
}

if (library) {
// Project library target.
const std::string libTarget = buildOutPath / "lib.o";
std::unordered_set<std::string> libTargetDeps = { libTarget };
collectBinDepObjs(
libTargetDeps, "",
targets.at(libTarget).remDeps, // we don't need sourceFile
buildObjTargets
);
defineLibTarget(outBasePath / libName, libTargetDeps);
}

// Test Pass
std::unordered_set<std::string> testTargets;
Expand Down
18 changes: 18 additions & 0 deletions src/BuildConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ struct BuildConfig {

private:
std::string packageName;
std::string libName;
fs::path buildOutPath;
fs::path unittestOutPath;
bool isDebug;

// if we are building an executable
bool executable{ false };
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
// if we are building a library
bool library{ false };
Lazauya marked this conversation as resolved.
Show resolved Hide resolved

std::unordered_map<std::string, Variable> variables;
std::unordered_map<std::string, std::vector<std::string>> varDeps;
std::unordered_map<std::string, Target> targets;
Expand All @@ -67,6 +73,13 @@ struct BuildConfig {
public:
explicit BuildConfig(const std::string& packageName, bool isDebug = true);

bool isExecutable() const {
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
return executable;
}
bool isLibrary() const {
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
return library;
}
ken-matsui marked this conversation as resolved.
Show resolved Hide resolved

void defineVar(
const std::string& name, const Variable& value,
const std::unordered_set<std::string>& dependsOn = {}
Expand All @@ -77,12 +90,14 @@ struct BuildConfig {
varDeps[dep].push_back(name);
}
}

void defineSimpleVar(
const std::string& name, const std::string& value,
const std::unordered_set<std::string>& dependsOn = {}
) {
defineVar(name, { .value = value, .type = VarType::Simple }, dependsOn);
}

void defineCondVar(
const std::string& name, const std::string& value,
const std::unordered_set<std::string>& dependsOn = {}
Expand Down Expand Up @@ -145,6 +160,9 @@ struct BuildConfig {
void defineLinkTarget(
const std::string& binTarget, const std::unordered_set<std::string>& deps
);
void defineLibTarget(
const std::string& libTarget, const std::unordered_set<std::string>& deps
);

void collectBinDepObjs( // NOLINT(misc-no-recursion)
std::unordered_set<std::string>& deps, std::string_view sourceFileName,
Expand Down
38 changes: 27 additions & 11 deletions src/Cmd/Build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,45 @@ const Subcmd BUILD_CMD =
.setMainFn(buildMain);

int
buildImpl(std::string& outDir, const bool isDebug) {
const auto start = std::chrono::steady_clock::now();

const BuildConfig config = emitMakefile(isDebug, /*includeDevDeps=*/false);
outDir = config.outBasePath;

const std::string& packageName = getPackageName();
runBuildCommand(
const std::string& outDir, const BuildConfig& config,
const std::string& targetName
) {
const Command makeCmd = getMakeCommand().addArg("-C").addArg(outDir).addArg(
(config.outBasePath / packageName).string()
(config.outBasePath / targetName).string()
);
Command checkUpToDateCmd = makeCmd;
checkUpToDateCmd.addArg("--question");

int exitCode = execCmd(checkUpToDateCmd);
if (exitCode != EXIT_SUCCESS) {
// If packageName binary is not up-to-date, compile it.
// If targetName binary is not up-to-date, compile it.
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
logger::info(
"Compiling", "{} v{} ({})", packageName, getPackageVersion().toString(),
"Compiling", "{} v{} ({})", targetName, getPackageVersion().toString(),
getProjectBasePath().string()

);
exitCode = execCmd(makeCmd);
}
return exitCode;
}

int
buildImpl(std::string& outDir, const bool isDebug) {
const auto start = std::chrono::steady_clock::now();

const BuildConfig config = emitMakefile(isDebug, /*includeDevDeps=*/false);
outDir = config.outBasePath;

const std::string& packageName = getPackageName();
int exitCode = 0;
if (config.isExecutable()) {
exitCode = runBuildCommand(outDir, config, packageName);
}

if (config.isLibrary() && exitCode == 0) {
const std::string libName = getLibraryName();
Lazauya marked this conversation as resolved.
Show resolved Hide resolved
exitCode = runBuildCommand(outDir, config, libName);
}

const auto end = std::chrono::steady_clock::now();
const std::chrono::duration<double> elapsed = end - start;
Expand Down
4 changes: 4 additions & 0 deletions src/Manifest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ const std::string&
getPackageName() {
return parsePackage().name;
}
std::string
getLibraryName() {
return fmt::format("lib{}.a", getPackageName());
}
const Edition&
getPackageEdition() {
return parsePackage().edition;
Expand Down
1 change: 1 addition & 0 deletions src/Manifest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const fs::path& getManifestPath();
fs::path getProjectBasePath();
std::optional<std::string> validatePackageName(std::string_view name) noexcept;
const std::string& getPackageName();
std::string getLibraryName();
const Edition& getPackageEdition();
const Version& getPackageVersion();
const Profile& getDevProfile();
Expand Down