Skip to content

Try to make exename portable. Refactor searchForIncludePath. #5185

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

Merged
merged 10 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
1 change: 0 additions & 1 deletion backends/bmv2/pna_nic/options.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "options.h"

#include "frontends/common/parser_options.h"
#include "lib/exename.h"

namespace P4::BMV2 {} // namespace P4::BMV2
8 changes: 7 additions & 1 deletion backends/bmv2/portable_common/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ namespace P4::BMV2 {
using namespace P4::literals;

std::vector<const char *> *PortableOptions::process(int argc, char *const argv[]) {
auto executablePath = getExecutablePath(argv[0]);
if (executablePath.empty()) {
std::cerr << "Could not determine executable path" << std::endl;
return nullptr;
}
this->exe_name = cstring(executablePath.stem().c_str());
searchForIncludePath(p4includePath,
{"p4include/bmv2"_cs, "../p4include/bmv2"_cs, "../../p4include/bmv2"_cs},
exename(argv[0]));
executablePath.c_str());

auto remainingOptions = CompilerOptions::process(argc, argv);

Expand Down
1 change: 0 additions & 1 deletion backends/dpdk/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ limitations under the License.
#include "ir/json_loader.h"
#include "lib/error.h"
#include "lib/exceptions.h"
#include "lib/exename.h"
#include "lib/gc.h"
#include "lib/log.h"
#include "lib/nullstream.h"
Expand Down
11 changes: 9 additions & 2 deletions backends/dpdk/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ namespace P4::DPDK {
using namespace P4::literals;

std::vector<const char *> *DpdkOptions::process(int argc, char *const argv[]) {
auto executablePath = getExecutablePath(argv[0]);
if (executablePath.empty()) {
std::cerr << "Could not determine executable path" << std::endl;
return nullptr;
}
this->exe_name = cstring(executablePath.stem().c_str());

searchForIncludePath(p4includePath,
{"p4include/dpdk"_cs, "../p4include/dpdk"_cs, "../../p4include/dpdk"_cs},
exename(argv[0]));
executablePath.c_str());

auto remainingOptions = CompilerOptions::process(argc, argv);
auto *remainingOptions = CompilerOptions::process(argc, argv);

return remainingOptions;
}
Expand Down
1 change: 0 additions & 1 deletion backends/tofino/bf-asm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ set (BFAS_COMMON_SOURCES
dynhash.cpp
error_mode.cpp
exact_match.cpp
exename.cpp
flexible_headers.cpp
gateway.cpp
hash_action.cpp
Expand Down
2 changes: 1 addition & 1 deletion backends/tofino/bf-asm/crash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
#include <iostream>

#include "bfas.h"
#include "exename.h"
#include "lib/exceptions.h"
#include "lib/exename.h"
#include "lib/hex.h"
#include "lib/log.h"

Expand Down
70 changes: 0 additions & 70 deletions backends/tofino/bf-asm/exename.cpp

This file was deleted.

25 changes: 0 additions & 25 deletions backends/tofino/bf-asm/exename.h

This file was deleted.

12 changes: 10 additions & 2 deletions backends/tofino/bf-p4c/bf-p4c-options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "ir/ir.h"
#include "ir/visitor.h"
#include "lib/cstring.h"
#include "lib/exename.h"
#include "lib/log.h"
#include "version.h"

Expand Down Expand Up @@ -712,14 +713,21 @@ std::vector<const char *> *BFN_Options::process(int argc, char *const argv[]) {
// Don't know, and I'm at the end of my patience with it ...
if (!processed) outputDir = "."_cs;

auto executablePath = getExecutablePath(argv[0]);
if (executablePath.empty()) {
std::cerr << "Could not determine executable path" << std::endl;
return nullptr;
}
this->exe_name = cstring(executablePath.stem().c_str());
// sde installs p4include directory to $SDE/install/share/p4c/p4include
// and installs p4c to $SDE/install/bin/
//
// Therefore, we need to search ../share/p4c/p4include from the
// directory that p4c resides in.
searchForIncludePath(p4includePath, {"../share/p4c/p4include"_cs}, exename(argv[0]));
searchForIncludePath(p4includePath, {"../share/p4c/p4include"_cs}, executablePath.c_str());

searchForIncludePath(p4_14includePath, {"../share/p4c/p4_14include"_cs}, exename(argv[0]));
searchForIncludePath(p4_14includePath, {"../share/p4c/p4_14include"_cs},
executablePath.c_str());

auto remainingOptions = CompilerOptions::process(argc, argv);

Expand Down
1 change: 0 additions & 1 deletion backends/tofino/bf-p4c/bf-p4c-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "frontends/common/applyOptionsPragmas.h"
#include "frontends/common/options.h"
#include "lib/cstring.h"
#include "lib/exename.h"
#include "logging/bf_error_reporter.h"

class BFN_Options : public CompilerOptions {
Expand Down
58 changes: 21 additions & 37 deletions frontends/common/parser_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ limitations under the License.
#include <sys/types.h>
#include <sys/wait.h>

#include <filesystem>
#include <memory>
#include <regex>
#include <unordered_set>
Expand All @@ -42,6 +43,7 @@ namespace P4 {
* installed from source locally. If the compiled binary is moved to another
* machine, the 'p4includePath' would contain the path on the original machine.
*/
// TODO: This should be std::filesystem::path.
const char *p4includePath = CONFIG_PKGDATADIR "/p4include";
const char *p4_14includePath = CONFIG_PKGDATADIR "/p4_14include";

Expand Down Expand Up @@ -355,53 +357,35 @@ void ParserOptions::setInputFile() {
}
}

namespace {

bool setIncludePathIfExists(const char *&includePathOut, const char *possiblePath) {
struct stat st;
if (!(stat(possiblePath, &st) >= 0 && S_ISDIR(st.st_mode))) return false;
if (auto path = realpath(possiblePath, NULL))
includePathOut = path;
else
includePathOut = strdup(possiblePath);
return true;
}

} // namespace

bool ParserOptions::searchForIncludePath(const char *&includePathOut,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This functions should really get a better interface overall, the output const char * argument that is heap-allocated is quite ugly. But I agree with doing it in a separate PR.

std::vector<cstring> userSpecifiedPaths,
const std::vector<cstring> &userSpecifiedPaths,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to vector of std::filesystem::path?

const char *exename) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can exename be converted to std::filesystem::path while here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would break downstream use of that function, figured I should do that in a separate PR. Ditto for all the cstring typing of variables that should be a path.

bool found = false;
char buffer[PATH_MAX];

BUG_CHECK(strlen(exename) < PATH_MAX, "executable path %1% is too long.", exename);

snprintf(buffer, sizeof(buffer), "%s", exename);
if (char *p = strrchr(buffer, '/')) {
++p;
exe_name = cstring(p);

for (auto path : userSpecifiedPaths) {
snprintf(p, buffer + sizeof(buffer) - p, "%s", path.c_str());
if (setIncludePathIfExists(includePathOut, buffer)) {
LOG3("Setting p4 include path to " << includePathOut);
found = true;
break;
}
for (const auto &path : userSpecifiedPaths) {
auto includePath =
std::filesystem::path(exename).parent_path() / std::filesystem::path(path.c_str());
if (std::filesystem::exists(includePath)) {
includePathOut = strdup(std::filesystem::absolute(includePath).c_str());
return true;
}
}
return found;
return false;
}

std::vector<const char *> *ParserOptions::process(int argc, char *const argv[]) {
searchForIncludePath(p4includePath, {"p4include"_cs, "../p4include"_cs, "../../p4include"_cs},
exename(argv[0]));
auto executablePath = getExecutablePath(argv[0]);
if (executablePath.empty()) {
std::cerr << "Could not determine executable path" << std::endl;
return nullptr;
}
this->exe_name = cstring(executablePath.stem().c_str());

searchForIncludePath(p4_14includePath,
{"p4_14include"_cs, "../p4_14include"_cs, "../../p4_14include"_cs},
exename(argv[0]));
executablePath.c_str());
searchForIncludePath(p4includePath, {"p4include"_cs, "../p4include"_cs, "../../p4include"_cs},
executablePath.c_str());

auto remainingOptions = Util::Options::process(argc, argv);
auto *remainingOptions = Util::Options::process(argc, argv);
if (!validateOptions()) {
return nullptr;
}
Expand Down
6 changes: 4 additions & 2 deletions frontends/common/parser_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ToP4;

/// Standard include paths for .p4 header files. The values are determined by
/// `configure`.
// TODO: This should be std::filesystem::path.
extern const char *p4includePath;
extern const char *p4_14includePath;

Expand Down Expand Up @@ -106,8 +107,9 @@ class ParserOptions : public Util::Options {
bool isAnnotationDisabled(const IR::Annotation *a) const;
/// Search and set 'includePathOut' to be the first valid path from the
/// list of possible relative paths.
bool searchForIncludePath(const char *&includePathOut, std::vector<cstring> relativePaths,
const char *);
static bool searchForIncludePath(const char *&includePathOut,
const std::vector<cstring> &userSpecifiedPaths,
const char *exename);
/// If true do not generate #include statements.
/// Used for debugging.
bool noIncludes = false;
Expand Down
11 changes: 9 additions & 2 deletions lib/alloc_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,15 @@ std::ostream &operator<<(std::ostream &out, const AllocTrace &at) {
}
std::sort(sorted.begin(), sorted.end(), [](auto &a, auto &b) { return a.first > b.first; });
#if HAVE_LIBBACKTRACE
if (!global_backtrace_state)
global_backtrace_state = backtrace_create_state(exename(), 1, bt_error, &out);
if (!global_backtrace_state) {
// TODO: Do not use strdup here?
auto executablePath = getExecutablePath();
if (executablePath.empty()) {
executablePath = "<unknown_path>";
}
const char *executableChar = strdup(executablePath.c_str());
global_backtrace_state = backtrace_create_state(executableChar, 1, bt_error, &out);
}
#endif

out << "Allocated a total of " << n4(total_total) << "B memory";
Expand Down
Loading
Loading