Skip to content

Commit

Permalink
cmake: build single-file-header with cmake
Browse files Browse the repository at this point in the history
This also allows us to install headers with cmake, and completely
remove our `build.py` script.
  • Loading branch information
Riolku committed Nov 29, 2023
1 parent ff5e450 commit e2bf6f2
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 403 deletions.
26 changes: 13 additions & 13 deletions .github/workflows/linux-precompiled-bin-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ jobs:

- name: Build precompiled binaries
run: |
source /opt/rh/devtoolset-11/enable
/opt/python/cp310-cp310/bin/python build.py
working-directory: ./scripts/pre-compiled-bins/
make LTO=1
make install
- uses: actions/upload-artifact@v3
with:
name: libkuzu-linux-x86_64
path: |
./scripts/pre-compiled-bins/kuzu.h
./scripts/pre-compiled-bins/kuzu.hpp
./scripts/pre-compiled-bins/libkuzu.so
./install/include/kuzu.h
./install/include/kuzu.hpp
./install/lib64/libkuzu.so
- uses: actions/upload-artifact@v3
with:
name: kuzu_cli-linux-x86_64
path: ./scripts/pre-compiled-bins/kuzu
path: ./install/bin/kuzu

build-precompiled-bin-aarch64:
runs-on: kuzu-self-hosted-linux-building-aarch64
Expand All @@ -41,18 +40,19 @@ jobs:
run: /opt/python/cp310-cp310/bin/python -m pip install networkx --user

- name: Build precompiled binaries
run: /opt/python/cp310-cp310/bin/python build.py
working-directory: ./scripts/pre-compiled-bins/
run: |
make LTO=1
make install
- uses: actions/upload-artifact@v3
with:
name: libkuzu-linux-aarch64
path: |
./scripts/pre-compiled-bins/kuzu.h
./scripts/pre-compiled-bins/kuzu.hpp
./scripts/pre-compiled-bins/libkuzu.so
./install/include/kuzu.h
./install/include/kuzu.hpp
./install/lib/libkuzu.so
- uses: actions/upload-artifact@v3
with:
name: kuzu_cli-linux-aarch64
path: ./scripts/pre-compiled-bins/kuzu
path: ./install/bin/kuzu
26 changes: 14 additions & 12 deletions .github/workflows/mac-precompiled-bin-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ jobs:
run: python3 -m pip install networkx --user

- name: Build precompiled binaries for Apple Silicon
run: python3 build.py
working-directory: ./scripts/pre-compiled-bins/
run: |
make LTO=1
make install
env:
MACOSX_DEPLOYMENT_TARGET: 11.0
ARCHFLAGS: "-arch arm64"
Expand All @@ -24,14 +25,14 @@ jobs:
with:
name: libkuzu-osx-arm64
path: |
./scripts/pre-compiled-bins/kuzu.h
./scripts/pre-compiled-bins/kuzu.hpp
./scripts/pre-compiled-bins/libkuzu.dylib
./install/include/kuzu.h
./install/include/kuzu.hpp
./install/lib/libkuzu.dylib
- uses: actions/upload-artifact@v3
with:
name: kuzu_cli-osx-arm64
path: ./scripts/pre-compiled-bins/kuzu
path: ./install/bin/kuzu

build-precompiled-bin-x86_64:
runs-on: self-hosted-mac-x64
Expand All @@ -42,8 +43,9 @@ jobs:
run: python3 -m pip install networkx --user

- name: Build precompiled binaries for Intel
run: python3 build.py
working-directory: ./scripts/pre-compiled-bins/
run: |
make LTO=1
make install
env:
MACOSX_DEPLOYMENT_TARGET: 10.15
ARCHFLAGS: "-arch x86_64"
Expand All @@ -52,11 +54,11 @@ jobs:
with:
name: libkuzu-osx-x86_64
path: |
./scripts/pre-compiled-bins/kuzu.h
./scripts/pre-compiled-bins/kuzu.hpp
./scripts/pre-compiled-bins/libkuzu.dylib
./install/include/kuzu.h
./install/include/kuzu.hpp
./install/lib/libkuzu.dylib
- uses: actions/upload-artifact@v3
with:
name: kuzu_cli-osx-x86_64
path: ./scripts/pre-compiled-bins/kuzu
path: ./install/bin/kuzu
13 changes: 7 additions & 6 deletions .github/workflows/windows-precompiled-bin-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ jobs:
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
python.exe build.py
make LTO=1
make install
working-directory: ./scripts/pre-compiled-bins/

