powershellmakefile

How do I rewrite this shell command to call PowerShell only once, and still read my Yaml file in my Makefile?


Introduction

I am trying to make Makefile read with the shell command a YAML file which is only 20 lines of code at most.

The problem I am having is that it takes a long time to read the data from the YAML file.

I asked several AI's, as at first I thought the powershell code was a bit slow, but the AI's told me it was because I was using the shell command too much and that it was adding a time overhead.

They told me that the best way to solve it was to make a single shell call and the returned value will be used to set the rest of the values.

I did this

CONFIG := $(shell powershell ‘(Get-Content -Path “config.yaml” -Raw | ConvertFrom-Yaml)’)
AS := $(CONFIG).assembly.assembler

Problem

The problem I had when I did that is that it didn't acquire the value and only the text entered.

Objetive

I tried many variants of the above code, but everything remained the same.

Extra dates

In the end I went back to the beginning and put in the following code

AS := $(shell powershell ‘(Get-Content -Path “config.yaml” -Raw | ConvertFrom-Yaml).assembly.assembler’)
LD := $(shell powershell ‘(Get-Content -Path “config.yaml” -Raw | ConvertFrom-Yaml).assembly.linker’)
ASFLAGS := $(shell powershell ‘(Get-Content -Path “config.yaml” -Raw | ConvertFrom-Yaml).assembly.asflags’)
LDFLAGS := $(shell powershell ‘(Get-Content -Path “config.yaml” -Raw | ConvertFrom-Yaml).assembly.ldflags’)

The problem with this code is that it takes a long time to execute when you put make.

I would like to make it run faster because when I did some tests, I noticed that it took about 2 - 3 seconds.

Here's my config.yaml file

System: Windows

assembly:
    assembler: as
    linker: gcc
    ldflags:
    asflags: -Iinclude --64
    cflags: -Wall -m64

directories:
    - src
    - lib
    - bin
    - scripts
    - include

Summary of the problem

To sum up, I want to get the values in the ‘Assembly’ part of my yaml file, but in a quick way as it takes too long to run my Makefile leaving the code as it is.

Considerations

I use the powershell-yaml module to read the yaml file.

I don't have any other modules installed and I don't plan to install any more.

Results obtained so far, using the solution from this answer:

enter image description here


Solution


  • The following sample Makefile puts it all together:

    # Define what shell to use and what options to pass to it.
    SHELL := powershell.exe
    .SHELLFLAGS := -NoProfile -Command 
    
    # Run a single PowerShell command that extracts all data of interest.
    # Pass-through $ must be escaped as $$
    RESULT := $(shell \
    $$obj = (Get-Content -Raw config.yaml | ConvertFrom-Yaml).assembly;\
    $$obj.assembler; $$obj.linker; $$obj.asflags -replace ' +', '&'; $$obj.ldflags -replace ' +', '&'\
    )
    
    # Split the result into the individual values of interest.
    AS := $(word 1,$(RESULT))
    LD := $(word 2,$(RESULT))
    ASFLAGS := $(subst &, ,$(word 3,$(RESULT)))
    LDFLAGS := $(subst &, ,$(word 4,$(RESULT)))
    
    # Phony default goal that echoes the resulting variable values,
    # using a PowerShell command.
    .PHONY: foo
    foo:
        @'AS=[$(AS)]', 'LD=[$(LD)]', 'ASFLAGS=[$(ASFLAGS)]', 'LDFLAGS=[$(LDFLAGS)]'
    # IMPORTANT: Be sure that the line above as well as recipe lines in general
    #            start with an actual TAB char.
    

    Running make then yields the following, based on your sample config.yaml, showing that the values were assigned to variables as intended.:

    AS=[as]
    LD=[gcc]
    ASFLAGS=[-Iinclude --64]
    LDFLAGS=[]
    

    Note:


    As for what you tried: