Cross-platform C/C++ Development with Conan

Conan is an open source and multi-platform package manager to create and share native binaries (mostly C and C++). It is written in Python and supports Windows, Linux, and Mac.

Besides managing dependencies, conan simplifies development process by int…

Conan is an open source and multi-platform package manager to create and share native binaries (mostly C and C++). It is written in Python and supports Windows, Linux, and Mac.

Besides managing dependencies, conan simplifies development process by integrating with various build tools. I touched on its most basic usage in tandem with cmake in my previous blog-post titled “Building HTTP Service in C++”. However, that post aimed primary towards Mac and Linux users, and developers using Windows platform were left aside.

Today, let’s see how we can use conan to manage cross-platform development.

Let’s start by creating a conanfile. Instead of using plaintext file, like in the HTTP service post, we use a Python script. Conan has ability to work with both types.

conanfile.py

from conans import ConanFile, CMake, tools

class MyApp(ConanFile):
    name = "my_app"
    version = "1.0"
    license = "unlicensed"
    author = "Artem Akatev"
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}
    generators = "cmake"
    requires = "boost/1.75.0"

    def config_options(self):
        if self.settings.os == "Windows":
            del self.options.fPIC

    def build(self):
        cmake = CMake(self)
        cmake.configure(source_folder="src")
        cmake.build()

Two important directives in the file are generators and requires. The first one contains a list of build tools, and the second a list of all dependencies. Both lists are comma delimited.

The build section (Python function) contains cmake configuration. The cmake is set to expect CMakeLists.txt file in src folder, so let’s create the file.

src/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)
project(my_app)

add_definitions("-std=c++11")

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

add_executable(my_app main.cc)
target_link_libraries(my_app ${CONAN_LIBS})

Now we need some application to compile. I will “steal” an example of HTTP client from Boost Beast.


#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <iostream>
#include <string>

namespace beast = boost::beast;     // from <boost/beast.hpp>
namespace http = beast::http;       // from <boost/beast/http.hpp>
namespace net = boost::asio;        // from <boost/asio.hpp>
using tcp = net::ip::tcp;           // from <boost/asio/ip/tcp.hpp>

// Performs an HTTP GET and prints the response
int main(int argc, char** argv)
{
    try
    {
        // Check command line arguments.
        if(argc != 4 && argc != 5)
        {
            std::cerr <<
                "Usage: http-client-sync <host> <port> <target> [<HTTP version: 1.0 or 1.1(default)>]\n" <<
                "Example:\n" <<
                "    http-client-sync www.example.com 80 /\n" <<
                "    http-client-sync www.example.com 80 / 1.0\n";
            return EXIT_FAILURE;
        }
        auto const host = argv[1];
        auto const port = argv[2];
        auto const target = argv[3];
        int version = argc == 5 && !std::strcmp("1.0", argv[4]) ? 10 : 11;

        // The io_context is required for all I/O
        net::io_context ioc;

        // These objects perform our I/O
        tcp::resolver resolver(ioc);
        beast::tcp_stream stream(ioc);

        // Look up the domain name
        auto const results = resolver.resolve(host, port);

        // Make the connection on the IP address we get from a lookup
        stream.connect(results);

        // Set up an HTTP GET request message
        http::request<http::string_body> req{http::verb::get, target, version};
        req.set(http::field::host, host);
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);

        // Send the HTTP request to the remote host
        http::write(stream, req);

        // This buffer is used for reading and must be persisted
        beast::flat_buffer buffer;

        // Declare a container to hold the response
        http::response<http::dynamic_body> res;

        // Receive the HTTP response
        http::read(stream, buffer, res);

        // Write the message to standard out
        std::cout << res << std::endl;

        // Gracefully close the socket
        beast::error_code ec;
        stream.socket().shutdown(tcp::socket::shutdown_both, ec);

        // not_connected happens sometimes
        // so don't bother reporting it.
        //
        if(ec && ec != beast::errc::not_connected)
            throw beast::system_error{ec};

        // If we get here then the connection is closed gracefully
    }
    catch(std::exception const& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Next, open a terminal window in the project’s root directory (same as the directory containing conanfile.py), and follow these steps to build and run the application:

1. Install build dependencies

conan install . --install-folder build

2. Build binary

conan install . --install-folder build

Run your application

Mac and Linux

./build/bin/my_app google.com 443

Windows

build\bin\my_app.exe google.com 443

Print Share Comment Cite Upload Translate
APA
Artem | Sciencx (2024-03-28T22:41:22+00:00) » Cross-platform C/C++ Development with Conan. Retrieved from https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/.
MLA
" » Cross-platform C/C++ Development with Conan." Artem | Sciencx - Saturday March 13, 2021, https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/
HARVARD
Artem | Sciencx Saturday March 13, 2021 » Cross-platform C/C++ Development with Conan., viewed 2024-03-28T22:41:22+00:00,<https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/>
VANCOUVER
Artem | Sciencx - » Cross-platform C/C++ Development with Conan. [Internet]. [Accessed 2024-03-28T22:41:22+00:00]. Available from: https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/
CHICAGO
" » Cross-platform C/C++ Development with Conan." Artem | Sciencx - Accessed 2024-03-28T22:41:22+00:00. https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/
IEEE
" » Cross-platform C/C++ Development with Conan." Artem | Sciencx [Online]. Available: https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/. [Accessed: 2024-03-28T22:41:22+00:00]
rf:citation
» Cross-platform C/C++ Development with Conan | Artem | Sciencx | https://www.scien.cx/2021/03/13/cross-platform-c-c-development-with-conan/ | 2024-03-28T22:41:22+00:00
https://github.com/addpipe/simple-recorderjs-demo