- refines comments
- use unified code for `lf tag not found` error
- merge lf_em410x_data.h & lf_hidprox_data.h, remove unused macros
- split btn_fn_copy_ic_uid as btn_fn_copy_lf & btn_fn_copy_hf
- fixes offline em410x tag copy not working
- fixes conflict SAADC usage between battery level service & lf fsk demodulator
- Replace Python 3.10+ type hint syntax (`int | None`) with `Union[int, None]`.
- Add explicit `byteorder='big'` argument to all `int.from_bytes()` calls.
* feat: add lf HIDProx read, t55xx write, emulate function
code quaility:
- consistance: simulation -> emulation, label -> tag
- machine translated unreadable comments are made native
logic:
- newly added cli command includes: `lf hid prox read`, `lf hid prox write`, `lf hid prox econfig`
- machester demodulator is simplified
- various wiegand formats of HIDProx are supported
- goertzel algorithm is used in HIDProx FSK demod
- lf read is refactored using stream/feed pattern to boost scan speed
- t55xx write is refactored to share same logic between em410x & HIDProx
- lf emulating is refactored to use PWM peripheral, allowing more card type to be added
closes: #212, #210
* chore: remove not implemented wiegand format comments
* fix: build ci
* fix: build ci
* fix: build ci
* fix: build ci
* Implement MF1_ENC_NESTED_ACQUIRE in firmware
* Implement MF1_ENC_NESTED_ACQUIRE in software + fix code formatter
* Remove xz and pthreads from sources, use CMake FetchContent
* Update changelog
* lzma.h
* Update CMakeLists.txt
* Update CMakeLists.txt
* Probably fix workflow taking wrong commit for building
* Fix CMake building tools into bin/Debug on Windows
* Added cmd for fetching all slots nicks (without 16 commands)
* Fix type and use temp directory instead cwd (https://github.com/RfidResearchGroup/ChameleonUltra/pull/261)
* Fix endian for mfu_read_emu_counter_data and mfu_write_emu_counter_data
* Fix --key interpreted as list
* hardnested test fixed, increased timeout on mf1_hard_nested_acquire to fix cmd exec timeout on clone
* hardnested recovery(cli command not yet ready), based in noproto/HardnestedRecovery
* removed compiled binary
* Hardnested cli ready
* removed some unnecesary files
* removed unnecesary cached files
* cmake now builds hardnested too
* removed license.md
* added liblzma source(should fix checks not passing)
* i missed a line
* trimmed xz sources
* cmake now links local liblzma.a
* third try(warning solved)
* cmake now builds and links correcctly liblzma.a
* xz-5.8.1 vfolder renamed to xz
* fixed paths
* runner test
* removed wrong placed check
* disable landlock under windows
* missing files
* missing files
* windows strtok fix
* corrected lzma path under windows
* fix
* set release config for liblzma
* corrected path
* trailing_zeros
* msclock
* msclock integer issue
* msclock missing header
* fallback if not using msvc
* deleted include by accident
* revert clock change
* change custom target for custom command
* windows fmemopen implementation
* wrong path
* wrong name
* use fmemopen only when not using msvc
* use fmemopen.h when building on windows, non msvc
* re-add static link
* wrong filename
* pthread handling for mingw(proxspace)
* cleanup
Defined a working function load_key_file(import_key, keys) for command hf mf fchk --key
function load_dic_file(import_dic, keys) is empty for now, to prevent an error when executing hf mf fchk --dic
1. Added 'cmd_processor_mf0_ntag_get_emu_page_count' interface to get available page count of mf0.
2. We can reuse the 'STATUS_PAR_ERR', and we can delete repeated cmd 'STATUS_INVALID_PARAMS'.
Added `wrbl` and `rcnt` commands for writing blocks and reading counters. Added `-P` parameter to all commands that may need it to allow prior auth with a 4-byte password. `dump` command now dumps all pages until it fails rather than just the first 16 pages when no `-q` parameter is provided. Added `version` command to allow requesting version bytes.
This (often largely) improves the speed of the decrypt process. On my
laptop, with the same logs (37 records for one block and 37 records
for another block), here are the performances, as measuerd using a
simple command:
```bash
time echo -e "hw connect\nhf mf elog --decrypt\nhw disconnect" | ./chameleon_cli_main.py
```
- Before parallelisation (#187): 14m59,277s
- With parallelisation (current main): 6m13,513s
- With item skipping (this PR): 2m42,491s
pcd_14a_reader_ats_request didn't check for NAK so in case the tag NAKd
the RATS it would return a zero length ATS which would cause an
underflow in pcd_14a_reader_scan_once, that in turn resulted in
HF_ERR_ATS being returned due to an invalid ATS length.
fds_util event handler was ignoring all the events related to
peer_manager files and that was causing a deadlock while waiting for
record deletion that in turn caused a wdt reset, usually this resulted in
a partially done factory reset.
The fix adds a `ignore_pm` flag to op_info struct that gets cleared by
fds_wipe allowing for a true reset to happen.
- visually closer to pm3 (differenciate groups and commands)
- "dumphelp" allows to quickly dump all cmds and their options
- now all commands support '-h', so e.g. `hw settings store -h` will print help instead of storing
- no more command description in decorator, it is now taken from argparse description
* wip_protocol_refresh: (38 commits)
CI for releases
changelog
build_firmware.yml: fetch depth=0 to be able to build proper version strings
Deduce APP_FW_VER from git tag
bump app version
style
colors
Increase initial button wakeup from 4 to 8 seconds
Adding MIFARE Ultralight reading, wip
hf14a_raw: use @expect_response and fix tests
Fix shadow mode not being preserved. Breaking change: nfc_tag_mf1_write_mode_t has one new mode SHADOW_REQ. Client can set SHADOW or SHADOW_REQ, internally it will be transformed to SHADOW_REQ. When it's time to save data, if SHADOW_REQ, the fw will change it to SHADOW and still allow to save the data before acting as shadow. Breaking: when client reads back MF1 write mode just after settings SHADOW and before saving config, it will receive SHADOW_REQ and must be ready to handle this new enum value.
MF1_DETECT_SUPPORT: remove redundant data
Breaking change: DATA_CMD_GET_DEVICE_MODEL to match chameleon_device_type_t
hw 14a raw: closer to pm3 syntax, removed bit_frame,...
use field LED also in reader mode
fix changelog
new tag_specific_type_t enum, new slotConfig struct. FW will take care of existing slots. Disruptive changes: see below
Implemented hf 14a raw
Fixed initialization bugs and added raw command implementation functions.
Update the table of MFC attack support levels.
...
Initial button press wakeup of 4 seconds is sometimes inadequate to establish BT connection.
This change will expand the Initial button wakeup from 4 seconds to 8 seconds.
Device sleep behavior after will be as follows:
(Changed)
Initial Button Wakeup to Sleep : 8s
(No Change)
Subsequent Button Action to Sleep : 4s
Leaving RF Field wake to sleep : 3s
BLE Disconnect to sleep : 4s
USB Power Disconnect to sleep : 3s
Example behavior :
User wakes device with Button B (8 Sec to sleep)
User pushes button B again (Now 4 Sec to sleep)
User Places device in RF field (Maintain wake)
User removes device from RF field (3 sec to sleep)
If user discontinues the user journey at any point, the identified condition will invoke sleep at defined times.
nfc_tag_mf1_write_mode_t has one new mode SHADOW_REQ.
Client can set SHADOW or SHADOW_REQ, internally it will be transformed to SHADOW_REQ.
When it's time to save data, if SHADOW_REQ, the fw will change it to SHADOW and still allow to save the data before acting as shadow.
Breaking: when client reads back MF1 write mode just after settings SHADOW and before saving config, it will receive SHADOW_REQ and must be ready to handle this new enum value.
Now data length is always in bits
Option -o => -a and only needed to turn field on without select or data
Reorganize pcd_14a_reader_raw_cmd
Some more checks
Disruptive changes:
- tag types are 2-byte long with new values
- GET_SLOT_INFO returns 32 bytes as tag types are now 2-byte long
- "enable" is not common to one slot anymore but bound to the HF or LF part
- GET_ENABLED_SLOTS returns 16 bytes as we get "enabled_hf" and "enabled_lf" for each slot
- SET_SLOT_ENABLE needs 3 bytes slot_number|sense_type|enable as we need to specify to enable HF or LF
- slotConfig changed a lot but this is internal to the fw and its flash and a function does the format conversion on first boot after flash
so slot data is preserved on fw upgrade, but if one downgrades to a previous version, data will be erased.
MF1_DETECT_DARKSIDE was actually runnign the full attack, as there is no quick way to detect Darkside
So if you want to check for Darkside, just run directly MF1_DARKSIDE_ACQUIRE.
This huge commit tries to enhance several things related to the fw/cli protocol.
Generally, the idea is to be verbose, explicit and reuse conventions, in order to enhance code maintainability and understandability for the other contributors.
docs/protocol.md got heavily updated
Many commands have been renamed for consistency. you are invited to adapt your client for easier maintenance
Guidelines, also written in docs/protocol.md "New data payloads: guidelines for developers":
- Now protocol data exchanged over USB or BLE are defined in netdata.h as packed structs and values are stored in Network byte order (=Big Endian)
- Command-specific payloads are defined in their respective cmd_processor handler in app_cmd.c and chameleon_cmd.py
- Define C `struct` for cmd/resp data greater than a single byte, use and abuse of `struct.pack`/`struct.unpack` in Python. So one can understand the payload format at a simple glimpse.
- If single byte of data to return, still use a 1-byte `data`, not `status`.
- Use unambiguous types such as `uint16_t`, not `int` or `enum`. Cast explicitly `int` and `enum` to `uint_t` of proper size
- Use Network byte order for 16b and 32b integers
- Macros `U16NTOHS`, `U32NTOHL` must be used on reception of a command payload.
- Macros `U16HTONS`, `U32HTONL` must be used on creation of a response payload.
- In Python, use the modifier `!` with all `struct.pack`/`struct.unpack`
- Concentrate payload parsing in the handlers, avoid further parsing in their callers. This is true for the firmware and the client.
- In cmd_processor handlers: don't reuse input `length`/`data` parameters for creating the response content
- Avoid hardcoding offsets, use `sizeof()`, `offsetof(struct, field)` in C and `struct.calcsize()` in Python
- Use the exact same command and fields names in firmware and in client, use function names matching the command names for their handlers unless there is a very good reason not to do so. This helps grepping around. Names must start with a letter, not a number, because some languages require it (e.g. `14a_scan` not possible in Python)
- Respect commands order in `m_data_cmd_map`, `data_cmd.h` and `chameleon_cmd.py` definitions
- Even if a command is not yet implemented in firmware or in client but a command number is allocated, add it to `data_cmd.h` and `chameleon_cmd.py` with some `FIXME: to be implemented` comment
- Validate data before using it, both when receiving command data in the firmware and when receiving response data in the client.
- Validate response status in client.
Disruptive changes:
- GET_DEVICE_CAPABILITIES: list of cmds in data are now really Big Endian
Note: the initial attempt to use macros PP_HTONS were actually considering wrongly that the platform was Big Endian (BYTE_ORDER was actually undefined) while it is actually Little Endian.
- GET_APP_VERSION: response is now a tuple of bytes: major|minor (previously it was in reversed order as a single uint16_t in Little Endian)
- SET_SLOT_TAG_TYPE: tag_type now on 2 bytes, to prepare remapping of its enum
- SET_SLOT_DATA_DEFAULT: tag_type now on 2 bytes, to prepare remapping of its enum
- GET_SLOT_INFO: tag_type now on 2 bytes, to prepare remapping of its enum
- GET_DEVICE_CHIP_ID: now returns its 64b ID following Network byte order (previously, bytes were in the reverse order)
- GET_DEVICE_ADDRESS: now returns its 56b address following Network byte order (previously, bytes were in the reverse order). CLI does not reverse the response anymore so it displays the same value as before.
- MF1_GET_DETECTION_COUNT: now returns its 32b value following Network byte order (previously Little Endian)
- GET_GIT_VERSION response status is now STATUS_DEVICE_SUCCESS
- GET_DEVICE_MODEL response status is now STATUS_DEVICE_SUCCESS
- MF1_READ_EMU_BLOCK_DATA response status is now STATUS_DEVICE_SUCCESS
- GET_DEVICE_CAPABILITIES response status is now STATUS_DEVICE_SUCCESS
- HF14A_SCAN: entirely new response format, room for ATS and multiple tags
- MF1_DETECT_SUPPORT response status is now HF_TAG_OK and support is indicated as bool in 1 byte of data
- MF1_DETECT_PRNG response status is now HF_TAG_OK and prng_type is returned in 1 byte of data with a new enum mf1_prng_type_t == MifareClassicPrngType
- MF1_DETECT_DARKSIDE response status is now HF_TAG_OK and darkside_status is returned in 1 byte of data with a new enum mf1_darkside_status_t == MifareClassicDarksideStatus
- MF1_DARKSIDE_ACQUIRE response status is now HF_TAG_OK and darkside_status is returned in 1 byte of data. If OK, followed by 24 bytes as previously
- MF1_GET_ANTI_COLL_DATA: in case slot does not contain anticoll data, instead of STATUS_PAR_ERR, now it returns STATUS_DEVICE_SUCCESS with empty data
- MF1_SET_ANTI_COLL_DATA and MF1_GET_ANTI_COLL_DATA now use the same data format as HF14A_SCAN
For clients to detect Ultra/Lite with older firmwares, one can issue the GET_APP_VERSION and urge the user to flash his device if needed.
On older firmwares, it will return a status=b'\x00' and data=b'\x00\x01' while up-to-date firmwares will return status=STATUS_DEVICE_SUCCESS and data greater or equal to b'\x01\x00' (v1.0).
Other changes: cf CHANGELOG, and probably a few small changes I forgot about..
TODO:
- remap `tag_specific_type_t` enum to allow future tags (e.g. LF tags) without reshuffling enum and affecting users stored cards
- TEST!
Simulation and emulation used within same document while having no distinctive technical differentiating usage, propose changing all instances to Emulate/Emulation
Avoid
```
Chameleon Connect fail: [Errno 2] could not open port /dev/ttyS15
/dev/ttyS39: [Errno 2] No such file or directory: '/dev/ttyS15\r\n/dev/ttyS39'
```
By only returning the first COM port with `VID_6868&PID_8686`
Please avoid creating variable in middle of functions, and in this particular case double `uint8_t status;`.
Can be valid for some compiler, but does not help to read the code.
Because otherwise one must wait for sleep animation to finish, then press button then wait for boot animation to finish...
Also, fix saved config CRC after config has been saved
Bug when NRF_LOG_DEFERRED=0
due to a userland NRF_LOG_INFO after FDS record update was initiated, interrupted by FDS record IRQ handler and its own NRF_LOG_INFO
resulting in
<error> app: Fatal error
<warning> app: System reset
Added a few more NRF_LOG in FDS module as well.
Added NRF_LOG_FLUSH in system_off_enter to not miss last messages.
Changes made:
- CI properly supports being ran on PRs and shouldn't fail anymore on
the RRG repo;
- The nonsense of unzipping archives during release creation isn't
needed anymore because now there's an artifact that holds all the
files (both zip and others) that should be included in a release;
- Softdevice and Application verification were re-enabled (as per
@doegox suggestion);
- Softdevice is now bundled in `-firmware` artifact;
- `dev` release tag is now updated ad every push to main;
- On PRs a comment linking to artifact is now added by CI after
success, artifact links are done with nightly.link so that they also
fork for unauthenticated users;
There are some quirks:
- on_pr runs on pull_request_target because it needs write access to
packages, but pull_request_target implies that GITHUB_SHA is set to
the base repo HEAD commit, so the whole `checkout-sha` thing is
needed. This also implies that if one of the workflow files are
changed in a PR the changed versions won't be ran against that same
PR.
- Client building per OS isn't yet implemented but all the necessary
scaffolding is there. At the moment the per-OS clients are just a zip
file containing all the client source.
Examples:
- PR comment: https://github.com/augustozanellato/ChameleonUltra/pull/14#issuecomment-1688737709
- `dev` release: https://github.com/augustozanellato/ChameleonUltra/releases/tag/dev
Once an external HF field is detected, when a first byte is received, then NFC IRQ is called non-stop.
But none of the conditions in nrfx_nfct_irq_handler() is met so the handler does nothing and there is no chance to get called from a registered callback.
Side effect is that main loop cannot run, button IRQs are called but button processing in main loop is not called, etc.
So one of the side effects is that bsp_wdt_feed() is not called.
Current workaround is to call bsp_wdt_feed() at the end of nRF SDK nrfx_nfct.c nrfx_nfct_irq_handler()
I suspect the hack of the NFC state machine done in nfc_14a.c nfc_tag_14a_event_callback() case NRFX_NFCT_EVT_FIELD_DETECTED
to get access to the anticollision phase is breaking sth in the SDK state machine, NFC IRQ should be called only on real change (field drop, cmd received,...)
Slot
Won't work like this
More randomness on nested auth (for hardnested recovery) and change default GCC location
Nobody will have GCC in this default location, /usr/bin/ will target way more users
Get enabled slots command
hw slot list show disabled slots
Improve python code quality
Show Mifare Classic emulator settings in hw slot list
Implement hf mf settings to change Mifare Classic emulator settings
Update
* SlotNumber values range from 1 to 8 rather than from 0 to 7
this allows more straightforward usage as ppl can use equivalently SLOT_1 or 1.
* SlotNumber.fix -> .to_fw, and add .from_fw
* removed unnecessary SLOT_NO
* More straightforward use of enums, no need for .value, .__members__, name.replace() etc
* Unify usage between TagSenseType and TagSpecificType
* Add str representations for TagSenseType
* Fixed TagSpecificType related help (e.g. in hw slot type -h)
* Removed some redundant error raise
* Note: iterations can be done with `for slot in chameleon_cmd.SlotNumber:`
* for issues specific to another client than the Python CLI, use the corresponding issue tracker. E.g. [here](https://github.com/GameTec-live/ChameleonUltraGUI/issues) for the ChameleonUltraGUI
***Compilation problems***
Try compiling with verbose. Use `make VERBOSE=1` for the firmware and the software/src tools.
Include the verbose compilation logs.
***flashing problems***
Have you followed the instructions properly?
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
Explain it as you would do to someone not familiar with the problematic feature.
What is the abnormal behavior you observed?
E.g.
1. Connect '....'
2. Execute '....'
3. Press button '....'
4. See error '....'
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem. For console text and logs, better to dump them as text than image. Attach files if too long.
**Host (please complete the following information):**
- OS and version
- for compilation issues, the toolchain version
- inside CLI run `hw version` and paste the output here
Please keep in mind we are still at the infancy of the project and a lot has still to be done.
Have first a look at the [Whitepaper](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/docs/technical_whitepaper.md), the Wiki [Roadmap](https://github.com/RfidResearchGroup/ChameleonUltra/wiki/Public-Roadmap) and [Wishlist](https://github.com/RfidResearchGroup/ChameleonUltra/wiki/Wishlist).
No need for creating issues for well known missing supports, we are already aware :)
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
Copyright of each contribution is tracked by the Git history.
See the output of `git shortlog -nse` for a full list or `git log --pretty=short --follow <path/to/sourcefile> |git shortlog -ne` to track a specific file.
See also [the Contributors page on Github](https://github.com/RfidResearchGroup/ChameleonUltra/graphs/contributors).
All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
## [v2.1.0][2025-09-02]
- Added UV, formatter and linter. Contribution guidelines. (@GameTec-live)
- Extend max packet data size from 512 to 4096 bytes (@Foxushka)
- HID Prox support (@TeCHiScy)
-`hf mf elog --decrypt` skip records with found keys (@taichunmin)
- Added cmd for fetching all slots nicks (@Foxushka)
- Added `hf mf senested` for recovering keys from static encrypted cards via backdoor (https://eprint.iacr.org/2024/1275) (@Foxushka)
- Added cmd for faster bulk key checking on one block (~33 keys per second) (@Foxushka, @taichunmin)
- Added cmd to acquire nonces for static encrypted cards via backdoor (@Foxushka)
- Added `firmware/docker-compose.yml` to build firmware in local docker (@taichunmin)
- Added cmd to acquire nonces for hardnested(Protocol doc need update) (@xianglin1998)
- Added command to check keys of multiple sectors at once (@taichunmin)
- Fixed unused target key type parameter for nested (@petepriority)
- Skip already used items `hf mf elog --decrypt` (@p-l-)
- Parallelize mfkey32v2 processes called from CLI (@p-l-)
- Added support for mifare classic value block operations (@taichunmin)
- Added regression tests (@doegox)
- Changed git version to version tag instead of dev tag (@taichunmin)
- Fixed 14A emulate bug and MF1 emulate bug (@spp2000 and @xianglin1998)
Heres a bit of info and a few guidelines to get you started:
- General
- Avoid force pushes. Force pushes and "one commit" PRs not only make reviewing more annoying but also erase a significant part of the git history. This, among other things, makes future debugging and bisection a lot harder.
- Conventional commits. It is recommended to follow the [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) pattern when it comes to commit messages. While this is not strictly enforced, its highly recommended and a good habbit.
- Atomic PRs. To help keep an overview and avoid conflicts, it is highly encouraged to file Atomic PRs. Atomic PRs are:
- Focused Scope: It targets a single, well-defined change, making it easier to understand and review.
- Minimal Size: It contains only the necessary code modifications to achieve its goal, avoiding unrelated changes.
- Independent: It should be able to stand on its own without depending on other unmerged PRs, reviewed, and merged independently.
- Self-Tested: each PR should include an appropriate set of unit tests that tests the changes. (optional but highly appreciated)
- Atomic Commits. Similar thing as atomic PRs. When you are done with a feature, commit. Made a working change? commit. Git commits are basically free. Doing frequent commits at sensible points throughout development not only helps you keep track of progress but also saves progress and changes so you can revert when something goes wrong. It also helps when debugging and bisecting as more granular commits allow for easier issue location.
- CLI
- The recommended packagemanager is [UV](https://docs.astral.sh/uv/) (from astralsh). You may use the manager of your choice, but when adding new dependencies they must be added to the UV lock file and pyproject toml as well.
- Type safety is important. The CLI should be typesafe. Python 3.9+ offer a wide variety of type declarations. Metas [pyrefly](https://pyrefly.org/) is used to do type validation. It is recommended to install the appropriate vscode extension and check your types before opening a PR.
- Formatting matters. Mostly. While pixelpeeping and exact rules are annoying and unnescesary, format your code in a readable and logical way. [Ruff](https://docs.astral.sh/ruff/) is used to enforce various formatting rules. You may install the Ruff vscode extension or use the CLI to format before opening a PR.
- Avoid extra packages. Almost everyone knows the "meme" of the javascript ["is-even"](https://www.npmjs.com/package/is-even) package. While it is encouraged and makes sense to use packages where appropriate, just installing packages for the hell of it even if its a 2 liner is not sensible.
In this file you can look up how to [edit](#Editing-the-code), [compile](#Compiling-the-code) and [debug](#Debugging-the-code) the code!
## Editing the code
We are using [Visual Studio Code](https://code.visualstudio.com/download) to edit this project! Simply download and install it!
- Install the [ARM-GCC](https://mynewt.apache.org/latest/get_started/native_install/cross_tools.html) version [9.3.1 Compiler](https://developer.arm.com/downloads/-/gnu-rm) and remember the path where you installed it.
- Install the [C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) in VS-Code.
- Create a new IntelliSense Configuration:
- press F1 in VS-Code and enter `C/C++: Edit Configurations (UI)`
- Add a new Configuration and name it
- Specify your Compiler path (path of previously installed Compiler `bin` folder)
- Change IntelliSense mode to `gcc-arm (legacy)`
- Add include path `${workspaceFolder}/**`
## Compiling the code
- Install the compiler (for instructions have a look at [Editing the code](#Editing-the-code))
- Edit Makefile.defs:
- Change `GNU_INSTALL_ROOT`(path of previously installed Compiler `bin` folder)
- Change `GNU_VERSION` (Version of the installed Compiler)
- Don't forget to remove the `#` in front of the changed lines
- Install make
- **Ubuntu:**
- Open a terminal.
- Run the following command to install Make: `sudo apt-get install build-essential`
- **Windows using Chocolatey:**
- Install Chocolatey:
- Open a PowerShell terminal with administrator privileges.
- Run the following command to install Chocolatey:
- In the same PowerShell terminal, run the following command to install Make using Chocolatey: `choco install make`
- **macOS:**
- Open a terminal.
- Install Homebrew package manager by running the following command: `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
- Once Homebrew is installed, run the following command to install Make: `brew install make`
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.