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

Team-4-Implementation-Final-2 #28

Open
wants to merge 1 commit into
base: team-4-Implementation
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 14 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,20 @@ jobs:
echo "Running $test"
./$test
done

- run:
name: Test New Graph
command: |
echo "Testing new graph"
cd new-graph
bash easybuild.sh
OUTPUT=$(./hello_world)
if [ "$OUTPUT" = "Hello World! " ]; then
echo "Output is correct: $OUTPUT"
else
echo "Test failed: Expected 'Hello World!', got '$OUTPUT'"
exit 1
fi
echo "New graph test completed successfully"

workflows:
build-test-workflow:
Expand Down
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,14 @@
/.vs/
/out/

commands.md
# general dev files for Shadowdash
*commands.md
*CMakeFiles
*.so
*.dylib
*.dll

# compile hello_world
*hello_world
*hello_world.o
*simulate-ninja-graph
11 changes: 11 additions & 0 deletions new-graph/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.10)

# Set the project name
project(HelloWorld)

# Specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Add the executable
add_executable(hello_world hello_world.cpp)
75 changes: 75 additions & 0 deletions new-graph/easybuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash

# Check OS
os_type=$(uname)
# Set default compiler and flags
export CC=gcc
export CXX=g++

if [[ "$os_type" == "Linux" ]]; then
lib_extension="so"
shared_flag="-shared"
rpath_flag="-Wl,-rpath=."
elif [[ "$os_type" == "Darwin" ]]; then
# Check gcc-11 on MacOS
if command -v gcc-11 &> /dev/null && command -v g++-11 &> /dev/null; then
echo "GNU g++-11 detected. Using g++-11 as the compiler."
export CC=gcc-11
export CXX=g++-11
else
echo "GNU g++-11 not found. Please install it using Homebrew with 'brew install gcc@11'."
echo "If another version of GCC (not Clang) is installed, please update this script accordingly."
exit 1
fi
lib_extension="dylib"
shared_flag="-dynamiclib"

# Add MacOS SDK path for standard headers
export SDK_PATH=$(xcrun --sdk macosx --show-sdk-path)
extra_flags="-isysroot $SDK_PATH"
rpath_flag="-Wl,-rpath,@loader_path"
else
# Assume is Windows
lib_extension="dll"
shared_flag="-shared"
rpath_flag="-Wl,-rpath=."
fi

# Build dynamic library
echo "Building libninja.${lib_extension}..."
$CXX -fPIC ${shared_flag} -I../src ${extra_flags} ../src/build_log.cc \
../src/build.cc \
../src/clean.cc \
../src/clparser.cc \
../src/dyndep.cc \
../src/dyndep_parser.cc \
../src/debug_flags.cc \
../src/deps_log.cc \
../src/disk_interface.cc \
../src/edit_distance.cc \
../src/elide_middle.cc \
../src/eval_env.cc \
../src/graph.cc \
../src/graphviz.cc \
../src/json.cc \
../src/line_printer.cc \
../src/manifest_parser.cc \
../src/metrics.cc \
../src/missing_deps.cc \
../src/parser.cc \
../src/state.cc \
../src/status_printer.cc \
../src/string_piece_util.cc \
../src/util.cc \
../src/subprocess-posix.cc \
../src/lexer.cc \
../src/depfile_parser.cc \
../src/version.cc -o "libninja.${lib_extension}"

# Compile simulate-ninja-graph.cc
echo "Compiling simulate-ninja-graph.cc..."
$CXX -fPIC simulate-ninja-graph.cc -I../src -L./ -lninja ${rpath_flag} ${extra_flags} -o simulate-ninja-graph

# Compile hello world using simulate-ninja-graph
echo "Running simulate-ninja-graph..."
./simulate-ninja-graph hello_world
10 changes: 10 additions & 0 deletions new-graph/hello_world.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <stdio.h>

#ifndef N
#define N "World"
#endif

int main() {
printf("Hello %s! \n", N);
return 0;
}
116 changes: 116 additions & 0 deletions new-graph/simulate-ninja-graph.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include "ninja.h"

using namespace std;

