C++ Include Paths: #include "..." vs <...>, -I, and CMake

C++ Include Paths: #include "..." vs <...>, -I, and CMake

이 글의 핵심

Include paths define where the preprocessor finds headers. This guide covers <> vs "", -I flags, search order, CMake, and common include mistakes.

Introduction

Broken builds and wrong headers usually start with include search path configuration. This article explains "" vs <>, how to add -I paths per toolchain, and how to structure projects for clarity.

Include paths are the directories the preprocessor searches for headers.


1. What is an include path?

Basics

#include <iostream>   // system / toolchain paths
#include "myheader.h" // often project-relative first

Rough mental model:

  • <>: standard and system headers
  • "": project headers (still needs correct -I or relative path)

2. Search order (typical)

#include "file.h"

  1. Directory of the file containing the #include
  2. Paths from -I (in order)
  3. System paths

#include <file.h>

  1. -I paths (in order)
  2. System paths

(Exact rules depend on the compiler; treat this as a practical model.)


3. Examples

Basic usage

#include <iostream>
#include <vector>
#include <string>

#include "myclass.h"
#include "utils.h"

Compiler flags

g++ -I./include main.cpp
g++ -I./include -I./lib/include main.cpp
g++ -I../common/include main.cpp

Project layout

project/
├── include/
│   ├── myclass.h
│   └── utils.h
├── src/
│   ├── main.cpp
│   ├── myclass.cpp
│   └── utils.cpp
└── build/
g++ -I./include src/main.cpp src/myclass.cpp -o build/myapp

CMake

cmake_minimum_required(VERSION 3.10)
project(MyApp)

include_directories(${CMAKE_SOURCE_DIR}/include)

add_executable(myapp src/main.cpp src/myclass.cpp)

target_include_directories(myapp PRIVATE
    ${CMAKE_SOURCE_DIR}/include
)

4. Inspecting system paths (GCC/Clang)

g++ -v -E -x c++ /dev/null
# or
echo | g++ -Wp,-v -x c++ - -fsyntax-only

5. Common problems

Problem 1: header not found

fatal error: myheader.h: No such file or directory

Fix: g++ -I./include main.cpp (or correct relative path).

Problem 2: brittle absolute paths

Prefer -I./include or ${CMAKE_SOURCE_DIR}/include.

Problem 3: -I order matters

Earlier -I wins when multiple trees contain the same filename.

Problem 4: name clashes

Use subdirectories in includes (e.g. #include "lib1/utils.h") or namespaces.


6. Environment variables

export CPLUS_INCLUDE_PATH=/usr/local/include
g++ main.cpp

7. External library example

g++ -I./include -I./external/json src/main.cpp -o myapp

Summary

  1. "" vs <> — project vs system conventions
  2. -I adds search directories
  3. Order matters for shadowing
  4. CMake automates paths
  5. Verify with -v when debugging

Next: Header files, CMake, Compilation process.


  • C++ Header Files
  • C++ Header Guards
  • C++ include errors
  • C++20 Modules
  • C++ path