Skip to content

Commit

Permalink
Version 1.8.3 (#16)
Browse files Browse the repository at this point in the history
fix: Improved CMake build system #15
feat: Example about the usage of the library
feat: CI now checks the code using cpplint
fix: Cleaner documentation
  • Loading branch information
martin-olivier authored May 5, 2022
1 parent 9a2ef33 commit 49d22a6
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 256 deletions.
19 changes: 16 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ defaults:
shell: bash

jobs:
run_unit_tests:
unit_tests:
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
os: [windows-latest, macos-latest, ubuntu-latest]
include:
- os: windows-latest
bin: unit_tests.exe
Expand Down Expand Up @@ -62,4 +62,17 @@ jobs:
run: cmake --build build

- name: Run Unit Tests with Valgrind
run: valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 ./unit_tests
run: valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 ./unit_tests

lint:
name: lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Install cpplint
run: pip install cpplint

- name: Run cpplint
run: cpplint --linelength=120 --filter=-whitespace/indent include/dylib.hpp
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ unit_tests
# Build Folders

cmake-build-*
build
build
Debug
75 changes: 32 additions & 43 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,43 @@ if(UNIX)
endif()

if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
# Project is configured as root (not subdirectory) -> include tests
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})

option(BUILD_TESTS "when set to ON, build unit tests" OFF)

if(BUILD_TESTS)

find_package(googletest QUIET)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

if(UNIX)
add_compile_options(-Wall -Wextra -Weffc++)
elseif(WIN32)
add_compile_options(/W4)
endif()

add_library(dynamic_lib SHARED tests/dynamic_lib.cpp)
set_target_properties(dynamic_lib PROPERTIES PREFIX "")
target_link_libraries(dynamic_lib PRIVATE dylib)

enable_testing()

add_executable(unit_tests tests/tests.cpp)
target_link_libraries(unit_tests PRIVATE dylib)

if(UNIX AND NOT APPLE)
add_compile_options(--coverage)
target_link_libraries(unit_tests PRIVATE gcov)
endif()

if(UNIX)
target_link_libraries(unit_tests PRIVATE dl)
endif()

target_link_libraries(unit_tests PRIVATE gtest_main)

include(GoogleTest)

gtest_discover_tests(unit_tests)

add_dependencies(unit_tests dynamic_lib)

find_package(googletest QUIET)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

if(UNIX)
add_compile_options(-Wall -Wextra -Weffc++)
elseif(WIN32)
add_compile_options(/W4)
endif()

add_library(dynamic_lib SHARED tests/lib.cpp)
set_target_properties(dynamic_lib PROPERTIES PREFIX "")
target_link_libraries(dynamic_lib PRIVATE dylib)

enable_testing()

add_executable(unit_tests tests/tests.cpp)
target_link_libraries(unit_tests PRIVATE gtest_main)
target_link_libraries(unit_tests PRIVATE dylib)

if(UNIX AND NOT APPLE)
add_compile_options(--coverage)
target_link_libraries(unit_tests PRIVATE gcov)
endif()

