Sublime Forum

Am I missing a trick? Build Systems

#1

Here is a screen shot of all the build systems I have. I actually have double to triple that amount.
(There’s builds for various versions of G++, SDL2, GMP and of course all the combinations of the afore mentioned)


(Taking a screen shot of this was a bit tricky, because as soon as I move the cursor, whoosh all the menu’s disappear, so apols for crappiness.)

This is smacking of inefficency and Smell (I think), so this leads me to the conclusion I’m missing a trick ?

If I am, please don’t recommend a youtube vid (I know @OdatNurd produces some great stuff) but I’ve had to ban myself from youtube, (and guess what my productivity has gone up loads). If you can point me in the direction of the written word that’d be awesome.

Live long and prosper, Loz :unicorn::skull_and_crossbones:

0 Likes

Building with Make, Regex and F4
#2

Can you explain what is inefficient here ? It’s just listing all of the build systems.

0 Likes

#3

You’re missing a C++ build system.

If you want to learn Rust, you have to understand its build system Cargo.
If you want to learn Java, you have to understand one of the build systems Maven or Gradle.
If you want to write a web app, you have a choice for many kinds of build systems (e.g. webpack)

Similarly for C++, there are a few choices for a build system:

  • Plain Makefiles
  • Xcode project files
  • Visual Studio project files
  • Bazel
  • Meson
  • CMake

Of these choices, I would recommend CMake as I have good experiences with it.
You can then write a general Sublime build system that wraps around your chosen C++ build system.

1 Like

#4

I don’t mean to imply the ST3 is doing anything wrong, more that I am. I’m wondering if there’s some unkown part of ST3 (to me) that allows me to say pass some arguments to the build system, or have some kind of nested arragement. The problem is I don’t know what I don’t know. Is that how other C++ programmers have their build systems organised ? Do they have a build system for every possible combination of libraries, flags, optimisations etc etc?

Just firing from the hip here, is it possible to have some thing like (and I hoping here folks might be able to take a little leap of imagination with me with this) you could put build systems together on the fly specifying some arguments ? Some kind of nesting maybe?(That’s a makefile, but i’ve got loads of those for various different flags, options etc) It just seems ineficient when all the build systems are nearly the same…

To a coder (not that I’d really consider myself one)(in any language) this would be (not smell sorry I got my terms muddled) very WET ie not DRY.

If this is how the ST experts have their build systems organised, or this is how they use ST then so be it, I was just wondering if I’d missed something to save me a bit of time/space (As I’ve got to scroll through tens of build systems everytime I do something different/debug)
Hopefully this is a bit clearer…
:grinning:

0 Likes

#5

I’m using make (I though I’d start somewhere), but then I’ve got different makefiles for different scenarious…Is it possible to avoid that, or at least reduce the quantity of makefiles?

I sense progress ! :star_struck:

0 Likes

#6

The usual layout of a Makefile is that the very first rule in the file is called all. It is a .PHONY rule that is supposed to “build everything”. If you ensure that that is the case in your Makefile, you can use the “Make” ST build system to run make when you press ctrl+B.

0 Likes

#7

If you really need to build your code with 20 or 30 possible permutations, I doubt you’re going to be able to come up with a way to trigger that without being prompted somewhere to choose which of the 30 is the one you want to use right now.

Personally, if I had that sort of situation I would make a single build system with variants in it, since likely the only thing that’s changing is the command line and most everything else is the same. Then a Build With will prompt you for the one to use, and it will keep using that one until you tell it to pick another one by using Build With again.

Alternately you could have a custom target using a plugin that prompts you for build variables before it executes the build without too much effort. Arguably, being prompted for every build is way more disruptive than just picking it once from the menu or the variant panel though.

I have videos on all of those topics, which I’m not going to link here for your stated reasons above. In any case, I would agree with @rwols that what you want is some sort of extra external build tool to make your life better overall.

Any time switching from one project to another requires you to rewrite a sublime-build file, that’s a signal that you’re probably thinking about things the wrong way. The instructions on how to build and run any particular project or file should be stored with that project and not as a configuration in your editor.

For this example, presume the use of make as a tool (which is just one of many). For any particular project, you create a control file that tells make exactly what steps to take, in what order, to compile, build, and/or run your code, as well as any other things you need.

For every project you create one, and then you just need a single sublime-build that knows how to interface with that tool:

{
	"shell_cmd": "make",
	"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
	"working_dir": "${folder:${project_path:${file_path}}}",
	"selector": "source.makefile",
	"syntax": "Packages/Makefile/Make Output.sublime-syntax",
	"keyfiles": ["Makefile", "makefile"],

	"variants":
	[
		{
			"name": "Clean",
			"shell_cmd": "make clean"
		}
	]
}

So, by default it invokes make, which finds the control file and does what it needs to do, and you can optionally get it to trigger a clean. One single build, works for every project. And as an added benefit, your code projects also contain the instructions needed to build them, so if you share them with someone else there’s no mystery.

