Skip to content

Commit 3d343c9

Browse files
authored
Merge pull request #277 from avinxshKD/refactor-tool-paths-247
2 parents ed98e3b + aac87c9 commit 3d343c9

3 files changed

Lines changed: 131 additions & 10 deletions

File tree

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ concore stop
5757

5858
For detailed CLI documentation, see [concore_cli/README.md](concore_cli/README.md).
5959

60+
## Configuration
61+
62+
_concore_ supports customization through configuration files in the `CONCOREPATH` directory (defaults to the _concore_ installation directory):
63+
64+
- **concore.tools** - Override tool paths (one per line, `KEY=value` format):
65+
```
66+
CPPEXE=/usr/local/bin/g++-12
67+
PYTHONEXE=/usr/bin/python3.11
68+
VEXE=/opt/iverilog/bin/iverilog
69+
OCTAVEEXE=/snap/bin/octave
70+
```
71+
Supported keys: `CPPWIN`, `CPPEXE`, `VWIN`, `VEXE`, `PYTHONEXE`, `PYTHONWIN`, `MATLABEXE`, `MATLABWIN`, `OCTAVEEXE`, `OCTAVEWIN`
72+
73+
- **concore.octave** - Treat `.m` files as Octave instead of MATLAB (presence = enabled)
74+
- **concore.mcr** - MATLAB Compiler Runtime path (single line)
75+
- **concore.sudo** - Docker command override (e.g., `docker` instead of `sudo docker`)
76+
- **concore.repo** - Docker repository override
77+
78+
Tool paths can also be set via environment variables (e.g., `CONCORE_CPPEXE=/usr/bin/g++`). Priority: config file > env var > defaults.
79+
6080
For a detailed and more scientific documentation, please read our extensive [open-access research paper on CONTROL-CORE](https://doi.org/10.1109/ACCESS.2022.3161471). This paper has a complete discussion on the CONTROL-CORE architecture and deployment, together with the commands to execute the studies in different programming languages and programming environments (Ubuntu, Windows, MacOS, Docker, and distributed execution).
6181

6282

mkconcore.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ def safe_name(value, context, allow_path=False):
9797

9898
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
9999

100+
def _load_tool_config(filepath):
101+
tools = {}
102+
with open(filepath, "r") as f:
103+
for line in f:
104+
line = line.strip()
105+
if not line or line.startswith("#") or "=" not in line:
106+
continue
107+
k, v = line.split("=", 1)
108+
k, v = k.strip(), v.strip()
109+
if v:
110+
tools[k] = v
111+
return tools
112+
100113
def _resolve_concore_path():
101114
script_concore = os.path.join(SCRIPT_DIR, "concore.py")
102115
if os.path.exists(script_concore):
@@ -109,16 +122,16 @@ def _resolve_concore_path():
109122
GRAPHML_FILE = sys.argv[1]
110123
TRIMMED_LOGS = True
111124
CONCOREPATH = _resolve_concore_path()
112-
CPPWIN = "g++" #Windows C++ 6/22/21
113-
CPPEXE = "g++" #Ubuntu/macOS C++ 6/22/21
114-
VWIN = "iverilog" #Windows verilog 6/25/21
115-
VEXE = "iverilog" #Ubuntu/macOS verilog 6/25/21
116-
PYTHONEXE = "python3" #Ubuntu/macOS python3
117-
PYTHONWIN = "python" #Windows python3
118-
MATLABEXE = "matlab" #Ubuntu/macOS matlab
119-
MATLABWIN = "matlab" #Windows matlab
120-
OCTAVEEXE = "octave" #Ubuntu/macOS octave
121-
OCTAVEWIN = "octave" #Windows octave
125+
CPPWIN = os.environ.get("CONCORE_CPPWIN", "g++") #Windows C++ 6/22/21
126+
CPPEXE = os.environ.get("CONCORE_CPPEXE", "g++") #Ubuntu/macOS C++ 6/22/21
127+
VWIN = os.environ.get("CONCORE_VWIN", "iverilog") #Windows verilog 6/25/21
128+
VEXE = os.environ.get("CONCORE_VEXE", "iverilog") #Ubuntu/macOS verilog 6/25/21
129+
PYTHONEXE = os.environ.get("CONCORE_PYTHONEXE", "python3") #Ubuntu/macOS python3
130+
PYTHONWIN = os.environ.get("CONCORE_PYTHONWIN", "python") #Windows python3
131+
MATLABEXE = os.environ.get("CONCORE_MATLABEXE", "matlab") #Ubuntu/macOS matlab
132+
MATLABWIN = os.environ.get("CONCORE_MATLABWIN", "matlab") #Windows matlab
133+
OCTAVEEXE = os.environ.get("CONCORE_OCTAVEEXE", "octave") #Ubuntu/macOS octave
134+
OCTAVEWIN = os.environ.get("CONCORE_OCTAVEWIN", "octave") #Windows octave
122135
M_IS_OCTAVE = False #treat .m as octave
123136
MCRPATH = "~/MATLAB/R2021a" #path to local Ubunta Matlab Compiler Runtime
124137
DOCKEREXE = "sudo docker"#assume simple docker install
@@ -147,6 +160,18 @@ def _resolve_concore_path():
147160
with open(CONCOREPATH+"/concore.repo", "r") as f:
148161
DOCKEREPO = f.readline().strip() #docker id for repo
149162

163+
if os.path.exists(CONCOREPATH+"/concore.tools"):
164+
_tools = _load_tool_config(CONCOREPATH+"/concore.tools")
165+
CPPWIN = _tools.get("CPPWIN", CPPWIN)
166+
CPPEXE = _tools.get("CPPEXE", CPPEXE)
167+
VWIN = _tools.get("VWIN", VWIN)
168+
VEXE = _tools.get("VEXE", VEXE)
169+
PYTHONEXE = _tools.get("PYTHONEXE", PYTHONEXE)
170+
PYTHONWIN = _tools.get("PYTHONWIN", PYTHONWIN)
171+
MATLABEXE = _tools.get("MATLABEXE", MATLABEXE)
172+
MATLABWIN = _tools.get("MATLABWIN", MATLABWIN)
173+
OCTAVEEXE = _tools.get("OCTAVEEXE", OCTAVEEXE)
174+
OCTAVEWIN = _tools.get("OCTAVEWIN", OCTAVEWIN)
150175

151176
prefixedgenode = ""
152177
sourcedir = sys.argv[2]

tests/test_tool_config.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import pytest
2+
import os
3+
4+
# can't import mkconcore directly (sys.argv at module level), so we duplicate the parser
5+
def _load_tool_config(filepath):
6+
tools = {}
7+
with open(filepath, "r") as f:
8+
for line in f:
9+
line = line.strip()
10+
if not line or line.startswith("#") or "=" not in line:
11+
continue
12+
k, v = line.split("=", 1)
13+
k, v = k.strip(), v.strip()
14+
if v:
15+
tools[k] = v
16+
return tools
17+
18+
19+
class TestLoadToolConfig:
20+
21+
def test_basic_overrides(self, temp_dir):
22+
cfg = os.path.join(temp_dir, "concore.tools")
23+
with open(cfg, "w") as f:
24+
f.write("CPPEXE=/usr/local/bin/g++-12\n")
25+
f.write("PYTHONEXE=/usr/bin/python3.11\n")
26+
27+
tools = _load_tool_config(cfg)
28+
assert tools["CPPEXE"] == "/usr/local/bin/g++-12"
29+
assert tools["PYTHONEXE"] == "/usr/bin/python3.11"
30+
assert "VEXE" not in tools
31+
32+
def test_comments_and_blanks_ignored(self, temp_dir):
33+
cfg = os.path.join(temp_dir, "concore.tools")
34+
with open(cfg, "w") as f:
35+
f.write("# custom tool paths\n")
36+
f.write("\n")
37+
f.write("OCTAVEEXE = /snap/bin/octave\n")
38+
f.write("# MATLABEXE = /opt/matlab/bin/matlab\n")
39+
40+
tools = _load_tool_config(cfg)
41+
assert tools["OCTAVEEXE"] == "/snap/bin/octave"
42+
assert "MATLABEXE" not in tools
43+
44+
def test_empty_value_skipped(self, temp_dir):
45+
cfg = os.path.join(temp_dir, "concore.tools")
46+
with open(cfg, "w") as f:
47+
f.write("CPPWIN=\n")
48+
f.write("VEXE = \n")
49+
50+
tools = _load_tool_config(cfg)
51+
assert "CPPWIN" not in tools
52+
assert "VEXE" not in tools
53+
54+
def test_value_with_equals_sign(self, temp_dir):
55+
cfg = os.path.join(temp_dir, "concore.tools")
56+
with open(cfg, "w") as f:
57+
f.write("CPPEXE=C:\\Program Files\\g++=fast\n")
58+
59+
tools = _load_tool_config(cfg)
60+
assert tools["CPPEXE"] == "C:\\Program Files\\g++=fast"
61+
62+
def test_whitespace_around_key_value(self, temp_dir):
63+
cfg = os.path.join(temp_dir, "concore.tools")
64+
with open(cfg, "w") as f:
65+
f.write(" VWIN = C:\\iverilog\\bin\\iverilog.exe \n")
66+
67+
tools = _load_tool_config(cfg)
68+
assert tools["VWIN"] == "C:\\iverilog\\bin\\iverilog.exe"
69+
70+
def test_empty_file(self, temp_dir):
71+
cfg = os.path.join(temp_dir, "concore.tools")
72+
with open(cfg, "w") as f:
73+
pass
74+
75+
tools = _load_tool_config(cfg)
76+
assert tools == {}

0 commit comments

Comments
 (0)