include(GoogleTest)
gtest_discover_tests(unit_tests)
endif()
endif()
106 changes: 17 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dylib - C++ cross-platform dynamic library loader
[![Dylib](https://img.shields.io/badge/Dylib-v1.8.2-blue.svg)](https://github.com/martin-olivier/dylib/releases/tag/v1.8.2)
[![Dylib](https://img.shields.io/badge/Dylib-v1.8.3-blue.svg)](https://github.com/martin-olivier/dylib/releases/tag/v1.8.3)
[![MIT license](https://img.shields.io/badge/License-MIT-orange.svg)](https://github.com/martin-olivier/dylib/blob/main/LICENSE)
[![CPP Version](https://img.shields.io/badge/C++-11_and_above-darkgreen.svg)](https://isocpp.org/)

Expand All @@ -10,7 +10,7 @@
[![workflow](https://github.com/martin-olivier/dylib/actions/workflows/CI.yml/badge.svg)](https://github.com/martin-olivier/dylib/actions/workflows/CI.yml)
[![codecov](https://codecov.io/gh/martin-olivier/dylib/branch/main/graph/badge.svg?token=4V6A9B7PII)](https://codecov.io/gh/martin-olivier/dylib)

[![GitHub download](https://img.shields.io/github/downloads/martin-olivier/dylib/total?style=for-the-badge)](https://github.com/martin-olivier/dylib/releases/download/v1.8.2/dylib.hpp)
[![GitHub download](https://img.shields.io/github/downloads/martin-olivier/dylib/total?style=for-the-badge)](https://github.com/martin-olivier/dylib/releases/download/v1.8.3/dylib.hpp)

The goal of this C++ library is to load dynamic libraries (.so, .dll, .dylib) and access its functions and global variables at runtime.

Expand All @@ -27,15 +27,14 @@ include(FetchContent)
FetchContent_Declare(
dylib
GIT_REPOSITORY "https://github.com/martin-olivier/dylib"
GIT_TAG "v1.8.2"
GIT_REPOSITORY "https://github.com/martin-olivier/dylib"
GIT_TAG "v1.8.3"
)
FetchContent_MakeAvailable(dylib)
include_directories(${dylib_SOURCE_DIR}/include)
```

You can also click [HERE](https://github.com/martin-olivier/dylib/releases/download/v1.8.2/dylib.hpp) to download the `dylib` header file.
You can also click [HERE](https://github.com/martin-olivier/dylib/releases/download/v1.8.3/dylib.hpp) to download the `dylib` header file.

# Documentation

Expand Down Expand Up @@ -88,7 +87,7 @@ Get a global variable from the dynamic library currently loaded in the object
dylib lib("./dynamic_lib.so");
// Get the global function adder
// Get the function adder
auto adder = lib.get_function<double(double, double)>("adder");
Expand All @@ -115,7 +114,7 @@ Returns the dynamic library handle
void example(dylib &lib)
{
if (lib)
std::cout << "Something is curently loaded in the dylib object" << std::endl;
std::cout << "Something is currently loaded in the dylib object" << std::endl;

if (lib.has_symbol("GetModule"))
std::cout << "GetModule symbol has been found" << std::endl;
Expand Down Expand Up @@ -149,87 +148,7 @@ return EXIT_SUCCESS;

# Example

Let's write some functions in our forthcoming dynamic library:
```c++
// dynamic_lib.cpp

#include <iostream>
#include "dylib.hpp"

DYLIB_API double pi_value = 3.14159;
DYLIB_API void *ptr = (void *)1;

DYLIB_API double adder(double a, double b)
{
return a + b;
}

DYLIB_API void print_hello()
{
std::cout << "Hello" << std::endl;
}
```
Let's build our code into a dynamic library:
```cmake
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
add_library(dynamic_lib SHARED dynamic_lib.cpp)
set_target_properties(dynamic_lib PROPERTIES PREFIX "")
```

Let's try to access the functions and global variables of our dynamic library at runtime with this code:
```c++
// main.cpp

#include <iostream>
#include "dylib.hpp"

int main()
{
try {
dylib lib("./dynamic_lib", dylib::extension);

auto adder = lib.get_function<double(double, double)>("adder");
std::cout << adder(5, 10) << std::endl;

auto printer = lib.get_function<void()>("print_hello");
printer();

double pi_value = lib.get_variable<double>("pi_value");
std::cout << pi_value << std::endl;

auto &ptr = lib.get_variable<void *>("ptr");
if (ptr == (void *)1)
std::cout << "1" << std::endl;
}
catch (const dylib::exception &e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
```

Let's build our code:
```cmake
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
add_executable(bin main.cpp)
if(UNIX)
target_link_libraries(bin PRIVATE dl)
endif()
```

Let's run our binary:
```sh
> ./bin
15
Hello
3.14159
1
```
A full example about the usage of the `dylib` library is available [HERE](example)

# Tips

Expand All @@ -249,8 +168,17 @@ set_target_properties(target PROPERTIES PREFIX "")

## Build and run unit tests

To build the unit tests, enter the following commands:
```sh
cmake . -B build -DBUILD_TESTS=ON
cmake --build build
```

To run the unit tests, enter the following command:
```sh
# on unix
./unit_tests

# on windows
./Debug/unit_tests.exe
```
32 changes: 32 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.14)

project(dylib_example)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})

# dylib fetch

include(FetchContent)

FetchContent_Declare(
dylib
GIT_REPOSITORY "https://github.com/martin-olivier/dylib"
GIT_TAG "v1.8.3"
)

FetchContent_MakeAvailable(dylib)

# build lib.cpp into a shared library

add_library(dynamic_lib SHARED lib.cpp)
set_target_properties(dynamic_lib PROPERTIES PREFIX "")
target_link_libraries(dynamic_lib PRIVATE dylib)

# build main.cpp into an executable

add_executable(dylib_example main.cpp)
target_link_libraries(dylib_example PRIVATE dylib)
Loading

0 comments on commit 49d22a6

Please sign in to comment.