Or as another example, for dotnet related programs I use this build:

{
    "working_dir": "${folder:${project_path:${file_path}}}",
    "selector": "source.cs",

    "variants":
    [
        {
            "name": "Build",
            "shell_cmd": "dotnet build",
            "word_wrap": false,
            "quiet": true,
        },
        {
            "name": "Clean",
            "shell_cmd": "dotnet clean"
        },
        {
            "name": "Run",
            "shell_cmd": "dotnet run"
        },
        {
            "name": "Run Interactive",
            "shell_cmd": "dotnet run",
            "target": "terminus_exec"
        }
    ],
}

So, no matter what dotnet project I’m in, this one single configured build works. I can just compile, clean up artifacts, build and then run, and even run interactively.

1 Like

#8

Ah ha, ah ha ha, ah ha ha ah ha ! I was wondering what build with did, that looks just like the ticket. Still late at my end and another wonderful answer ! Will digest and get back to you if I come up with anything (useful which might be postable).

Thanks dude, wicked !

L :unicorn::skull_and_crossbones:

Ps I did watch some of your vids (@OdatNurd) which did mention variants and to be fair these instructions do contain the info; but sometimes I (certainly) suffer from information overload (there’s only so much I can take in, which might not be that much :crazy_face:) so it’s good to have some targeted help. Helps with the motivation too, good to know there are folks willing to help etc. Ta very muchly ! (I’ve gushed enuff) :smiling_face_with_three_hearts:

0 Likes

#9

Haven’t quite gone to bed… Indeed I’m not doing the above, however during development I do need to compile with different flags, libraries (and associated flags); plus clang (for example) gives much nicer error messages than gcc. Also as I update my compilers and knowledge too (Am moving from C++14 to C++17 ish) (and comparing the perfomance of those versions too).
So the final build maybe just one makefile but all the debugging, profiling and general tomfoolery seems to require more than one makefile or a makefile with a lot of options…
Again if I’m making a mistake here (and I appreciate we’re a bit off topic ATM) and someone wants to correct the error of my ways pls do !
Right bed, more later. Again thanks !

0 Likes

Adding "variants" "Breaks" Build System
#10

So after some wrestling, mainly with makefiles I have something for my fellow noobs:
The short answer to the question is:-

“Yes I am missing a trick and that trick is build with the allows me to specialise the build systems.”

Here is an example of a ST3 build system with accompanying makefile:

{
  "cmd" : ["make release --file=makeTestBuildWith.mk -B TARGET=\"$file_base_name\""],
  "selector" : "source.c",
  "shell": true,
  "file_regex":"^(..[^:]*):([0-9]*):([0-9]*): (.*)$",
  "working_dir": "${folder:${project_path:${file_path}}}",
  "syntax": "Packages/Makefile/Make Output.sublime-syntax",
  "variants":
  [
    {
      "name": "G++",
      "shell_cmd": "make release --file=makeTestBuildWith.mk -B CC=g++-7 TARGET=\"$file_base_name\""
    },
    {
      "name": "Clang Debug",
      "shell_cmd": "make debug --file=makeTestBuildWith.mk -B TARGET=\"$file_base_name\""
    },
    {
      "name": "G++ Debug",
      "shell_cmd": "make debug --file=makeTestBuildWith.mk -B CC=g++-7 TARGET=\"$file_base_name\""
    }
  ]
}

And here’s the makefile, makeTestBuildWith.mk

# This variable might be 'overwritten' by a command line arg
CC = clang++-3.8

# Sorting the different flags out for different compilers and modes
ifeq ($(CC),g++-7)
release:CXXFLAGS=-std=c++17 -w -O02
else
release:CXXFLAGS= -std=c++14 -stdlib=libc++ -w -O02
endif

ifeq ($(CC),g++-7)
debug:CXXFLAGS=-std=c++17 -w -O00 -ggdb -DDEBUG
else
debug:CXXFLAGS=-std=c++14 -stdlib=libc++ -w -O00 -ggdb -DDEBUG
endif

# LDFLAGs for -L rather than -l LDFLAGS = ...
LDLIBS = -lSDL2 -lSDL2_image -lc++ -lm -lgcc_s -lgcc -lc

SRCS := $(wildcard *.cpp)
OBJS := $(patsubst %.cpp,%.o,$(SRCS))

debug: $(TARGET)
release:$(TARGET)

%.o: %.cpp
	$(CC) $(CPPFLAGS) $(CXXFLAGS) -c $< ; pwd

$(TARGET): $(OBJS)
	g++-7 $^ $(LDLIBS) -o $@ 

In ST3 I select the build system via Tools => BuildSystem
ctrl+b is the default option (or is it the last build option that was execued ?) which would give me the release build with clang+±3.8 and ctrl+shift+b then gives me a further three options of debug with clang++/g++ or g++ with no debug.

The B flag I’m passing to make is just so that everything builds during testing.

Sorted, thanks @OdatNurd just what I was looking for…

0 Likes