- uses: actions/upload-artifact@v3
with:
name: libkuzu-windows-x86_64
path: |
./scripts/pre-compiled-bins/kuzu.h
./scripts/pre-compiled-bins/kuzu.hpp
./scripts/pre-compiled-bins/kuzu_shared.dll
./scripts/pre-compiled-bins/kuzu_shared.lib
./install/include/kuzu.h
./install/include/kuzu.hpp
./install/lib/kuzu_shared.dll
./install/lib/kuzu_shared.lib
- uses: actions/upload-artifact@v3
with:
name: kuzu_cli-windows-x86_64
path: ./scripts/pre-compiled-bins/kuzu.exe
path: ./install/bin/kuzu.exe
5 changes: 3 additions & 2 deletions examples/c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_executable(example-c main.c)
target_link_libraries(example-c kuzu_shared)
add_executable(example_c main.c)
target_link_libraries(example_c kuzu_shared)
target_include_directories(example_c PRIVATE ${PROJECT_SOURCE_DIR}/src/include/c_api)
5 changes: 2 additions & 3 deletions examples/c/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
#include <stdio.h>
#include <stdlib.h>

#include "c_api/kuzu.h"
#include "kuzu.h"

int main() {
kuzu_database* db = kuzu_database_init("" /* fill db path */, kuzu_default_system_config());
kuzu_connection* conn = kuzu_connection_init(db);

kuzu_query_result* result;
// Create schema.
result = kuzu_connection_query(
kuzu_query_result* result = kuzu_connection_query(
conn, "CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY(name));");
kuzu_query_result_destroy(result);
// Create nodes.
Expand Down
6 changes: 4 additions & 2 deletions examples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
add_executable(example-cpp main.cpp)
target_link_libraries(example-cpp kuzu_shared)
add_executable(example_cpp main.cpp)
target_link_libraries(example_cpp kuzu_shared)
target_include_directories(example_cpp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
add_dependencies(example_cpp single_file_header)
2 changes: 1 addition & 1 deletion examples/cpp/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <iostream>

#include "main/kuzu.h"
#include "kuzu.hpp"
using namespace kuzu::main;

int main() {
Expand Down
91 changes: 91 additions & 0 deletions scripts/collect-single-file-header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
from __future__ import annotations

import graphlib
import os
import sys
import shutil
import logging

from typing import Optional
from pathlib import Path

logging.basicConfig(level=logging.WARNING)

SCRIPT_PATH = Path(__file__)
HEADER_BASE_PATH = (SCRIPT_PATH / "../../src/include").resolve()
MAIN_HEADER_PATH = HEADER_BASE_PATH / "main"
START_POINT = MAIN_HEADER_PATH / "kuzu.h"
JSON_HEADER_PATH = (
SCRIPT_PATH / "../../third_party/nlohmann_json/json_fwd.hpp"
).resolve()
OUTPUT_PATH = "kuzu.hpp"

logging.debug("HEADER_BASE_PATH: %s", HEADER_BASE_PATH)
logging.debug("MAIN_HEADER_PATH: %s", MAIN_HEADER_PATH)
logging.debug("START_POINT: %s", START_POINT)
logging.debug("JSON_HEADER_PATH: %s", JSON_HEADER_PATH)


def resolve_include(source_header: Path, include_path: str) -> Optional[Path]:
if include_path == "json_fwd.hpp":
return JSON_HEADER_PATH

current_directory_include = source_header.parent / include_path
if current_directory_include.exists():
return current_directory_include

main_directory_include = HEADER_BASE_PATH / include_path
if main_directory_include.exists():
return main_directory_include

return None


processed_headers = set()


def build_graph(graph: graphlib.TopologicalSorter, source_file: Path) -> None:
assert source_file.is_absolute()
global processed_headers
if source_file in processed_headers:
return
processed_headers.add(source_file)

with source_file.open("r") as f:
for line in f.readlines():
if not line.startswith('#include "'):
continue
header_path = line.split('"')[1]
header_real_path = resolve_include(source_file, header_path)
if header_real_path is None:
logging.error(f"Could not find {header_path} included in {source_file}")
sys.exit(1)
logging.debug(
f"Resolved {header_path} in {source_file} to {header_real_path}"
)
graph.add(source_file, header_real_path)
build_graph(graph, header_real_path)


def create_merged_header():
graph = graphlib.TopologicalSorter()
logging.info("Building dependency graph...")
build_graph(graph, START_POINT)
logging.info("Topological sorting...")
logging.info("Writing merged header...")
with open(OUTPUT_PATH, "w") as f:
f.write("#pragma once\n")
for header_path in graph.static_order():
with header_path.open() as f2:
for line in f2.readlines():
if not (
line.startswith("#pragma once") or line.startswith('#include "')
):
f.write(line)

logging.info("Done!")


if __name__ == "__main__":
create_merged_header()
12 changes: 0 additions & 12 deletions scripts/pre-compiled-bins/README.md

This file was deleted.

Loading

0 comments on commit e2bf6f2

Please sign in to comment.