为什么我会收到致命错误:“include/hwComms/port.h:没有这样的文件或目录#include <include/hwComms/port.h>”?

问题描述 投票:0回答:1

我正在做的项目是一个一步一步的操作系统。

我使用的是 Visual Studio Code 版本 1.85.1 和 Ubuntu 22.04.3 LTS。

当前我正在打开文件夹“Create_Your_Own_OS”,目标是使用 makefile 编译“Lesson9”。

文件夹结构如下:

Create_Your_Own_OS
└───Lesson1
└───Lesson2
└───Lesson3
└───Lesson4
└───Lesson5
└───Lesson6
└───Lesson7
└───Lesson8
└───Lesson9
│   └───include
│       └───common
│       │          types.h
│       └───drivers
│       │          driver.h
│       │          keyboard.h
│       │          mouse.h
│       └───hwComms
│       │          interrupt.h
│       │          port.h
│    └───src
│       └───common
│       │          types.cpp
│       └───drivers
│       │          driver.cpp
│       │          keyboard.cpp
│       │          mouse.cpp
│       └───hwComms
│       │          interrupt.cpp
│       │          port.cpp
│  
└───linker.ld
└───makefile

“Lesson9”的代码如下:

端口.h

#ifndef __MYOS__HWCOMMS__PORT_H
#define __MYOS__HWCOMMS__PORT_H

#include <common/types.h>

namespace myos
{
    namespace hwComms
    {

            class Port
            {
                protected:
                    Port(myos::common::uint16_t portnumber);
                    ~Port();
                    
                    myos::common::uint16_t portnumber;
            };

            class Port8bit: public Port
            {
                public:
                    Port8bit(myos::common::uint8_t portnumber);
                    ~Port8bit();
                    virtual void Write(myos::common::uint8_t portnumber);
                    virtual myos::common::uint8_t Read();

                protected:
                    static inline myos::common::uint8_t Read8(myos::common::uint16_t _port)
                    {
                        myos::common::uint8_t result;
                        __asm__ volatile("inb %1, %0" : "=a" (result) : "Nd" (_port));
                        return result;
                    }

                    static inline void Write8(myos::common::uint16_t _port, myos::common::uint8_t _data)
                    {
                        __asm__ volatile("outb %0, %1" : : "a" (_data), "Nd" (_port));
                    }
            };

            class SlowPort8bit : public Port8bit
            {
                public:
                    SlowPort8bit(myos::common::uint8_t portnumber);
                    ~SlowPort8bit();

                    virtual void Write(myos::common::uint8_t portnumber);

                protected:
                    static inline void Write8Slow(myos::common::uint16_t _port, myos::common::uint8_t _data)
                    {
                        __asm__ volatile("outb %0, %1\njmp 1f\n1: jmp 1f\n1:" : : "a" (_data), "Nd" (_port));
                    }
            };    

            class Port16bit : public Port
            {
                public:
                    Port16bit(myos::common::uint16_t portnumber);
                    ~Port16bit();
                    virtual void Write(myos::common::uint16_t portnumber);
                    virtual myos::common::uint16_t Read();

                protected:
                    static inline myos::common::uint16_t Read16(myos::common::uint16_t _port)
                    {
                        myos::common::uint16_t result;
                        __asm__ volatile("inw %1, %0" : "=a" (result) : "Nd" (_port));
                        return result;
                    }

                    static inline void Write16(myos::common::uint16_t _port, myos::common::uint16_t _data)
                    {
                        __asm__ volatile("outw %0, %1" : : "a" (_data), "Nd" (_port));
                    }
            };

            class Port32bit : public Port
            {
                public:
                    Port32bit(myos::common::uint32_t portnumber);
                    ~Port32bit();
                    virtual void Write(myos::common::uint32_t portnumber);
                    virtual myos::common::uint32_t Read();
                
                protected:
                    static inline myos::common::uint32_t Read32(myos::common::uint16_t _port)
                    {
                        myos::common::uint32_t result;
                        __asm__ volatile("inl %1, %0" : "=a" (result) : "Nd" (_port));
                        return result;
                    }

                    static inline void Write32(myos::common::uint16_t _port, myos::common::uint32_t _data)
                    {
                        __asm__ volatile("outl %0, %1" : : "a"(_data), "Nd" (_port));
                    }
            };
    }
}

#endif

端口.cpp


#include <include/hwComms/port.h>

using namespace myos::common;
using namespace myos::hwComms;


Port::Port(uint16_t portnumber)
{
    this->portnumber = portnumber;
}

Port::~Port()
{
}




Port8bit::Port8bit(uint8_t portnumber)
: Port(portnumber)
{
}

Port8bit::~Port8bit()
{
}

void Port8bit::Write(uint8_t data)
{
    Write8(portnumber, data);
}

uint8_t Port8bit::Read()
{
    return Read8(portnumber);
}




SlowPort8bit::SlowPort8bit(uint8_t portnumber)
: Port8bit(portnumber)
{
}

SlowPort8bit::~SlowPort8bit()
{
}

void SlowPort8bit::Write(uint8_t data)
{
    Write8Slow(portnumber, data);
}




Port16bit::Port16bit(uint16_t portnumber)
: Port(portnumber)
{
}

Port16bit::~Port16bit()
{
}

void Port16bit::Write(uint16_t data)
{
    Write16(portnumber, data);
}

uint16_t Port16bit::Read()
{
    return Read16(portnumber);
}




Port32bit::Port32bit(uint32_t portnumber)
: Port(portnumber)
{
}

Port32bit::~Port32bit()
{
}

void Port32bit::Write(uint32_t data)
{
    Write32(portnumber, data);
}

uint32_t Port32bit::Read()
{
    return Read32(portnumber);
}

生成文件

GPPARAMS = -m32 -Iinclude -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wno-write-strings
ASPARAMS = --32
LDPARAMS = -melf_i386

objects = obj/loader.o \
obj/gdt.o \
obj/drivers/driver.o \
obj/hwComms/port.o \
obj/hwComms/interruptstubs.o \
obj/hwComms/interrupts.o \
obj/drivers/keyboard.o \
obj/drivers/mouse.o \
obj/kernel.o

obj/%.o: src/%.cpp
mkdir -p $(@D)
gcc $(GPPARAMS) -o $@ -c $\<

obj/%.o: src/%.s
mkdir -p $(@D)
as $(ASPARAMS) -o $@ $\<

mykernel.bin: linkder.ld $(objects)
ld $(LDPARAMS) -T $\< -o $@ $(objects)

install: mykernel.bin
sudo cp $\< /boot/mykernel.bin

mykernel.iso: mykernel.bin
mkdir iso
mkdir iso/boot
mkdir iso/boot/grub
cp $\< iso/boot/mykernel.bin
echo 'set timeout=0'                       \> iso/boot/grub/grub.cfg
echo 'set default=0'                      \>\> iso/boot/grub/grub.cfg
echo ''                                   \>\> iso/boot/grub/grub.cfg
echo 'menuentry "My Operating System" {'  \>\> iso/boot/grub/grub.cfg
echo '  multiboot /boot/mykernel.bin'     \>\> iso/boot/grub/grub.cfg
echo '  boot'                             \>\> iso/boot/grub/grub.cfg
echo '}'                                  \>\> iso/boot/grub/grub.cfg
grub-mkrescue --output=$@ iso
rm -rf iso
rm ../mykernel.iso
cp $@ ../

run: mykernel.iso
VBoxManage controlvm My_OS poweroff || true
sleep 3 && VBoxManage startvm My_OS

.PHONY: clean
clean:
rm -rf obj mykernel.bin mykernel.iso

要编译“Lesson9”,我进入“Lesson9”的目录并在终端中执行“make”。输出是这样的:

~/Desktop/OS_Development/OS_C/Build_Your_Own_OS/Lesson_9/myos$ make
mkdir -p obj/hwComms
gcc -m32 -Iinclude -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wno-write-strings -o obj/hwComms/port.o -c src/hwComms/port.cpp
src/hwComms/port.cpp:2:10: fatal error: include/hwComms/port.h: No such file or directory
    2 | #include <include/hwComms/port.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [makefile:18: obj/hwComms/port.o] Error 1

我解决该问题的尝试如下:

  1. 更改为

    1. “包括/hwComms/port.h”

    2. “myos/include/hwComms/port.h”

这些尝试都没有成功。我相信可能需要设置一个环境变量。

理想情况下,我想在 makefile 中设置该变量。

c++ makefile operating-system
1个回答
0
投票

如何找到要包含的文件?您将 #include <...> 中指定的路径

append
-I
中指定的路径,如果后者是相对的,则将 that 附加到编译器的当前工作目录。如果您有很多
-I
,请依次尝试每一个。如果您有
#include "..."
,请先尝试源文件本身所在的目录,然后搜索用
-I
指定的目录。

现在让我们将其应用到您的示例中。

您将

-Iinclude
传递给
gcc
。您的源文件位于
src/hwComms

  • #include <include/hwComms/port.h>
    有用吗?不,因为任何地方都没有
    include/include/hwComms/port.h
  • #include <myos/include/hwComms/port.h>
    有用吗?不,因为任何地方都没有
    include/myos/include/hwComms/port.h
  • #include "include/hwComms/port.h"
    有用吗?不,因为既没有
    src/hwComms/include/hwComms/port.h
    也没有
    include/include/hwComms/port.h
    任何地方。

我的建议:

  • 从您喜欢的包含指令的外观开始。例如,指定
    #include <include/....>
    毫无意义,目录名称
    include
    不传达任何信息。更喜欢
    #include <hwComms/port.h>
    #include <myos/hwComms/port.h>
  • 确保您的项目顶级目录(例如
    hwComms/port.h
    )的
    myos/hwComms/port.h
    子目录下有所有头文件(例如
    include
    Lesson9
    ,具体取决于您选择的样式)。所以你会有例如
    Lesson9/include/myos/hwComms/port.h
  • 从项目的顶级目录启动
    gcc
    (第 9 课)。
  • -Iinclude
    传递给它。
  • 或者,指定 absolute 路径(例如
    -I/home/yourname/Desktop/OS_Development/OS_C/Build_Your_Own_OS/Lesson_9/include
    )并从您想要的任何目录启动
    gcc
© www.soinside.com 2019 - 2024. All rights reserved.