Example of a Cross-Platform CMake Project Structure

Directory Structure


MyApp/
├── CMakeLists.txt
├── cmake/
│   ├── openssl.cmake
│   ├── zlib.cmake
│   └── utils.cmake        
└── src/
    ├── CMakeLists.txt
    └── main.cpp

Top-Level CMakeLists.txt

The main CMake file includes modular scripts and sets up imported targets for third-party dependencies.

cmake_minimum_required(VERSION 3.20)
project(MyApp LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

include(openssl)
include(zlib)

add_subdirectory(src)

cmake/openssl.cmake

This script attempts to locate OpenSSL via system packages or fallback paths and creates imported targets.

# Ensure OpenSSL::SSL and OpenSSL::Crypto are available

cmake_policy(PUSH)
cmake_policy(SET CMP0074 NEW)
find_package(OpenSSL QUIET)
cmake_policy(POP)

if(OpenSSL_FOUND)
  message(STATUS "[3rdparty] Using system OpenSSL: ${OPENSSL_VERSION}")
  return()
endif()

message(STATUS "[3rdparty] System OpenSSL not found, using fallback")

set(OPENSSL_ROOT "" CACHE PATH "Root directory of OpenSSL (optional)")

set(_OPENSSL_HINTS)
if(OPENSSL_ROOT)
  list(APPEND _OPENSSL_HINTS "${OPENSSL_ROOT}")
endif()

if(WIN32)
  list(APPEND _OPENSSL_HINTS "C:/OpenSSL-Win64" "C:/Program Files/OpenSSL-Win64")
elseif(APPLE)
  list(APPEND _OPENSSL_HINTS "/opt/homebrew/opt/openssl@3" "/usr/local/opt/openssl@3")
else()
  list(APPEND _OPENSSL_HINTS "/usr" "/usr/local")
endif()

find_path(OPENSSL_INCLUDE_DIR
  NAMES openssl/ssl.h
  HINTS ${_OPENSSL_HINTS}
  PATH_SUFFIXES include
  REQUIRED)

find_library(OPENSSL_SSL_LIBRARY
  NAMES ssl libssl
  HINTS ${_OPENSSL_HINTS}
  PATH_SUFFIXES lib lib64
  REQUIRED)

find_library(OPENSSL_CRYPTO_LIBRARY
  NAMES crypto libcrypto
  HINTS ${_OPENSSL_HINTS}
  PATH_SUFFIXES lib lib64
  REQUIRED)

add_library(OpenSSL::SSL UNKNOWN IMPORTED)
set_target_properties(OpenSSL::SSL PROPERTIES
  IMPORTED_LOCATION "${OPENSSL_SSL_LIBRARY}"
  INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}"
)

add_library(OpenSSL::Crypto UNKNOWN IMPORTED)
set_target_properties(OpenSSL::Crypto PROPERTIES
  IMPORTED_LOCATION "${OPENSSL_CRYPTO_LIBRARY}"
  INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}"
)

target_link_libraries(OpenSSL::SSL INTERFACE OpenSSL::Crypto)

cmake/zlib.cmake

This script attempts to locate zlib and creates an imported target for it.

# Ensure ZLIB::ZLIB is available

find_package(ZLIB QUIET)
if(ZLIB_FOUND)
  message(STATUS "[3rdparty] Using system ZLIB: ${ZLIB_VERSION}")
  return()
endif()

message(STATUS "[3rdparty] System ZLIB not found, using fallback")

set(ZLIB_ROOT "" CACHE PATH "Root directory of zlib (optional)")

set(_ZLIB_HINTS)
if(ZLIB_ROOT)
  list(APPEND _ZLIB_HINTS "${ZLIB_ROOT}")
endif()

if(WIN32)
  list(APPEND _ZLIB_HINTS "C:/zlib" "C:/Program Files/zlib")
else()
  list(APPEND _ZLIB_HINTS "/usr" "/usr/local" "/opt/homebrew")
endif()

find_path(ZLIB_INCLUDE_DIR
  NAMES zlib.h
  HINTS ${_ZLIB_HINTS}
  PATH_SUFFIXES include
  REQUIRED)

find_library(ZLIB_LIBRARY
  NAMES z zlib
  HINTS ${_ZLIB_HINTS}
  PATH_SUFFIXES lib lib64
  REQUIRED)

add_library(ZLIB::ZLIB UNKNOWN IMPORTED)
set_target_properties(ZLIB::ZLIB PROPERTIES
  IMPORTED_LOCATION "${ZLIB_LIBRARY}"
  INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIR}"
)

src/CMakeLists.txt

This file builds the main appplication and links it with imported targets.

add_executable(myapp main.cpp)

target_link_libraries(myapp
  PRIVATE
    OpenSSL::SSL
    OpenSSL::Crypto
    ZLIB::ZLIB
)

src/main.cpp

A simple test applicatoin that uses OpenSSL and zlib.

#include <iostream>
#include <zlib.h>
#include <openssl/ssl.h>

int main() {
    std::cout << "zlib version: " << zlibVersion() << std::endl;
#if defined(OPENSSL_VERSION_TEXT)
    std::cout << "OpenSSL: " << OPENSSL_VERSION_TEXT << std::endl;
#else
    std::cout << "OpenSSL present." << std::endl;
#endif
    return 0;
}

Usage Instructions

Using system librareis (recommended):

cmake -S . -B build -G "Ninja Multi-Config"
cmake --build build --config Release

Using custom root directories:

cmake -S . -B build -G "Ninja Multi-Config" \
  -DOPENSSL_ROOT="C:/OpenSSL-Win64" \
  -DZLIB_ROOT="C:/zlib"
cmake --build build --config Release

Tags: CMake openssl zlib cross-platform

Posted on Fri, 21 Aug 2026 16:10:15 +0000 by nawal