"pxt target arcade" fails

#1

Just playing around with C++ extensions. I made a dummy C++ extension, but cannot build it from the command line - I made sure my CPP file is in the pxt.json file, and made sure that it contains a compile error, but “pxt build” does not attempt to build it.

Targetting microbit works, for example. I can set up the same project, by running “pxt target microbit”, and that will dispatch the .cpp file to the cloud build as I expect. But “pxt target arcade” fails, because pxt-arcade is not visible to npm’s directory?

So if I run “pxt build” in this directory without previously targetting microbit, the build will succeed (because my *.ts files are empty, and valid), but does not attempt compilation of the C++ source.

Is there a way of overriding this locally? I’ve tried cloning the pxt-arcade repo locally, but can’t figure out what to give to “pxt target” to make it look at the local copy - it always seems to hit the online directory of pxt targets, and cant find ‘arcade’.

I can compile the extension, including it’s C++ files in the online editor. And the build fails as expected, but it’s not possible to see the errors, so this isn’t a great write-compile-test experience.

How are other folks doing this?

#2

https://www.npmjs.com/package/pxt-microbit exists, and https://www.npmjs.com/package/pxt-arcade does not.

That seems to be the root cause, unless there is a way to have “pxt target” look at locally available projects, instead of always consulting npm.

#3

This command is not yet supported for arcade. If you’ve clone evertying locally, you should be able to simply run “pxt build” from a project folder. You will not be able to run the simulator locally as it is still private.

#4

The ‘pxt build’ command completes if I run it. I ran a control experiment by adding a deliberate compile error to ‘main.ts’, and that caused an error.

However I see that the C++ files are not compiled. I add a deliberate syntactic error to a file, and the build succeeds.

Repeating this exercise with a microbit target produces the expected outcome - a cloud build is initiated with the C++ file, and it fails.

#5

is your c++ file referenced in pxt.json?

#6

Yep. As I say, if I target microbit it fails as expected.

#7

Can you share a github repo?

#8

Sure OK, here are some experiments to reproduce what I’m describing:

Experiment #1

$ git clone https://github.com/junk100/pxt-cpptest
Cloning into 'pxt-cpptest'...
<etc>

$ cd pxt-cpptest/

$ pxt target microbit
Installing pxt-microbit locally; don't worry about package.json warnings.
<etc>

$ pxt install
Using target microbit with build engine yotta
<etc>

$ pxt build
Using target microbit with build engine yotta
<...>
polling C++ build https://makecode.com/compile/<blah blah>

BUILD FAILS AS EXPECTED

Experiment #2

$ git clone https://github.com/junk100/pxt-cpptest
Cloning into 'pxt-cpptest'...
<etc>

$ cd pxt-cpptest/

$ pxt target arcade
Installing pxt-arcade locally; don't worry about package.json warnings.
<...>
404 Not Found: pxt-arcade@latest

CANNOT PROCEED

Experiment #3

$ git clone https://github.com/junk100/pxt-cpptest
Cloning into 'pxt-cpptest'...
<etc>

$ cd pxt-cpptest/

$ pxt build
Cannot find node_modules/pxtcli.json nor pxtarget.json
Couldn't find PXT; maybe try 'pxt target microbit'?

CANNOT PROCEED

Experiment #4

$ git clone https://github.com/Microsoft/pxt-arcade
Cloning into 'pxt-arcade'...
<etc>

$ cd pxt-arcade/

$ npm install

$ pxt serve

<CTRL-C> after some time passes

$ cd projects

$ git clone https://github.com/junk100/pxt-cpptest
Cloning into 'pxt-cpptest'...
<etc>

$ cd pxt-cpptest/

$ pxt install
Using target arcade with build engine codal
<etc>

$ pxt build
Using target arcade with build engine codal
<etc>
package built; written to binary.uf2

BUILD SUCCEEDED (incorrectly)

So the MicroBit experiment works exactly as I would expect, and as the documentation suggests.

Even after jumping through what I think are the right hoops for the Arcade target, the build doesn’t behave as it should. The C++ files are simply ignored.

If I consume the faulty C++ project inside of the online editor, it will fail to build the binary executable, but without anywhere I can find to inspect the errors. Just a popover window saying ‘it went wrong’. The “output.txt” file seems to only contain Typescript errors, so it says “everything seems fine”.

#9

Just wondering if any of the above results suggest a way forward here. I wasn’t able to make any progress with this.

Is there any significance of the output “Using target microbit with build engine yotta” and “Using target arcade with build engine codal”? The former is emitted during the apparently correct MicroBit build, the latter during the apparently incorrect Arcade build… Is there some extra step I’m failing to perform, to configure the Arcade build correctly?

Is anything in here relevant:? https://github.com/Microsoft/pxt/blob/master/cli/buildengine.ts#L41

#10

OK, so maybe this is progress: I changed my pxt.json to this (after much hacking):

{
    "name": "pxt-cpptest",
    "version": "0.0.0",
    "description": "",
    "dependencies": {
        "core---stm32": "*",
        "accelerometer": "*"
    },
    "files": [
        "README.md",
        "main.ts",
        "blah.cpp"
    ],
    "testFiles": [
        "test.ts"
    ],
    "compileServiceVariant": "stm32f401",
    "public": false
}

Notes:

  • Added the “compileServiceVariant” entry.
  • Used a dependency of “core—stm32” rather than “core” or “device”
  • Added the “accelerometer” dependency, without which there is a link error due to its absence.

My build now concludes as expected with a local build (I have Docker and Yotta installed, and they seem to be working right).

I’m not really testing the cloud build, to rule out any weirdness there - I was getting inconsistent results and errors which did match the local build. Am also not testing any experiments inside the graphical editor.

But my question now is, although my hackery has the appearance of some kind of correctness, are these the steps I should have taken? I got there only via trial and error really.

#11

From a brief further test, it seems like I can:

  • Remove the “compileServiceVariant” entry.
  • Replace the pair of added dependencies with just: “hw—stm32f401”: “*”

So that’s a nice simplification. Is this the right way to proceed? It looks kind of ‘Brainpad Arcade’ specific. Is there a better way?

#12

Yes, referencing hw—CPU is the way to go. When you compile you need to compile for a specific target in this case F4. You can reference other hw— and compile for D5 or RPi. The F4 covers GHI board as well as Kitten Bot one and more in future. We generate the same binary for all F4.

1 Like
#13

Oh. Also this is only for command line builds. when you publish your extension remove the hw— dependency.

1 Like
#14

Got it - thanks a lot for the help, and glad I’m on the right track!

So what I’m thinking here is to add a Makefile rule for my command line build, to swizzle the

“hw–<cpu>”: “*”
in and out of the pxt.json automatically, leaving it ‘clean’ for the in-editor version.

However, inside the editor, it must be somehow configuring pxt to build for the currently configured board. How is it doing that? Is there a flag along the lines of 'pxt build --target=f4" or similar. I can’t find anything documented, but internally the editor must be doing something along those lines is it?

#15

Correct, when you click download and choose a board the editor internally replaces hw with hw—xyz. There isn’t a flag right now and I guess it would not be that useful since if you change target we don’t handle the local build too well.

I suggest you keep your extension dependency-free and create a test project alongside that references it (through file:…/pxt-blah syntax). Then use the hw— dependency in the test project but only publish the extension.

Also if the extension is Typescript only (which I guess yours isn’t) you can do all that from the browser using our github support.

BTW why do you need C++ in your extension? In Arcade we only use cpp for the most low level stuff and most of the code is TS.

#16

For the sake of it pretty much… just to get my hands dirty! Thanks for the help.