asar
asar copied to clipboard
`includeonce` breaks on some equivalent paths
To quote the manual:
The includeonce command places an include guard on the file that is currently being assembled. This prevents it from being assembled again in the same pass.
This is currently not actually true, from what I've seen in 1.81 as well as current versions of 1.9 and 2.0.
While includeonce works fine for something like
incsrc "shared.asm"
incsrc "shared.asm"
it takes very little to break it, something like this is already good enough (in some cases):
incsrc "shared.asm"
incsrc "../shared_code/shared.asm"
The same effect can also be seen when referring to the same file with an absolute and relative path.
As it turns, this problem also seems to appear and disappear depending on the current working directory, so I assume this might also be tied to #253.
Solution: Normalize paths or check them for actual equivalence.
Workaround: Use manual include guards: if defined("guard")), etc.
Asar actually does normalize paths for include guards internally. However, I think it might not be reliable when passing the main patch to Asar as a relative path (and maybe there IS some working directory shenanigans going on there). Just for science: Can you reproduce the error when you pass the main patch to Asar as an absolute path?
Anyways, checking paths for true equality unfortunately isn't all that trivial. I'm not sure if we can manage to have a 100% reliable solution.
However, I think it might not be reliable when passing the main patch to Asar as a relative path (and maybe there IS some working directory shenanigans going on there). Just for science: Can you reproduce the error when you pass the main patch to Asar as an absolute path?
I haven't managed to reproduce it while passing the main patch as an absolute path yet, so that might be the issue. Unfortunate since I do think some tools probably pass relative paths to the asar DLL as well, I've observed the bug in uberasm before.
Anyways, checking paths for true equality unfortunately isn't all that trivial. I'm not sure if we can manage to have a 100% reliable solution.
Idk what C++ version you're bound to but there is fs::equivalent as well as fs::weakl_canonical and fs::canonical.
Asar actually does normalize paths for include guards internally. However, I think it might not be reliable when passing the main patch to Asar as a relative path (and maybe there IS some working directory shenanigans going on there). Just for science: Can you reproduce the error when you pass the main patch to Asar as an absolute path?
Anyways, checking paths for true equality unfortunately isn't all that trivial. I'm not sure if we can manage to have a 100% reliable solution.
"Can you reproduce the error when you pass the main patch to Asar as an absolute path?"
I ran into such a problem (currently working with a workaround) with my new update on my player HP patch. Specifically have occurred with GPS on a SA-1 ROM during my testing. The blocks asm files are in a subfolder of GPS's blocks folder. With the define asm files in the same location as GPS.exe, blocks deeply nested needs the extra ../ on their incsrc to properly locate the defines file. Here's an example with the muncher block
incsrc "../../../StatusBarDefines.asm"
I have define files that also refer to the same define file, StatusBarDefines.asm:
incsrc "../StatusBarDefines.asm"
When I try to insert, no errors pop up, but get depreciation warning about redefined functions. Here is where the ASM files are placed:
├───GPS(V1.4.5)
│ │ asar.dll
│ │ Changes.txt
│ │ defines.asm
│ │ gps.exe
│ │ GraphicalBarDefines.asm
│ │ list.txt
│ │ main.asm
│ │ MotherHPDefines.asm
│ │ NumberDisplayRoutinesDefines.asm
│ │ PlayerHPDefines.asm
│ │ README.txt
│ │ SA1StuffDefines.asm
│ │ src.zip
│ │ StatusBarDefines.asm
│ │
│ ├───blocks
│ │ │ template.asm
│ │ │ template2.asm
│ │ │
│ │ └───PlayerHP_blocks
│ │ │ list.txt
│ │ │
│ │ ├───Damage
│ │ │ │ DirectionalHurtBlock.asm
│ │ │ │ SlowDamage.asm
│ │ │ │ SM64Lava.asm
│ │ │ │ VanillaMuncher.asm
│ │ │ │
│ │ │ └───DirectionalHurtBlockPresets
│ │ │ DirectionalHurtBlockPresetsCommonDefines.asm
│ │ │ DirectionalHurtBlock_Bottom.asm
│ │ │ DirectionalHurtBlock_Left.asm
│ │ │ DirectionalHurtBlock_Right.asm
│ │ │ DirectionalHurtBlock_Top.asm
│ │ │
│ │ ├───Heal
│ │ │ Mushroom.asm
│ │ │ ReusableHeal.asm
│ │ │ SlowHeal.asm
│ │ │
│ │ ├───MaxHP_Upgrade
│ │ │ │ MaxHP_UpgradeBit0.asm
│ │ │ │ MaxHP_UpgradeBit1.asm
│ │ │ │ MaxHP_UpgradeBit2.asm
│ │ │ │ MaxHP_UpgradeBit3.asm
│ │ │ │ MaxHP_UpgradeBit4.asm
│ │ │ │ MaxHP_UpgradeBit5.asm
│ │ │ │ MaxHP_UpgradeBit6.asm
│ │ │ │ MaxHP_UpgradeBit7.asm
│ │ │ │
│ │ │ └───MaxHPUpgradeDef
│ │ │ HPUpgradeDef.asm
│ │ │
│ │ └───Other
│ │ CharacterCustomizePreset0.asm
│ │ CharacterCustomizePreset1.asm
│ │
│ └───routines
│ change_map16.asm
│ check_sprite_kicked_horizontal.asm
│ check_sprite_kicked_vertical.asm
│ create_smoke.asm
│ DamagePlayer.asm
│ erase_block.asm
│ get_map16.asm
│ give_points.asm
│ glitter.asm
│ GraphicalBar_RoundAwayEmpty.asm
│ GraphicalBar_RoundAwayEmptyFull.asm
│ GraphicalBar_RoundAwayFull.asm
│ HorizKnockback.asm
│ InvincibilityCheck.asm
│ ItemSpriteHitbox.asm
│ kill_sprite.asm
│ layer2_sprite_position.asm
│ LevelListedIndex.asm
│ MathDiv32_16.asm
│ MathMul16_16.asm
│ MathMul32_32.asm
│ move_spawn_above_block.asm
│ move_spawn_below_block.asm
│ move_spawn_into_block.asm
│ move_spawn_relative.asm
│ move_spawn_to_player.asm
│ move_spawn_to_sprite.asm
│ PositionScoreSprite.asm
│ rainbow_shatter_block.asm
│ RecoverPlayerHP.asm
│ RemovePlayerHPBarRecord.asm
│ reset_turn_block.asm
│ set_item_memory.asm
│ shatter_block.asm
│ SideContactCheck.asm
│ SpawnScoreSprite.asm
│ spawn_bounce_sprite.asm
│ spawn_item_sprite.asm
│ spawn_sprite.asm
│ spawn_sprite_block.asm
│ sprite_block_position.asm
│ swap_XY.asm
│ teleport.asm