Page 3 of 9

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:00 am
by b.zaar
Wajideu wrote:

Code: Select all

$(MAKE) -C "$(MySubProject_DIR)" all
That's the magic line I was looking for. My idea of make++ would avoid this and also be able to determine if the project needs to be built without another make process being spawned.

Also the script code wouldn't use anything the average C/C++/Java/JavaScript programmer (who uses make) isn't already familar with. It wouldn't be learning a new language.

Code: Select all

PROJECTS   = MySubProject

MySubProject_DIR = My Sub Project

all: $(PROJECTS)

$(PROJECTS):{
    foreach($(MySubProject_DIR), dir){
        include $(dir)
    }
}

I was thinking something like this where the included file could be a traditional Makefile wrapped up in a nice private environment.

I guess all the targets and deps would then be $(dir).target and $(dir).deps for the internal make target: deps table.

There wouldn't be any option other than having make++ installed but then that also applies to cmake, scon etc

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:29 am
by Wajideu
b.zaar wrote:
Wajideu wrote:

Code: Select all

$(MAKE) -C "$(MySubProject_DIR)" all
That's the magic line I was looking for. My idea of make++ would avoid this and also be able to determine if the project needs to be built without another make process being spawned.
Isn't spawning another make process kinda necessary when you're calling a separate makefile? Unless you plan to change the directory and use an include statement, but that's just messy.


I really like the syntax that you use for your make++ idea. As much as I'm advocating not to stray to far from traditional makefiles (as not to cause a huge fuss over projects that may adopt a new build system), I would actually prefer something like that as opposed to everything else that I've worked with. Meh, what that hell. If you don't mind, I'll just help chip in on your idea.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:39 am
by b.zaar
Wajideu wrote:Isn't spawning another make process kinda necessary when you're calling a separate makefile? Unless you plan to change the directory and use an include statement, but that's just messy.
That makes sense... I'll think about how to do it neatly, but off the top of my head maybe make -C becomes a special kind of include that changes directories automatically but doesn't spawn a new process. Either that or there's an include -C comand.

Thinking about it a bit more make -C could do automatic encapsulation for a tradition makefile and some of the {} code blocks wouldn't even be needed.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:42 am
by Wajideu
b.zaar wrote:Thinking about it a bit more make -C could do automatic encapsulation for a tradition makefile and some of the {} code blocks wouldn't even be needed.
That's actually what I did before in the example I showed you:

Code: Select all

all-MyPlan:
   $(MAKE) -f $(lastword $(MAKEFILE_LIST)) build-MyPlan RULE=MyPlan


ifeq ($(RULE),MyPlan)
STEPS = MyStep1

SRCS = main.c

build-MyPlan: $(addprefix --MyPlan-,$(STEPS))
   @echo plan complete
--MyPlan-MyStep1:
   @echo step 1 complete
endif

EDIT:
Maybe we could get a little collaboration going on. I don't really have any specific details in mind regarding the format of Planfile atm; I'm just winging it; and your idea for make++ seems pretty well structured.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:47 am
by b.zaar
Wajideu wrote:
b.zaar wrote:Thinking about it a bit more make -C could do automatic encapsulation for a tradition makefile and some of the {} code blocks wouldn't even be needed.
That's actually what I did before in the example I showed you:

Code: Select all

all-MyPlan:
   $(MAKE) -f $(lastword $(MAKEFILE_LIST)) build-MyPlan RULE=MyPlan
Aren't you still spawning a new proc with this line?

I'm thinking $(MAKE) or make would be a transparent include which doesn't create a new proc.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:52 am
by Wajideu
b.zaar wrote:Aren't you still spawning a new proc with this line?
Yeah. The variable MAKEFILE_LIST is a list of all the currently processing makefiles. By calling $(lastword $(MAKEFILE_LIST)), I'm retrieving the path of the currently running makefile; and then I'm re-making it with a variable called RULE that controls which target blocks are parsed within the file; which allows all of the targets to be encapsulated and reuse variable names.

I'm not entirely sure how 'make' handles process execution.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 1:54 am
by b.zaar
Wajideu wrote:Maybe we could get a little collaboration going on. I don't really have any specific details in mind regarding the format of Planfile atm; I'm just winging it; and your idea for make++ seems pretty well structured.
Sure thing, I'm not working on anything important and this might be useful to more than just me...
I'm aware there are plenty of standards to choose from. I just don't like any of them. So of course, I'm going to bask in the irony of making my own.
;)

Re: Waji's Standards

Posted: Fri Oct 10, 2014 2:11 am
by Owen
Wajideu wrote:I'm not entirely sure how 'make' handles process execution.
It pipes your command blocks to "/bin/sh -e"

Re: Waji's Standards

Posted: Fri Oct 10, 2014 2:25 am
by Wajideu
A few suggestions

1. For all of the internal makefile commands like foreach and patsubst I think we should use a $ prefix like

Code: Select all

$foreach($(MySubProject_DIR), dir)
{
	include $(dir)
}
Just to help differentiate between directives and commands.


2. Planfile variables should be declared like $[VAR] instead of $(VAR) or ${VAR} to indicate that they need to be resolved rather than being passed to the makefile. Ie.

Code: Select all

[VAR]      = hello
TEST      := $[VAR] $(VAR)
Would produce a makefile with

Code: Select all

TEST      := hello $(VAR)
3. The following commands would be added:

