QB64 Phoenix Edition (QB64-PE)

repository·main·Indexed 42 days ago

https://github.com/qb64-phoenix-edition/qb64pe

A modern extended BASIC+OpenGL language compatible with QB4.5 and QBasic that compiles into native binaries for Windows, Linux, and macOS. It features an integrated IDE, command-line compilation, and a sophisticated auto-include system for managing library dependencies via the $USELIBRARY metacommand.

Tokens
4.3K
Snippets
10
Records
20
Agent score
44%

What's inside QB64 Phoenix Edition

  1. Understand the QB64-PE auto-include logic

    main

    Since v4.0.0, QB64-PE automatically includes support files (such as general/color constants and $DEBUG vwatch code) at specific positions in your program. Since v4.3.0, this mechanism also handles the $USELIBRARY metacommand to manage 3rd party library dependencies.

    This process is transparent to the user, but understanding the three primary include positions helps in managing program structure and library dependencies:

    1. AtTop: Occurs before the first line of user code. Used for initializing CONST, (RE)DIM [SHARED], and TYPE. Files typically use the *.bi extension.
    2. AfterMain: Occurs at the end of the main level code. Traditionally used for DATA, GOSUB routines, or error handlers. Since v4.4.0, this position always occurs right before the AtBottom includes, even if main-level and SUB/FUNCTION code are interleaved.
    3. AtBottom: Occurs after the last line of user code. Used for SUB and FUNCTION definitions. Files typically use the *.bm extension.
  2. Verify QBasic compatibility with QBasic testcases

    main
    The project includes a collection of legacy QBasic programs located in ./tests/qb64_testcases. During the build process, these programs are compiled to ensure that QB64-PE maintains backward compatibility and can compile standard QBasic code without errors. Note that the runtime behavior of these programs is not verified, only their successful compilation.
  3. How $USELIBRARY handles dependency ordering

    main

    When using the $USELIBRARY metacommand, QB64-PE manages the inclusion of library files across the three auto-include positions. To ensure dependencies are satisfied, the compiler uses different ordering rules:

    • AtTop library files: These are included in reverse order of their appearance in your code. This ensures that if Library B depends on Library A, and you call $USELIBRARY B then $USELIBRARY A, Library A is actually included first at the top.
    • AfterMain library files: These are included in the order they appear in your code.
    • AtBottom library files: These are included in the order they appear in your code.
  4. Understand QB64-PE versioning (SemVer)

    main

    QB64 Phoenix Edition follows Semantic Versioning (SemVer).

    • Release Versions: Formatted as X.Y.Z (e.g., 4.6.0).
    • CI Versions: Include a tag for tracking builds, formatted as X.Y.Z-XX-YYYYYYYY (where XX is the commit count and YYYYYYYY is the first 8 digits of the commit hash).
    • Local/Manual Builds: If built directly from the repository without the CI process, the version is tagged as -UNKNOWN.
  5. Run QB64-based compiler tests

    main

    To execute the suite of QB64-based tests, run the provided shell script. The script automatically searches the ./tests/compile_tests directory for *.bas files and uses the QB64-PE compiler to validate them against their corresponding .output or .err files.

    ./tests/compile_tests.sh
  6. Compile a QB64 program using the Makefile

    main

    To compile a QB64 program into an executable, use the make command at the root of the repository. The process involves converting QB64 source code into C++ source code (stored in ./internal/temp), compiling the C++ source, and linking it with libqb.o and any requested 3rd party dependencies.

    Note: These parameters are primarily intended for the internal setup scripts and QB64-PE itself, not for direct manual usage, but they define the build surface.

    # Example conceptual invocation
    make OS=win EXE=myprogram.exe DEP_GL=y
  7. Create and structure QB64-based tests

    main

    QB64-based tests are used to verify compiler and language functionality. They are located in ./tests/compile_tests.

    To create a test, you must provide a .bas source file and one of the following validation files:

    • *.output: Contains the expected text output produced by the compiled program.
    • *.err: Contains the expected error message produced by the compiler when attempting to compile the code.

    Important constraints to avoid false failures:

    • No trailing empty lines: The test output must end exactly after the last meaningful line.
    • Trailing spaces: Avoid producing trailing spaces in your .bas output. If your code uses formatted output that produces trailing spaces, those exact spaces must be present in your *.output or *.err file.

    Optional configuration files:

    • *.flags: The contents of this file are passed as command-line arguments to the QB64-PE compiler during the test.
    • *.noprompt: Overrides the default QB64PE_NOPROMPT=y setting. The contents of this file are used as the value for the QB64PE_NOPROMPT environment variable when running the test executable. This is useful for testing 'Continue' behavior.
    • *.compile-from-base: If present, the test will compile the .bas file from the compiler's directory instead of the .bas file's directory (using the full path via -x).
    Example directory structure:
    ./tests/compile_tests/category_name/
    ├── test1.bas
    ├── test1.output
    ├── test2.bas
    └── test2.err
  8. Comply with QB64 Phoenix Edition licensing requirements

    main

    QB64-PE uses many third-party libraries that are statically linked into your compiled programs. To comply with their licenses when distributing your software, follow these guidelines:

    1. Permissive Licenses (MIT, Public Domain, zlib, etc.): Most libraries used by QB64-PE fall into this category. You can satisfy their requirements by simply distributing the license files found in the ./licenses folder of the QB64-PE repository along with your compiled program.
    2. Conditional Compilation: QB64-PE only compiles in third-party libraries if your code actually uses the corresponding functionality. If you do not use a specific feature (e.g., you never call _OPENCLIENT()), the associated library is not compiled into your program, and you do not need to meet its license requirements.
    3. Static Linking Note: All third-party libraries are statically linked. This means they become part of your executable, making the inclusion of their license files necessary.
  9. Create and run C++-based tests for libqb

    main

    C++ tests are used to verify libqb functionality. They are located in ./tests/c/ and consist of .cpp files, each containing its own main() function.

    Development Workflow:

    1. Implementation: Use test.h within your .cpp files to manage test execution and ensure proper output formatting. Failure is signaled via the program's exit code.
    2. Linking: When testing libqb functionality, ensure you link the necessary object files into your test executable.
    3. Building: Use the ./tests/build.mk make logic to compile tests. You can define individual compiler flags for each specific test.
    4. Execution: Run the ./tests/run_c_tests.sh script. This script expects that you have already built the tests using make build-tests. It iterates through a predefined list of test executables and checks their exit codes.
    # Build the tests first
    make build-tests
    
    # Run the C++ test suite
    ./tests/run_c_tests.sh