add example with docs
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
build
|
||||||
|
.cache
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
project(core CXX)
|
||||||
|
|
||||||
|
find_package(fmt REQUIRED)
|
||||||
|
find_package(range-v3 REQUIRED)
|
||||||
|
find_package(cxxopts REQUIRED)
|
||||||
|
find_package(Protobuf CONFIG REQUIRED)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
add_library(core STATIC
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/protocol/messenger/messenger.proto"
|
||||||
|
fib.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROTO_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
|
||||||
|
target_include_directories(core
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
"$<BUILD_INTERFACE:${PROTO_BINARY_DIR}>"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(core
|
||||||
|
PRIVATE
|
||||||
|
fmt::fmt
|
||||||
|
range-v3::range-v3
|
||||||
|
cxxopts::cxxopts
|
||||||
|
PUBLIC
|
||||||
|
protobuf::libprotobuf
|
||||||
|
)
|
||||||
|
|
||||||
|
protobuf_generate(
|
||||||
|
TARGET core
|
||||||
|
IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/protocol"
|
||||||
|
PROTOC_OUT_DIR "${PROTO_BINARY_DIR}"
|
||||||
|
)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Overview
|
||||||
|
This repository serves as a complex example of how C++ tooling and cross-compilation works.
|
||||||
|
|
||||||
|
## The challenge
|
||||||
|
The variables at play:
|
||||||
|
* Protoc used to generate C++ files
|
||||||
|
* Compilation of the generated C++ files & other library/source files.
|
||||||
|
* Linking the correct protobuf runtime library for the target machine.
|
||||||
|
|
||||||
|
`protoc` from any host machine can generate portable C++ files (.cpp and .h). However, the version of protoc that is used must match the _protobuf runtime library_ that is used.
|
||||||
|
|
||||||
|
For example, the generated header will have something like this:
|
||||||
|
```cpp
|
||||||
|
#include "google/protobuf/runtime_version.h"
|
||||||
|
#if PROTOBUF_VERSION != 5029003
|
||||||
|
#error "Protobuf C++ gencode is built with an incompatible version of"
|
||||||
|
#error "Protobuf C++ headers/runtime. See"
|
||||||
|
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
If we are trying to build an application for arm64 from a x86_64 machine, the protobuf runtime library that we use _must_ be for that target (AND still match the protoc version that we used to generate the C++ files from `.proto`). This is why we use vcpkg.
|
||||||
|
|
||||||
|
|
||||||
|
See [here](https://claude.ai/share/c6c6394d-b9b4-41b4-9146-265682223174) for in-depth conversation with claude.
|
||||||
|
|
||||||
|
|
||||||
|
## The solution
|
||||||
|
```sh
|
||||||
|
./build.sh # build for applications meant only for the host machine
|
||||||
|
./cross-compile-for-ios.sh # uses ios/arm64 toolchain to compile all protoc generated C++ as well as other library files. More importantly, it also ensures that it compiles (or pulls from vcpkg cache) the correct protobuf runtime version for arm64.
|
||||||
|
```
|
||||||
|
|
||||||
|
Please look into the scripts to see how it all comes together.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
I had an issue with vcpkg whereby the protobuf was conflicting between host machine one and the target machine one. So I had to add the cmake flag `-DVCPKG_BINARY_SOURCES=clear`.
|
||||||
|
|
||||||
|
See [this issue](https://github.com/microsoft/vcpkg/issues/44517#issuecomment-2816462459) that I posted.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
rm -rf build
|
||||||
|
cmake -Bbuild -S. -GNinja \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake \
|
||||||
|
-DVCPKG_BINARY_SOURCES=clear \
|
||||||
|
-DVCPKG_INSTALL_OPTIONS="--debug"
|
||||||
|
|
||||||
|
cmake --build build/
|
||||||
Executable
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
echo "THIS SERVES AS AN EXAMPLE OF HOW TO CROSS COMPILE THIS FOR USE ON IOS"
|
||||||
|
|
||||||
|
# NOTE: DVCPKG_TARGET_ARCHITECTURE is for a setting within the set DVCPKG_CHAINLOAD_TOOLCHAIN_FILE
|
||||||
|
# if using another toolchain or none at all, consider using the following native cmake variables
|
||||||
|
# - CMAKE_OSX_SYSROOT
|
||||||
|
# - CMAKE_OSX_DEPLOYMENT_TARGET
|
||||||
|
# - CMAKE_OSX_ARCHITECTURES
|
||||||
|
# - MACOSX_BUNDLE_GUI_IDENTIFIER
|
||||||
|
# - ...
|
||||||
|
# Qt has toolchain files that take care of these sorts of things, as does `vcpkg` as shown below
|
||||||
|
|
||||||
|
rm -rf build
|
||||||
|
cmake -Bbuild -S. -GNinja \
|
||||||
|
-DVCPKG_TARGET_TRIPLET=arm64-ios \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake \
|
||||||
|
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/ios.cmake \
|
||||||
|
-DVCPKG_TARGET_ARCHITECTURE=arm64 \
|
||||||
|
-DVCPKG_BINARY_SOURCES=clear \
|
||||||
|
-DVCPKG_INSTALL_OPTIONS="--debug"
|
||||||
|
|
||||||
|
|
||||||
|
cmake --build build/
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include <cxxopts.hpp>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <range/v3/view.hpp>
|
||||||
|
|
||||||
|
namespace view = ranges::views;
|
||||||
|
|
||||||
|
int fib(int x) {
|
||||||
|
int a = 0, b = 1;
|
||||||
|
|
||||||
|
for (int it : view::repeat(0) | view::take(x)) {
|
||||||
|
(void)it;
|
||||||
|
int tmp = a;
|
||||||
|
a += b;
|
||||||
|
b = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
syntax="proto3";
|
||||||
|
package messenger;
|
||||||
|
|
||||||
|
service HelloService {
|
||||||
|
rpc SayHello(SayHelloRequest) returns (SayHelloResponse) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
message SayHelloRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
message SayHelloResponse {
|
||||||
|
string message = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"dependencies": [
|
||||||
|
"cxxopts",
|
||||||
|
"fmt",
|
||||||
|
"range-v3",
|
||||||
|
"protobuf"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user