Alex079 / vscode-avr-helper

Helper extension to simplify code compilation and flashing for AVR chips
MIT License
12 stars 1 forks source link

C++20 modules support #50

Open leonty opened 3 months ago

leonty commented 3 months ago

Right now the extension performs file scan and dependency resolution by its own means but this doesn't work with c++ modules. C++ modules make it possible to implement program structure without header files (java-like structure) and this introduce another limitation on the compiling process - order is important now because the compiler creates CMI (compiled module interface, kind of cached information of the exported module types, variables and functions) and this CMI is mandatory to compile dependent modules. The -MM option of the compiler doesn't work with modules. There's -MMD option that can recognize modules but it also must be called with correct order (from independent modules to dependent). The only working solution is to use newer gcc-14 that has new flags -fdeps-format=, -fdeps-file=, and -fdeps-target= that may be used to generate dependency information in P1689R5 format (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html). I'm not sure if it still worth to parse that manually. Maybe it's more reasonable to implement build process with the help of CMake which has c++20 modules suport (with the help of gcc14 of course). I came across with this issue while converting my small project for ATMega8 into c++20 modules format.

Alex079 commented 3 months ago

Do you have an example of such a project?

leonty commented 3 months ago

3 files example project (resembling my project structure): i2c module implements avr i2c communication, isl1208 module implements communication with isl1208 rtc module via i2c and the main function. The compilation must be performed in in the only order: i2c, isl1208, main. After compilation of each module the compiler created gcm.cache folder with compiled module interface that is used later to compile dependent modules. Ordered commands to build the project: avr-g++ -fmodules-ts -std=c++23 -c i2c.cpp avr-g++ -fmodules-ts -std=c++23 -c isl1208.cpp avr-g++ -fmodules-ts -std=c++23 -c main.cpp avr-g++ i2c.o isl1208.o main.o

I haven't got yet g

i2c.cpp

module;

#include <stdint.h>

export module i2c;

export namespace i2c
{
    void init() {}
    uint8_t read() { return 0; }
    void write(uint8_t byte) {}
}

isl1208.cpp

module;

#include <time.h>

export module isl1208;

import i2c;

export namespace isl1208 
{
    time_t get_time() 
    {
        time_t t;

        i2c::init();
        i2c::write(0);
        i2c::read();

        return t;
    }
}

main.cpp

#include <time.h>

import isl1208;

int main()
{
    while (true)
    {
        // delay(1000);
        time_t t = isl1208::get_time();
    }

    return 0;
}
leonty commented 3 months ago

Just found out that his combination of options on gcc13 is order independent and produces dependency information in 'Makefile' format: % avr-g++ -fmodules-ts -std=c++23 -MD -E isl1208.cpp % cat isl1208.d isl1208.o gcm.cache/isl1208.gcm: isl1208.cpp \ /opt/local/avr/include/time.h \ /opt/local/lib/gcc/avr/13.1.0/include/stdint.h \ /opt/local/avr/include/stdint.h /opt/local/avr/include/stdlib.h \ /opt/local/lib/gcc/avr/13.1.0/include/stddef.h isl1208.o gcm.cache/isl1208.gcm: i2c.c++m isl1208.c++m: gcm.cache/isl1208.gcm .PHONY: isl1208.c++m gcm.cache/isl1208.gcm:| isl1208.o CXX_IMPORTS += i2c.c++m

Though it still demands parsing to find out the order or using make and a custom Makefile including this generated dependencies to build the project (https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/).