void CreateHelloWorldGraph(State* state, NinjaMain& ninja) {
BindingEnv env;
env.AddBinding("inputFile", "hello_world.cpp");
env.AddBinding("linkFile", "hello_world.o");
env.AddBinding("outputFile", "hello_world");

// Create rules
Rule* cxx_compiler = new Rule("CXX_COMPILER__hello_world_");

// Create command
EvalString command;
command.AddText("g++ -c ");
command.AddSpecial("in");
command.AddText(" -o ");
command.AddSpecial("out");
cxx_compiler->AddBinding("command", command);

// Create description
EvalString description;
description.AddText("Building CXX object ");
description.AddSpecial("out");
cxx_compiler->AddBinding("description", description);

// Add rule to state
state->bindings_.AddRule(cxx_compiler);

Rule* cxx_linker = new Rule("CXX_EXECUTABLE_LINKER__hello_world_");
EvalString link;
link.AddText("g++ ");
link.AddSpecial("in");
link.AddText(" -o ");
link.AddSpecial("out");
cxx_linker->AddBinding("command", link);

// Link description
EvalString linkDescription;
linkDescription.AddText("Linking CXX object ");
linkDescription.AddSpecial("$out");
cxx_linker->AddBinding("description", linkDescription);

state->bindings_.AddRule(cxx_linker);

// Create executable node
Node* executable = state->GetNode(env.LookupVariable("outputFile"), 0);

// Create compilation edges
string err;
Edge* compile_edge = ninja.GetState().AddEdge(cxx_compiler);

// Initialize the environment and bind the necessary variables.
if (compile_edge->env_ == nullptr) {
compile_edge->env_ = new BindingEnv(&state->bindings_);
}
compile_edge->env_->AddBinding("in", env.LookupVariable("inputFile"));
compile_edge->env_->AddBinding("out", env.LookupVariable("linkFile"));

if (!ninja.state_.AddOut(compile_edge, env.LookupVariable("linkFile"), 0,
&err)) {
Error(("Failed to add output to compile edge: " + err).c_str());
return;
}
ninja.state_.AddIn(compile_edge, env.LookupVariable("inputFile"), 0);

// Create link edges
Edge* link_edge = ninja.GetState().AddEdge(cxx_linker);

if (link_edge->env_ == nullptr) {
link_edge->env_ = new BindingEnv(&state->bindings_);
}
link_edge->env_->AddBinding("in", env.LookupVariable("linkFile"));
link_edge->env_->AddBinding("out", env.LookupVariable("outputFile"));

if (!ninja.state_.AddOut(link_edge, env.LookupVariable("outputFile"), 0,
&err)) {
Error(("Failed to add output to link edge: " + err).c_str());
return;
}
ninja.state_.AddIn(link_edge, env.LookupVariable("linkFile"), 0);

// Add default target
if (!state->AddDefault(env.LookupVariable("outputFile"), &err)) {
Error(("Failed to add default target: " + err).c_str());
return;
}
}

void Error(const string& message) {
cerr << "Error: " << message << endl;
}

int main(int argc, char** argv) {
const char* ninja_command = argv[0];

cout << "Build start" << endl;

// Config with Verbose output and 1 process
BuildConfig config;
config.verbosity = config.VERBOSE;
config.parallelism = 1; // 1 process
State state;
NinjaMain ninja(ninja_command, config);

// Create Graph
CreateHelloWorldGraph(&state, ninja);

Status* status = Status::factory(config);
int result = ninja.RunBuild(argc - 1, &argv[1], status);

cout << "Build completed" << endl;
delete status;
return 0;
}
54 changes: 26 additions & 28 deletions src/getopt.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,46 @@
/* include files needed by this include file */

/* macros defined by this include file */
#define no_argument 0
#define no_argument 0
#define required_argument 1
#define OPTIONAL_ARG 2
#define OPTIONAL_ARG 2

/* types defined by this include file */

/* GETOPT_LONG_OPTION_T: The type of long option */
typedef struct GETOPT_LONG_OPTION_T
{
const char *name; /* the name of the long option */
int has_arg; /* one of the above macros */
int *flag; /* determines if getopt_long() returns a
* value for a long option; if it is
* non-NULL, 0 is returned as a function
* value and the value of val is stored in
* the area pointed to by flag. Otherwise,
* val is returned. */
int val; /* determines the value to return if flag is
* NULL. */
typedef struct GETOPT_LONG_OPTION_T {
const char* name; /* the name of the long option */
int has_arg; /* one of the above macros */
int* flag; /* determines if getopt_long() returns a
* value for a long option; if it is
* non-NULL, 0 is returned as a function
* value and the value of val is stored in
* the area pointed to by flag. Otherwise,
* val is returned. */
int val; /* determines the value to return if flag is
* NULL. */
} GETOPT_LONG_OPTION_T;

typedef GETOPT_LONG_OPTION_T option;

#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif

/* externally-defined variables */
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
/* externally-defined variables */
extern char* optarg;
extern int optind;
extern int opterr;
extern int optopt;

/* function prototypes */
#ifndef _AIX
int getopt (int argc, char **argv, char *optstring);
/* function prototypes */
#if !defined(linux) && !defined(APPLE)

Choose a reason for hiding this comment

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

That would be great to have one or two sentences that explains the reason of modification here.

We're curious why the code style of this file changed a lot too..

int getopt(int argc, char** argv, char* optstring);
#endif
int getopt_long (int argc, char **argv, const char *shortopts,
const GETOPT_LONG_OPTION_T * longopts, int *longind);
int getopt_long_only (int argc, char **argv, const char *shortopts,
const GETOPT_LONG_OPTION_T * longopts, int *longind);
int getopt_long(int argc, char** argv, const char* shortopts,
const GETOPT_LONG_OPTION_T* longopts, int* longind);
int getopt_long_only(int argc, char** argv, const char* shortopts,
const GETOPT_LONG_OPTION_T* longopts, int* longind);

#ifdef __cplusplus
};
Expand Down
Loading