Hi all,

I recently tried tup in a reasonably complex scenario. Building consists of:

* building a custom generation tool
* running the tool to generate headers
* compiling the source (a mix of generated & "original" files)
* inter project dependencies
* multiple build variants

I was pleasantly surprised that tup does a pretty good job of it! It leaves 
the source tree pristine and although the errors are quite terse, it's good 
to be strict.

On the bad side, I wasted a bit of time trying to get things to work using 
the builtin syntax before abandoning it and outputting rules directly.

Interestingly, as soon as I used the run command, my tupfiles were almost 
empty. I suspect this will be the case for a lot of people since for cross 
platform development, the rules/config is stored somewhere else and 
makefiles/tupfiles etc are generated from them. In the case of tup, is 
there any need to have Tupfiles at all? I didn't have any luck getting tup 
to generate tupfiles on the fly, but that's exactly what would be wonderful 
- the equivalent of "run" except that it outputs pairs of (source folder, 
tup rule generator).

Thoughts?
Stephen.

PS. Since the source is so small, I include it below. Comments in 
bin/list-tup-rules show how it works. I'd love for this to be added to the 
tutorial.

diff -Naur a/bin/generate.in b/bin/generate.in
--- a/bin/generate.in 1970-01-01 01:00:00.000000000 +0100
+++ b/bin/generate.in 2014-04-03 15:18:55.216254329 +0100
@@ -0,0 +1,9 @@
+#! /usr/bin/env python
+
+import sys
+
+for arg in sys.argv[1:]:
+ stem = arg.rsplit(".",1)[0]
+ open(arg).read()
+ open("_Auto/%s.inl"%stem,"w").write("// %s" % arg)
+
diff -Naur a/bin/list-tup-rules b/bin/list-tup-rules
--- a/bin/list-tup-rules 1970-01-01 01:00:00.000000000 +0100
+++ b/bin/list-tup-rules 2014-04-03 16:58:22.074471065 +0100
@@ -0,0 +1,59 @@
+#! /usr/bin/env python
+
+import os
+import sys
+
+def find_inputs(top):
+ headers = []
+ source = []
+ for where,dirs,files in os.walk(top):
+ for f in files:
+ p = os.path.normpath(os.path.join(where,f))
+ if p.endswith(".h"):
+ headers.append( p )
+ if p.endswith(".cpp"):
+ source.append( p )
+ return headers,source
+
+def main():
+ # argv[1] == "lib" or "exe"
+ # argv[2:] is the list of dependent projects (assumed libs to link 
against)
+ project_type = sys.argv[1]
+ dependencies =  [os.path.normpath(p) for p in sys.argv[2:]]
+
+ # find source
+ headers, source = find_inputs(".")
+
+ # it would be nice if there was a variable for the root dir
+ pathtobin = os.path.relpath(os.path.dirname(__file__), os.getcwd())
+
+ # output rules to generate inl files from each header
+ # they are grouped in <AutoGen>
+ if len(headers):
+ print ": %s | %s/generate |> %s/generate %%f |> %s | <AutoGen>" % (
+ " ".join(headers), pathtobin, pathtobin, " 
".join("_Auto/%s.inl"%h.rsplit(".",1)[0] for h in headers))
+
+ # cpp files get compiled. wait for autogen to finish before starting 
compilation.
+ # If we depend on other projects, we depend on their autogen also.
+ # dependencies get added to the include path also
+ for src in source:
+ autogen_deps = " ".join("%s/<AutoGen>" % d for d in dependencies)
+ include_deps = " ".join("-I%s" % d for d in dependencies)
+ print ": %s | <AutoGen> %s |> ^ CC  %%f^ @(CXX) @(CXXFLAGS) %s -c %%f -o 
%%o |> %s.o" % (
+ src, autogen_deps, include_deps, src.rsplit(".",1)[0] )
+
+ # Put all "final" outputs into the bin directory
+ project_name = os.path.basename(os.getcwd())
+
+ if project_type=="lib":
+ # Each lib also defines a group <Built> which other projects depend on.
+ # This hides some cross-platform issues (libfoo.a, foo.lib) and allows 
post-build steps
+ print ": *.o |> ^ AR %%o^ @(AR) %%o %%f |> %s/lib%s.a | <Built>" % 
(pathtobin, project_name)
+
+ elif project_type=="exe":
+ # Executables depend on the <Built> node of their dependencies
+ build_deps = " ".join("%s/<Built>" % d for d in dependencies)
+ linkflags = ("-L%s " % pathtobin) + (" ".join("-l%s" % 
os.path.basename(d) for d in dependencies))
+ print ": *.o | %s |> ^ LINK %%o^ @(LINK) -o %%o %%f %s |> %s/%s | 
<Built>" % (build_deps, linkflags, pathtobin, project_name)
+
+main()
diff -Naur a/bin/Tupfile b/bin/Tupfile
--- a/bin/Tupfile 1970-01-01 01:00:00.000000000 +0100
+++ b/bin/Tupfile 2014-04-03 16:11:06.935345669 +0100
@@ -0,0 +1,4 @@
+
+# 'Compile' a generator tool
+: generate.in |> cp %f %o |> generate
+
diff -Naur a/build-debug/tup.config b/build-debug/tup.config
--- a/build-debug/tup.config 1970-01-01 01:00:00.000000000 +0100
+++ b/build-debug/tup.config 2014-04-03 16:54:55.730474102 +0100
@@ -0,0 +1,4 @@
+CONFIG_CXXFLAGS=-O0
+CONFIG_CXX=g++
+CONFIG_LINK=g++
+CONFIG_AR=ar crs
diff -Naur a/build-release/tup.config b/build-release/tup.config
--- a/build-release/tup.config 1970-01-01 01:00:00.000000000 +0100
+++ b/build-release/tup.config 2014-04-03 16:54:55.734474169 +0100
@@ -0,0 +1,4 @@
+CONFIG_CXXFLAGS=-O3
+CONFIG_CXX=g++
+CONFIG_LINK=g++
+CONFIG_AR=ar crs
diff -Naur a/exe1/exe1.cpp b/exe1/exe1.cpp
--- a/exe1/exe1.cpp 1970-01-01 01:00:00.000000000 +0100
+++ b/exe1/exe1.cpp 2014-04-03 16:16:30.815340483 +0100
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include "square.h"
+
+int main()
+{
+ printf("Exe1 says five squared is: %i\n", square(5));
+ return 0;
+}
diff -Naur a/exe1/Tupfile b/exe1/Tupfile
--- a/exe1/Tupfile 1970-01-01 01:00:00.000000000 +0100
+++ b/exe1/Tupfile 2014-04-03 16:19:12.295338178 +0100
@@ -0,0 +1 @@
+run ../bin/list-tup-rules exe ../source/base
diff -Naur a/exe2/hello.cpp b/exe2/hello.cpp
--- a/exe2/hello.cpp 1970-01-01 01:00:00.000000000 +0100
+++ b/exe2/hello.cpp 2014-04-03 16:18:01.047339258 +0100
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "square.h"
+#include "util.h"
+
+int main()
+{
+ printf("Exe2 says %i ^ 2 == %i\n", MAGIC_NUMBER, square(MAGIC_NUMBER));
+ return 0;
+}
diff -Naur a/exe2/Tupfile b/exe2/Tupfile
--- a/exe2/Tupfile 1970-01-01 01:00:00.000000000 +0100
+++ b/exe2/Tupfile 2014-04-03 16:19:19.343338484 +0100
@@ -0,0 +1 @@
+run ../bin/list-tup-rules exe ../source/base ../source/util
diff -Naur a/source/base/square.cpp b/source/base/square.cpp
--- a/source/base/square.cpp 1970-01-01 01:00:00.000000000 +0100
+++ b/source/base/square.cpp 2014-03-31 11:49:40.678432005 +0100
@@ -0,0 +1,7 @@
+#include "square.h"
+#include "tri.h"
+
+int square(int x)
+{
+ return x * x;
+}
diff -Naur a/source/base/square.h b/source/base/square.h
--- a/source/base/square.h 1970-01-01 01:00:00.000000000 +0100
+++ b/source/base/square.h 2014-03-31 12:48:15.974017764 +0100
@@ -0,0 +1,5 @@
+// SQUARE
+
+int square(int x);
+
+#include "_Auto/square.inl"
diff -Naur a/source/base/tri.h b/source/base/tri.h
--- a/source/base/tri.h 1970-01-01 01:00:00.000000000 +0100
+++ b/source/base/tri.h 2014-04-01 10:55:52.697303647 +0100
@@ -0,0 +1,4 @@
+
+int tri();
+
+#include "_Auto/tri.inl"
diff -Naur a/source/base/Tupfile b/source/base/Tupfile
--- a/source/base/Tupfile 1970-01-01 01:00:00.000000000 +0100
+++ b/source/base/Tupfile 2014-04-03 16:19:37.015336990 +0100
@@ -0,0 +1,2 @@
+run ../../bin/list-tup-rules lib
+
diff -Naur a/source/util/Tupfile b/source/util/Tupfile
--- a/source/util/Tupfile 1970-01-01 01:00:00.000000000 +0100
+++ b/source/util/Tupfile 2014-04-03 16:19:44.727337716 +0100
@@ -0,0 +1 @@
+run ../../bin/list-tup-rules lib
diff -Naur a/source/util/util.h b/source/util/util.h
--- a/source/util/util.h 1970-01-01 01:00:00.000000000 +0100
+++ b/source/util/util.h 2014-04-03 16:59:37.338470137 +0100
@@ -0,0 +1,4 @@
+
+#define MAGIC_NUMBER 4
+
+#include "_Auto/util.inl"

-- 
-- 
tup-users mailing list
email: [email protected]
unsubscribe: [email protected]
options: http://groups.google.com/group/tup-users?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"tup-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to