Skip to content

Commit 0f3bc39

Browse files
tobil4skyuxiaomao
andauthored
[hlc] Implement automatic compilation with make and Build.xml templates (#706)
* Add Makefile hlc template * Add hxcpp Build.xml hlc template * Automate Makefile and Build.xml template builds * Fix header file check when hlgen.makefilepath is set * Avoid duplicate slashes in paths in hlc templates * Avoid passing -std=c11 on MSVC in build.xml * Add HASHLINK variable based paths in Build.xml * Support debug builds with Build.xml template * Improve makefile template Use LDLIBS for passing libraries to the linker: https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html#index-LDLIBS Compile .c files into separate .o files to avoid recompiling the entire project every time. Use .d files to keep track of .c files that depend on .h files. For reference: https://stackoverflow.com/a/52036564 * Add warning about auto generated makefile * Add mingw support for makefile template * Fix include path in generated makefile for mingw For some reason, mingw doesn't like `-I./`, this causes it to be unable to find the includes * Keep makefile tmp files within hlgen.makefilepath Previously it would always generate them next to the .c files, regardless of whether hlgen.makefilepath had been set. Now it ensures that it doesn't write outside of the Makefile directory. This means that it first has to create the directories, otherwise the compiler complains about directories not existing when it tries to write the output files. ".SUFFIXES" also has to be set as an empty target, otherwise the built- in rules mess up the rule dependencies. * Allow HASHLINK for makefile template on linux/mac * Simplify mingw flags for makefile template * Let vs2019, vs2022 template build with makefile provided * Makefile: generate separate linking flags for mac * Add hlgen.makefile suggestion based on systemName --------- Co-authored-by: Yuxiao Mao <[email protected]>
1 parent 2834237 commit 0f3bc39

File tree

3 files changed

+120
-21
lines changed

3 files changed

+120
-21
lines changed

other/haxelib/Run.hx

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ class Build {
22

33
var output : String;
44
var name : String;
5+
var sourcesDir : String;
56
var targetDir : String;
67
var dataPath : String;
78
var config : {
@@ -17,17 +18,36 @@ class Build {
1718
this.dataPath = dataPath;
1819
var path = new haxe.io.Path(output);
1920
this.name = path.file;
20-
this.targetDir = path.dir+"/";
21+
this.sourcesDir = path.dir+"/";
22+
this.targetDir = this.sourcesDir;
2123
}
2224

25+
function log(message:String) {
26+
if( config.defines.get("hlgen.silent") == null )
27+
Sys.println(message);
28+
}
29+
30+
2331
public function run() {
2432
var tpl = config.defines.get("hlgen.makefile");
2533
if( tpl != null )
2634
generateTemplates(tpl);
27-
if( config.defines.get("hlgen.silent") == null )
28-
Sys.println("Code generated in "+output+" automatic native compilation not yet implemented");
35+
log('Code generated in $output');
36+
switch tpl {
37+
case "make":
38+
Sys.command("make", ["-C", targetDir]);
39+
case "hxcpp":
40+
Sys.command("haxelib", ["--cwd", targetDir, "run", "hxcpp", "Build.xml"].concat(config.defines.exists("debug") ? ["-Ddebug"] : []));
41+
case "vs2019", "vs2022":
42+
Sys.command("make", ["-C", targetDir]);
43+
case null:
44+
var suggestion = (Sys.systemName() == "Windows") ? "vs2019" : "make";
45+
log('Set -D hlgen.makefile=${suggestion} for automatic native compilation');
46+
case unimplemented:
47+
log('Automatic native compilation not yet implemented for $unimplemented');
48+
}
2949
}
30-
50+
3151
function isAscii( bytes : haxe.io.Bytes ) {
3252
// BOM CHECK
3353
if( bytes.length > 3 && bytes.get(0) == 0xEF && bytes.get(1) == 0xBB && bytes.get(2) == 0xBF )
@@ -36,7 +56,7 @@ class Build {
3656
var len = bytes.length;
3757
while( i < len ) {
3858
var c = bytes.get(i++);
39-
if( c == 0 || c >= 0x80 ) return false;
59+
if( c == 0 || c >= 0x80 ) return false;
4060
}
4161
return true;
4262
}
@@ -45,22 +65,20 @@ class Build {
4565
if( tpl == null || tpl == "1" )
4666
tpl = "vs2015";
4767
var srcDir = tpl;
48-
var targetDir = config.defines.get("hlgen.makefilepath");
4968
var jumboBuild = config.defines.get("hlgen.makefile.jumbo");
5069
var relDir = "";
51-
if( targetDir == null )
52-
targetDir = this.targetDir;
53-
else {
70+
if( config.defines["hlgen.makefilepath"] != null ) {
71+
targetDir = config.defines.get("hlgen.makefilepath");
5472
if( !StringTools.endsWith(targetDir,"/") && !StringTools.endsWith(targetDir,"\\") )
5573
targetDir += "/";
74+
var sourcesAbs = sys.FileSystem.absolutePath(sourcesDir);
5675
var targetAbs = sys.FileSystem.absolutePath(targetDir);
57-
var currentAbs = sys.FileSystem.absolutePath(this.targetDir);
58-
if( !StringTools.startsWith(currentAbs, targetAbs+"/") )
59-
relDir = currentAbs+"/"; // absolute
60-
else
61-
relDir = currentAbs.substr(targetAbs.length+1);
76+
if( !StringTools.startsWith(sourcesAbs, targetAbs+"/") )
77+
relDir = sourcesAbs+"/"; // absolute
78+
else
79+
relDir = sourcesAbs.substr(targetAbs.length+1);
6280
relDir = relDir.split("\\").join("/");
63-
if( relDir != "" )
81+
if( !(relDir == "" || StringTools.endsWith(relDir, "/")) )
6482
relDir += "/";
6583
}
6684
if( !sys.FileSystem.exists(srcDir) ) {
@@ -76,7 +94,7 @@ class Build {
7694
for( f in config.files )
7795
if( StringTools.endsWith(f,".c") ) {
7896
var h = f.substr(0,-2) + ".h";
79-
if( sys.FileSystem.exists(targetDir+h) )
97+
if( sys.FileSystem.exists(sourcesDir+h) )
8098
allFiles.push(h);
8199
}
82100
allFiles.sort(Reflect.compare);
@@ -98,7 +116,7 @@ class Build {
98116

99117
var directories = [for( k in directories.keys() ) { path : k }];
100118
directories.sort(function(a,b) return Reflect.compare(a.path,b.path));
101-
119+
102120
function genRec( path : String ) {
103121
var dir = srcDir + "/" + path;
104122
for( f in sys.FileSystem.readDirectory(dir) ) {
@@ -143,7 +161,7 @@ class Build {
143161
return sha1.substr(0,8)+"-"+sha1.substr(8,4)+"-"+sha1.substr(12,4)+"-"+sha1.substr(16,4)+"-"+sha1.substr(20,12);
144162
},
145163
makePath : function(_,dir:String) {
146-
return dir == "" ? "./" : (StringTools.endsWith(dir,"/") || StringTools.endsWith(dir,"\\")) ? dir : dir + "/";
164+
return dir == "" ? "." : (StringTools.endsWith(dir,"/") || StringTools.endsWith(dir,"\\")) ? dir : dir + "/";
147165
},
148166
upper : function(_,s:String) {
149167
return s.charAt(0).toUpperCase() + s.substr(1);
@@ -172,7 +190,7 @@ class Run {
172190
var originalPath = args.pop();
173191
var haxelibPath = Sys.getCwd()+"/";
174192
Sys.setCwd(originalPath);
175-
193+
176194
switch( args.shift() ) {
177195
case "build":
178196
var output = args.shift();
@@ -183,11 +201,11 @@ class Run {
183201
new Build(haxelibPath,output,config).run();
184202
case "run":
185203
var output = args.shift();
186-
if( StringTools.endsWith(output,".c") ) return;
204+
if( StringTools.endsWith(output,".c") ) return;
187205
Sys.command("hl "+output);
188206
case cmd:
189207
Sys.println("Unknown command "+cmd);
190208
Sys.exit(1);
191209
}
192210
}
193-
}
211+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<xml>
2+
<files id="::name::">
3+
<compilerflag value="-std=c11" unless="MSVC_VER" />
4+
<compilerflag value="-DHL_MAKE" />
5+
<compilerflag value="-I$$makePath(::relDir::)" />
6+
<compilerflag value="-I${HASHLINK}/src" if="HASHLINK" />
7+
<compilerflag value="-I${HASHLINK}/include" if="HASHLINK" />
8+
::foreach hfiles::
9+
<depend name="::relDir::::path::" />::end::
10+
::foreach cfiles::
11+
<file name="::relDir::::path::" />::end::
12+
</files>
13+
14+
<set name="ARCH_DIR" value="/x64" if="HXCPP_M64" />
15+
16+
<target id="default" output="::name::" tool="linker" toolid="exe">
17+
<files id="::name::" />
18+
19+
<libpath name="${HASHLINK}" if="HASHLINK" />
20+
<libpath name="${HASHLINK}/lib" if="HASHLINK" />
21+
22+
<section unless="windows">
23+
<lib name="-lhl" />
24+
<lib name="-lm" />
25+
<lib name="-luv" />
26+
::foreach libraries::
27+
<lib name="-l:::name::.hdll" />::end::
28+
</section>
29+
30+
<section if="windows">
31+
<libpath name="${HASHLINK}${ARCH_DIR}/Debug" if="debug HASHLINK" />
32+
<libpath name="${HASHLINK}${ARCH_DIR}/Release" if="HASHLINK" unless="debug" />
33+
34+
<lib name="libhl.lib" />
35+
::foreach libraries::
36+
<lib name="::name::.lib" />::end::
37+
</section>
38+
</target>
39+
</xml>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Auto-generated from hashlink's Makefile template; do not edit
2+
3+
UNAME := $(shell uname)
4+
CFLAGS=-O3 -std=c11 -DHL_MAKE -I$$makePath(::relDir::)
5+
ifeq ($(UNAME),Darwin)
6+
LDLIBS=-lhl -lm -luv::foreach libraries:: /usr/local/lib/::name::.hdll::end::
7+
else
8+
LDLIBS=-lhl -lm -luv::foreach libraries:: -l:::name::.hdll::end::
9+
endif
10+
11+
ifdef HASHLINK
12+
CFLAGS+=-I$(HASHLINK)/include -I$(HASHLINK)/src
13+
LDFLAGS+=-L$(HASHLINK)/lib -L$(HASHLINK)
14+
endif
15+
16+
ifeq ($(OS),Windows_NT)
17+
LDFLAGS+=-municode
18+
LDLIBS+=-ldbghelp
19+
EXE_SUFFIX=.exe
20+
endif
21+
22+
SRC_FILES=::foreach cfiles:: \
23+
::path::::end::
24+
25+
OBJ_FILES=$(patsubst %.c,%.o,$(SRC_FILES))
26+
27+
DEP_FILES=$(patsubst %.c,%.d,$(SRC_FILES))
28+
29+
::name::$(EXE_SUFFIX): $(OBJ_FILES)
30+
$(CC) $(OBJ_FILES) -o $@ $(LDFLAGS) $(LDLIBS)
31+
32+
-include $(DEP_FILES)
33+
34+
%.o:
35+
@mkdir -p $(dir $@)
36+
$(CC) $(CFLAGS) -MMD -MP -c ::relDir::$*.c -o $@
37+
38+
clean:
39+
find . \( -name '*.o' -o -name '*.d' \) -delete
40+
rm ::name::$(EXE_SUFFIX)
41+
42+
.SUFFIXES:

0 commit comments

Comments
 (0)