Code: Select all

$assert(value1,[value2])      - Assert that value1 = value2
$detect(symbolic name)        - Detect the existence of a program with the symbol name (eg. $detect(cc))
$define(symbol,value)         - Define a symbol
$undef(symbol)                - Undefine a symbol
$hasfile(file)                - Check for the existence of a file
$hasfunc(symbol,files)        - Check for the existence of function within files
$hasvar(symbol,files)         - Check for the existence of variable within files
$output([language], file)     - Output the current configuration as language (default = c) into file.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 2:45 am
by b.zaar
1. This

Code: Select all

$foreach
should either be

Code: Select all

$(foreach ...)
or just

Code: Select all

foreach()
but only within a code block.

2. Planfiles again?

make++ works directly with makefiles. If you really want then add the following

Code: Select all

ifndef $(_MAKE_PP_)
$(error This project requires make++)
endif

3. Adding extra functions should wait until encapsulation is working.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 2:52 am
by Wajideu
b.zaar wrote:1. This

Code: Select all

$foreach
should either be

Code: Select all

$(foreach ...)
or just

Code: Select all

foreach()
but only within a code block.[/code]
The reason I suggested this was that commands like '$(foreach)' are completely different from commands like 'ifeq'. Either way, we're going to have to think of a way to somehow differentiate between immediate and passive commands.
b.zaar wrote: 2. Planfiles again?

make++ works directly with makefiles. If you really want then add the following

Code: Select all

ifndef $(_MAKE_PP_)
$(error This project requires make++)
endif
Yes, because we're not just making the project, we need to configure and cache settings. Additionally, as I said before, I wanted to provide a clean way of declaring a multi-step build process. With the new syntax, I was thinking perhaps something like:

Code: Select all

::MyPlan:
{
	:MyStep1:
	{
		MyRule1: { }
	}

	:MyStep2: { }

	MyRule2: { }
}

Re: Waji's Standards

Posted: Fri Oct 10, 2014 3:59 am
by b.zaar
Wajideu wrote:Yes, because we're not just making the project, we need to configure and cache settings. Additionally, as I said before, I wanted to provide a clean way of declaring a multi-step build process.
Show me one of each as an example.

What do you want to configure in detail and how would you like to see it? I'm assuming it's a script with a lot of autodetecting installed software etc.

And what exactly is a multi-step build process?

Re: Waji's Standards

Posted: Fri Oct 10, 2014 4:10 am
by embryo
iansjack wrote:I predict a poor future for your "standards".
This is the standard phrase that teachers used to lecture Billy Gates and Steve Jobs. So, it is about exceptions, that happen.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 5:49 am
by Wajideu
b.zaar wrote:What do you want to configure in detail and how would you like to see it? I'm assuming it's a script with a lot of autodetecting installed software etc.
The same things you'd do with autotools; detecting the presence of programs, headers, and functions. Detecting the host and target platforms, handling user specified options like "--disable-nls", etc.
b.zaar wrote:And what exactly is a multi-step build process?
There are several cases in which a person would need to build a project in multiple stages. For example, they may need to build tools to build a part of themselves, the user may be performing a Canadian cross compilation, or another example being something like binutils/gcc where you have to build both first in order to compile the C runtime and rebuild them a second time to link against it.

Re: Waji's Standards

Posted: Fri Oct 10, 2014 2:07 pm
by b.zaar
Wajideu wrote:The same things you'd do with autotools; detecting the presence of programs, headers, and functions. Detecting the host and target platforms, handling user specified options like "--disable-nls", etc.
I kind of wanted a stripped down example that you've created to translate but here's a crack at part of the configure.in script in make++ format for a general project.
Call using make++ config disable-nls=1

Code: Select all

# Top level Makefile

# Make++ check
ifndef $(_MAKE_PP_)
$(error This project requires make++)
endif

all: foo bar

CONFIG_FILE := config.mk

ifeq ($(MAKECMDGOALS), config)
include configure.mk
endif

-include $(CONFIG_FILE)        # Saved configuration settings after running 'make config'
include foo.mk
include bar.mk

Code: Select all

# configure.mk

config:{

# This would be all your AC stuff
# The minimum gcc version numbers
REQUIRED_CC = 4.8

# Check standard headers are installed
REQUIRED_HEADER_STDC = 1

# Check format of time header
REQUIRED_HEADER_TIME = 1

# A static script, maybe in the make++ include directory
include autoconfig.mk

# Manual check for external programs needed not in the autoconfig check list
# This requires more processing to strip the version form the output string
PERL_VERSION = $(shell perl -v)

}
    

Code: Select all

# autoconfig.mk
# This is basically the equivalent configure script generated by autotools
# written in make++ script format. 
# Make++ handes the script so a bash shell isn't required.
#
# Straight scripting code so needs to be included after all the configuration setup.

ifdef($(REQUIRED_CC)){
    # Usual bash scripts for checking in make++ script form
}

# Continues with all the usual check scripts
# Writes all saved options to $(CONFIG_FILE)

Very cut down example but it would be possible to skip the step from configure.in to configure to Makefile.
Wajideu wrote:There are several cases in which a person would need to build a project in multiple stages. For example, they may need to build tools to build a part of themselves, the user may be performing a Canadian cross compilation, or another example being something like binutils/gcc where you have to build both first in order to compile the C runtime and rebuild them a second time to link against it.
If make already handles it natively so would make++.