☠️
smadi0x86 Playground
  • 💀Welcome to smadi0x86 Playground
    • 🍷Resources
    • 🚬Projects
    • 🎓Certifications
    • 📌Pinned
    • ❓Questions
    • 📞Contact
  • 🏞️Cloud Native
    • Docker
      • Quick Reference
      • Introduction
      • Containers
      • Images
      • Storage & Volumes
      • Security
      • Cheatsheet
    • Git
    • Serverless Framework
    • YAML
  • 🔨Software Engineering
    • System Design
    • Environment Variables
    • JSON Web Tokens
  • 👾Architecture
    • C Language
      • Introduction
      • Calling Conventions
      • GCC Compilation
      • Libraries & Linking
      • I/O
      • Files
      • Pointers
      • Dynamic Memory Allocation
      • Data Types
      • Strings Manipulation
      • Bit Manipulation
      • Pre-processors
      • Macros
      • Type Qualifiers
    • C/C++ Build Systems
      • Fundamentals for Linking
      • Symbolic Linking
      • Cross-Platform Compilation
      • CMake for Building and Linking
      • Shared Libraries
      • Dynamic Linking and Dependency Management
    • Operating Systems
      • OS & Architecture
      • Processes
      • CPU Scheduling
      • Memory Management
  • 🛩️Cyber Warfare
    • Flight Physics
    • Communication
      • PWM & PPM
      • MAVLink
  • 🏴‍☠️Offensive Security
    • Active Directory
      • Introduction
    • Web Attacks
      • Server Side
        • OS Command Injection
        • Information Disclosure
        • Directory Traversal
        • Business Logic
        • Authentication
        • File Upload
        • SSRF
      • Client Side
        • CSRF
        • XSS
    • Recon
      • Active
        • Host discovery
        • Nmap
        • Mass Scan
      • Passive
        • Metadata
      • Web Applications
        • Discovery
        • Subdomains & Directories
        • SSL Certs
        • CMS
        • WAF Detection
      • Firewall Evasion
  • Binary Exploitation
    • Stack Smashing
      • x86
      • x86_64
    • pwntools
      • Processes and Communication
      • Logging and Context
      • Cyclic
      • Packing
      • ELF
      • ROP
  • 😈Advanced Persistent Threat
    • C2
      • Sliver
    • Malware
      • Windows Internals
        • PEB
      • Academy
        • Basics
      • Sektor7
        • Essentials
  • 💌Certifications
    • AWS Certified Cloud Practitioner (CLF-C01)
      • Cloud Foundations
      • Domain 1: Cloud Concepts
      • Domain 2: Security and Compliance
      • Domain 3: Technology
      • Domain 4: Billing and Pricing
    • AWS Certified Solutions Architect - Associate (SAA-C03)
      • Foundation
    • Certified Kubernetes Administrator (CKA)
      • Core Concepts
      • Scheduling
      • Logging & Monitoring
      • Application Lifecycle Management
      • Cluster Maintenance
      • Security
      • Storage
      • Networking
      • Design Kubernetes Cluster
      • Kubernetes The Kubeadm Way
      • Troubleshooting
      • JSONPATH
      • Lightning Lab
      • Mock Exams
      • Killer Shell
    • Certified Kubernetes Security (CKS)
      • Foundation
      • Cluster Setup
      • Cluster Hardening
      • Supply Chain Security
      • Runtime Security
      • System Hardening
      • Killer Shell
    • (KGAC-101) Kong Gateway Foundations
      • Introduction to APIs and API Management
      • Introduction to Kong Gateway
      • Getting Started with Kong Enterprise
      • Getting Started with Kong Konnect
      • Introduction to Kong Plugins
  • 📜Blog Posts
    • Modern Solutions For Preventing Ransomware Attacks
Powered by GitBook
On this page
  • Project Setup
  • Building a Simple Static Library
  • Building an Executable and Linking with the Static Library
  • Building a Shared Library
  • Linking with External Libraries using find_package
  • Advanced Linking Options and Flags
  • Visibility Control
  • Cross-Platform Considerations
  1. Architecture
  2. C/C++ Build Systems

CMake for Building and Linking

PreviousCross-Platform CompilationNextShared Libraries

CMake is a powerful cross-platform build system that simplifies building C/C++ projects, especially when it comes to managing libraries and linking.

Here's a comprehensive look at using CMake for building and linking, complete with examples:

Project Setup

  • Create a directory for your project.

  • Inside the project directory, create a file named CMakeLists.txt. This is the heart of your CMake configuration.

  • Create a build directory

  • Write your CMakeLists.txt

  • Move to build directory

  • Run cmake ..

  • Run make

Refer to CMake documentation for specific library names and linking instructions.

Create a separate build directory and run cmake there.

Building a Simple Static Library

# Minimum required CMake version
cmake_minimum_required(VERSION 3.0)

# Project name
project(MyStaticLib)

# Create a static library
add_library(MyStaticLib STATIC source1.cpp source2.cpp)

Explanation:

  • cmake_minimum_required(VERSION 3.0): This line specifies the minimum required version of CMake for this project.

  • project(MyStaticLib): This line defines the project name, which is used for generating build files.

  • add_library(MyStaticLib STATIC source1.cpp source2.cpp): This line creates a static library named MyStaticLib from the source files source1.cpp and source2.cpp.

