Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bugdea1er committed Jan 3, 2024
0 parents commit 5ad7f87
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/LinuxBuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Linux Build
on:
push

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build
- name: Build
run: cmake --build ${{github.workspace}}/build
- name: Check that AbstractPlugin::preface is defined in the executable
run: nm -g ${{github.workspace}}/build/dynamic_lookup | grep AbstractPlugin.preface | grep T
- name: Check that AbstractPlugin::preface is undefined in the module
run: nm -g ${{github.workspace}}/build/libModulePlugin.so | grep AbstractPlugin.preface | grep U
- name: Run the executable
run: cd ${{github.workspace}}/build && ./dynamic_lookup
20 changes: 20 additions & 0 deletions .github/workflows/MacBuildWithFlags.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Mac Build With Flags
on:
push

jobs:
build:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DDYNAMIC_LOOKUP=ON
- name: Build
run: cmake --build ${{github.workspace}}/build
- name: Check that AbstractPlugin::preface is defined in the executable
run: nm -g ${{github.workspace}}/build/dynamic_lookup | grep AbstractPlugin.preface | grep T
- name: Check that AbstractPlugin::preface is undefined in the module
run: nm -g ${{github.workspace}}/build/libModulePlugin.so | grep AbstractPlugin.preface | grep U
- name: Run the executable
run: cd ${{github.workspace}}/build && ./dynamic_lookup
15 changes: 15 additions & 0 deletions .github/workflows/MacBuildWithoutFlags.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Mac Build Without Flags
on:
push

jobs:
build:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build
- name: Fail to build
run: cmake --build ${{github.workspace}}/build
continue-on-error: true
6 changes: 6 additions & 0 deletions AbstractPlugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "AbstractPlugin.hpp"
#include <iostream>

void AbstractPlugin::preface() {
std::cout << "Hello world" << std::endl;
}
13 changes: 13 additions & 0 deletions AbstractPlugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

class AbstractPlugin {
public:
/// This symbol must be defined in the module
virtual void run() = 0;

virtual ~AbstractPlugin() = default;

protected:
/// This symbol should not be defined in the module
void preface();
};
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.12)
project(dynamic_lookup)
set(CMAKE_CXX_STANDARD 17)

option(DYNAMIC_LOOKUP "Adds dynamic lookup linker flag" OFF)

add_library(AbstractPlugin OBJECT AbstractPlugin.cpp)
add_library(ModulePlugin MODULE ModulePlugin.cpp)
if (${DYNAMIC_LOOKUP})
target_link_options(ModulePlugin PRIVATE -undefined dynamic_lookup)
endif()

add_executable(dynamic_lookup main.cpp)
target_link_libraries(dynamic_lookup PUBLIC AbstractPlugin ${CMAKE_DL_LIBS})

set_property(TARGET dynamic_lookup PROPERTY ENABLE_EXPORTS ON)
14 changes: 14 additions & 0 deletions ModulePlugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "AbstractPlugin.hpp"
#include <iostream>

class ModulePlugin final : public AbstractPlugin {
public:
void run() override {
preface();
std::cout << "Bye world" << std::endl;
}
};

extern "C" {
AbstractPlugin* createPlugin() { return new ModulePlugin(); }
}
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
This example shows different behaviour of cmake project build when building MODULEs on Linux and Mac OS

The example consists of three parts:
- `AbstractPlugin` OBJECT library defines a virtual class AbstractPlugin. It has one defined method `preface` and one pure virtual method `run`. The `preface` method **required** to be defined in the object library
- `dynamic_lookup` executable links with the AbstractPlugin library and therefore contains a definition for `AbstractPlugin::preface` method
- `ModulePlugin` MODULE library defines an implementation of AbstractPlugin. The resulting `.so` file contains the `run` definition and does not contain the `preface` method definition.

The CMakeLists.txt file describes an option DYNAMIC_LOOKUP (off by default) which adds a `-undefined dynamic_lookup` linker flag for the MODULE target.

`dynamic_lookup` executable lists `preface` symbol as defined:
```shell
$ nm -g build/dynamic_lookup | grep AbstractPlugin.preface | grep T
0000000100003010 T __ZN14AbstractPlugin7prefaceEv
```

and `libModulePlugin` module lists `preface` symbol as undefined:
```shell
$ nm -g build/libModulePlugin.so | grep AbstractPlugin.preface | grep T
U __ZN14AbstractPlugin7prefaceEv
```

Linux build ([Linux Build CI](https://github.com/bugdea1er/dynamic_lookup/actions/workflows/LinuxBuild.yml)) completes just fine: no need for extra flags on top of marking the libs as OBJECT and MODULE where needed:
```shell
$ cmake -B build
$ cmake --build build
[ 20%] Building CXX object CMakeFiles/AbstractPlugin.dir/AbstractPlugin.cpp.o
[ 20%] Built target AbstractPlugin
[ 40%] Building CXX object CMakeFiles/ModulePlugin.dir/ModulePlugin.cpp.o
[ 60%] Linking CXX shared module libModulePlugin.so
[ 60%] Built target ModulePlugin
[ 80%] Building CXX object CMakeFiles/dynamic_lookup.dir/main.cpp.o
[100%] Linking CXX executable dynamic_lookup
[100%] Built target dynamic_lookup
```

Mac OS build ([Mac Build Without Flags CI](https://github.com/bugdea1er/dynamic_lookup/actions/workflows/MacBuildWithoutFlags.yml)) fails under the same conditions:
```shell
$ cmake -B build
$ cmake --build build
[ 20%] Building CXX object CMakeFiles/AbstractPlugin.dir/AbstractPlugin.cpp.o
[ 20%] Built target AbstractPlugin
[ 40%] Building CXX object CMakeFiles/ModulePlugin.dir/ModulePlugin.cpp.o
[ 60%] Linking CXX shared module libModulePlugin.so
Undefined symbols for architecture x86_64:
"AbstractPlugin::preface()", referenced from:
ModulePlugin::run() in ModulePlugin.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libModulePlugin.so] Error 1
make[1]: *** [CMakeFiles/ModulePlugin.dir/all] Error 2
make: *** [all] Error 2
```

Mac OS build needs a separate linker flag `-undefined dynamic_lookup` in order to achive the same results ([Mac Build With Flags CI](https://github.com/bugdea1er/dynamic_lookup/actions/workflows/MacBuildWithFlags.yml)):
```shell
$ cmake -B build -DDYNAMIC_LOOKUP=ON
$ cmake --build build
[ 20%] Building CXX object CMakeFiles/AbstractPlugin.dir/AbstractPlugin.cpp.o
[ 20%] Built target AbstractPlugin
[ 40%] Building CXX object CMakeFiles/ModulePlugin.dir/ModulePlugin.cpp.o
[ 60%] Linking CXX shared module libModulePlugin.so
[ 60%] Built target ModulePlugin
[ 80%] Building CXX object CMakeFiles/dynamic_lookup.dir/main.cpp.o
[100%] Linking CXX executable dynamic_lookup
[100%] Built target dynamic_lookup
```
14 changes: 14 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "AbstractPlugin.hpp"
#include <dlfcn.h>
#include <filesystem>

int main() {
auto module = std::filesystem::absolute("libModulePlugin.so");
auto* handle = dlopen(module.c_str(), RTLD_NOW);
auto* constructor = (AbstractPlugin*(*)()) dlsym(handle, "createPlugin");
auto* plugin = constructor();
plugin->run();

delete plugin;
dlclose(handle);
}

0 comments on commit 5ad7f87

Please sign in to comment.