Building an Executable and Linking with the Static Library

# Include the library directory
target_include_directories(MyProgram PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")

# Create an executable
add_executable(MyProgram main.cpp)

# Link the executable with the static library
target_link_libraries(MyProgram PRIVATE MyStaticLib)

Explanation:

  • target_include_directories(MyProgram PRIVATE "${CMAKE_CURRENT_BINARY_DIR}"): This line tells the compiler where to find header files. Since the static library might have headers, we include the current binary directory (where the library is built) in the search path.

  • add_executable(MyProgram main.cpp): This line creates an executable named MyProgram from the source file main.cpp.

  • target_link_libraries(MyProgram PRIVATE MyStaticLib): This line links the executable MyProgram with the previously created static library MyStaticLib. The PRIVATE keyword indicates that the library is private to this project and shouldn't be exposed to other projects linking against this executable.

Building a Shared Library

# Create a shared library
add_library(MySharedLib SHARED source1.cpp source2.cpp)

Explanation:

This line is similar to creating a static library, but instead of STATIC, we use SHARED to create a shared library named MySharedLib.

Linking with External Libraries using find_package

# Find an external library (replace with the actual library)
find_package(Threads REQUIRED)

# Include the library directory
target_include_directories(MyProgram PRIVATE "${CMAKE_THREAD_INCLUDE_DIRS}")

# Link the executable with the external library
target_link_libraries(MyProgram PRIVATE Threads::Threads)

Explanation:

  • find_package(Threads REQUIRED): This line attempts to find a package named Threads (replace with the actual library name, like OpenSSL or SDL2). The REQUIRED keyword ensures CMake throws an error if the library is not found.

  • target_include_directories(MyProgram PRIVATE "${CMAKE_THREAD_INCLUDE_DIRS}"): This line includes the library's header directory (CMAKE_THREAD_INCLUDE_DIRS) in the search path for MyProgram.

  • target_link_libraries(MyProgram PRIVATE Threads::Threads): This line links the executable with the external library's target (Threads::Threads).

Advanced Linking Options and Flags

Visibility Control

You can control which symbols from a library are visible to linked programs using compiler flags like -fvisibility=hidden (GCC) or /DEF:{symbol} (MSVC).

CMake can help manage these flags through target properties:

if(CMAKE_C_COMPILER_ID MATCHES "GNU")
  target_compile_properties(MyLib PROPERTIES CVISIBILITY_PRESET "hidden")
endif()

Explanation:

  • The if statement checks the compiler ID.

  • If it's GCC, target_compile_properties sets the CVISIBILITY_PRESET property to "hidden" for the target MyLib, effectively hiding symbols by default.

  • Custom Linker Flags: You can pass custom linker flags using target_link_libraries with the LINK_OPTIONS clause:

target_link_libraries(MyProgram PRIVATE MyLib LINK_OPTIONS "-Wl,-rpath,/path/to/additional/libraries")

Explanation:

  • This line links the program MyProgram with MyLib and adds the linker flag -Wl,-rpath,/path/to/additional/libraries, specifying an additional search path for libraries at runtime.

Cross-Platform Considerations

  • Toolchain Files: CMake allows defining toolchain files that specify compiler and linker settings for different platforms. This enables consistent builds across operating systems.

  • Platform-Specific Flags: Be mindful of platform-specific compiler and linker flags. CMake can handle some of these through built-in properties like CMAKE_CXX_FLAGS or CMAKE_EXE_LINKER_FLAGS, but you might need to add custom flags for specific needs.

Example of a cross platform build:

cmake_minimum_required(VERSION 3.0)

project(MyMultithreadedApp)

# Find pthread library (replace with the actual find_package call for your target platform)
find_package(Threads REQUIRED)

# Include directories (adjust based on your header locations)
target_include_directories(MyProgram PRIVATE
  "${CMAKE_CURRENT_BINARY_DIR}"  # Include current directory for project headers
  "${CMAKE_THREAD_INCLUDE_DIRS}"  # Include directory from Threads package
)

# Source files (replace with your actual source files)
add_executable(MyProgram main.cpp worker.cpp)

# Link with pthread library
target_link_libraries(MyProgram PRIVATE Threads::Threads)

# Platform-specific flags (optional)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
  target_link_libraries(MyProgram PRIVATE "-lpthread")  # Link with pthread on Linux
endif()

if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
  target_link_libraries(MyProgram PRIVATE "-framework pthread")  # Link with pthread on macOS
endif()

Explanation:

  1. CMake Minimum Version: We specify the minimum required CMake version.

  2. Project Name: We define the project name.

  3. Finding Threads Library: We use find_package(Threads REQUIRED) to attempt finding the pthread library. This might require replacing Threads with the actual package name for your target platform (e.g., PkgConfig on some Linux distributions).

  4. Include Directories: We set the include directories for our project headers and the headers from the Threads package.

  5. Source Files: We define the source files for our application.

  6. Linking with Threads: We link the executable MyProgram with the target Threads::Threads from the found library.

  7. Platform-Specific Flags (Optional): We use conditional statements to add platform-specific linker flags. On Linux, we link with -lpthread, and on macOS, we link with the -framework pthread framework.

👾
cmake-buildsystem(7) — CMake 3.29.2 Documentation
Logo
cmake — cppcheatsheet