Skip to content
Snippets Groups Projects
Commit 75e39606 authored by tobiglaser's avatar tobiglaser
Browse files

comitting to use gcc and importlib

parent f9f1d3a5
No related merge requests found
cmake_minimum_required(VERSION 3.18) cmake_minimum_required(VERSION 3.18)
#set (GNUtoMS 1)
project(SimpleTest VERSION 0.1 LANGUAGES CXX) project(SimpleTest VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
...@@ -14,15 +12,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ...@@ -14,15 +12,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(WIN32) if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(Qt5_DIR "C:/msys64/mingw64/qt5-static/lib/cmake/Qt5")
endif() endif()
#set(CMAKE_C_COMPILER "clang")
#set(CMAKE_CXX_COMPILER "clang++")
#set(CMAKE_CXX_STANDARD_LIBRARIES "-stdlib=libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -static -Wno-cast-function-type") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -static -Wno-cast-function-type")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld -static")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
find_package(Qt5 REQUIRED COMPONENTS Widgets Charts) find_package(Qt5 REQUIRED COMPONENTS Widgets Charts)
...@@ -35,7 +27,6 @@ add_library(cute SHARED ...@@ -35,7 +27,6 @@ add_library(cute SHARED
src/cute.cpp src/cute.cpp
src/control.cpp src/control.cpp
src/cuteControl.cpp src/cuteControl.cpp
# src/cute.def
) )
target_link_libraries(cute PRIVATE target_link_libraries(cute PRIVATE
...@@ -56,7 +47,6 @@ if (WIN32) ...@@ -56,7 +47,6 @@ if (WIN32)
set_target_properties(cute PROPERTIES PREFIX "") set_target_properties(cute PROPERTIES PREFIX "")
endif() endif()
set_target_properties(cute PROPERTIES LINK_FLAGS "-Wl,--output-def,cute.def")
add_executable(DynamicDemo add_executable(DynamicDemo
...@@ -81,7 +71,6 @@ endif(WIN32) ...@@ -81,7 +71,6 @@ endif(WIN32)
add_executable(LoaderDemo add_executable(LoaderDemo
src/main.cpp src/main.cpp
src/cuteImporter.cpp
examples/dynamicLoadDummy.cpp examples/dynamicLoadDummy.cpp
) )
...@@ -89,10 +78,6 @@ target_include_directories(LoaderDemo PRIVATE ...@@ -89,10 +78,6 @@ target_include_directories(LoaderDemo PRIVATE
include include
) )
target_compile_definitions(LoaderDemo PRIVATE
RUNTIME_LOAD
)
# Set the WIN32_EXECUTABLE property conditionally for Release, MinSizeRel, and RelWithDebInfo builds. # Set the WIN32_EXECUTABLE property conditionally for Release, MinSizeRel, and RelWithDebInfo builds.
# This lets the exe run without a terminal, making stdout inaccessible for now. # This lets the exe run without a terminal, making stdout inaccessible for now.
if(WIN32) if(WIN32)
......
...@@ -61,6 +61,13 @@ With clang, this command has to be quite verbose, the basic pattern is: `Sender, ...@@ -61,6 +61,13 @@ With clang, this command has to be quite verbose, the basic pattern is: `Sender,
9. Build. 9. Build.
Up to here it works when using the compiled import library `libcute.dll.a`. If you want to be able to load the dll at runtime, continue. Up to here it works when using the compiled import library `libcute.dll.a`. If you want to be able to load the dll at runtime, continue.
## The rest is obsolete because we are using an import library (libcute.dll.a) which automates these tedious steps for us.
### We would struggle to make it compatible across compilers anyway, because C++ Types break ABI (Application Binary Interface) constantly, with different compilers.
### We would have to C-ify the types to char* and Point[] to be able to eleviate that.
#### Not the scope of this work.
#### Looking at the commit where this stuff has been removed, might save you some time.
#### "comitting to use gcc and importlib"
10. The linker exports a `cute.def` file in the build directory. In this file, search the mangled function name. It contains the function name and it's namespace, so you can use Ctrl+F to find it. 10. The linker exports a `cute.def` file in the build directory. In this file, search the mangled function name. It contains the function name and it's namespace, so you can use Ctrl+F to find it.
Copy this string and paste it into the `cute.def` file in the source directory. Here, create an alias with the plain function name. Copy this string and paste it into the `cute.def` file in the source directory. Here, create an alias with the plain function name.
This way, the `cuteImporter.cpp` is simpler to read. It is also possible to use the mangled name there. This way, the `cuteImporter.cpp` is simpler to read. It is also possible to use the mangled name there.
......
...@@ -148,26 +148,6 @@ namespace cute ...@@ -148,26 +148,6 @@ namespace cute
void DYNAMIC timerStop(); void DYNAMIC timerStop();
std::chrono::microseconds DYNAMIC timerResult(); std::chrono::microseconds DYNAMIC timerResult();
/**
* @brief This is only here to facilitate loading and unloading functions, loaded dynamically from a .dll.
* @todo With the current approach or with static libraries, this is unneccessary.
*/
namespace core
{
// These are for loading and unloading libcute.dll at runtime
#if !defined(RUNTIME_LOAD) and !defined(EXPORT_CUTE)
inline int initialize() ///< In case of not loading at runtime and importing cute as the User, do nothing.
{
return 0;
}
inline void shutdown() {} ///< In case of not loading at runtime and importing cute as the User, do nothing.
#else
int initialize();
void shutdown();
#endif
} //namespace core
} //namespace cute } //namespace cute
......
LIBRARY cute
EXPORTS
logMessage=_ZN4cute10logMessageERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE
setProgress=_ZN4cute11setProgressEi
_ZN4cute12setPlotTitleENS_4PlotERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE
setPlotTheme=_ZN4cute12setPlotThemeEi
enableAutorun=_ZN4cute13enableAutorunEb
setStatusMessage=_ZN4cute16setStatusMessageERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEi
_ZN4cute14setPlotVisibleENS_4PlotEb
setProblemFile=_ZN4cute14setProblemFileERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE
setProblemSize=_ZN4cute14setProblemSizeEi
getProblemData1D=_ZN4cute16getProblemData1DEv
getProblemData2D=_ZN4cute16getProblemData2DEv
registerAlgorithm=_ZN4cute17registerAlgorithmEPFvvERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE
ok=_ZN4cute2okEv
run=_ZN4cute3runEPFvvE
delay=_ZN4cute5delayEi
#include "cute.h"
#include <windows.h>
namespace
{
// Private variables to hold the DLL handle and function pointers
// Anonymous namespace will not be visible outside of this translation unit
HINSTANCE hDll = nullptr;
typedef void (*t_setProgress)(int);
typedef void (*t_logMessage)(const std::string&);
typedef void (*t_setStatusMessage)(const std::string&, int);
typedef void (*t_setPlotTheme)(int);
typedef void (*t_enableAutorun)(bool);
typedef void (*t_setProblemFile)(const std::string&);
typedef void (*t_setProblemSize)(int);
typedef void (*t_registerAlgorithm)(void (*)(), const std::string&);
typedef void (*t_delay)(int);
typedef int (*t_run)(void (*)());
typedef bool (*t_ok)();
typedef const std::vector<float>& (*t_getProblemData1D)();
typedef const std::vector<cute::Point>& (*t_getProblemData2D)();
t_setProgress setProgressImpl = nullptr;
t_logMessage logMessageImpl = nullptr;
t_setStatusMessage setStatusMessageImpl = nullptr;
t_setPlotTheme setPlotThemeImpl = nullptr;
t_enableAutorun enableAutorunImpl = nullptr;
t_setProblemFile setProblemFileImpl = nullptr;
t_setProblemSize setProblemSizeImpl = nullptr;
t_registerAlgorithm registerAlgorithmImpl = nullptr;
t_delay delayImpl = nullptr;
t_run runImpl = nullptr;
t_ok okImpl = nullptr;
t_getProblemData1D getProblemData1DImpl = nullptr;
t_getProblemData2D getProblemData2DImpl = nullptr;
} //namespace
// Function implementations hidden from the user
namespace cute
{
int core::initialize()
{
hDll = LoadLibrary("cute.dll");
if (!hDll)
{
return -2;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-function-type" // No better way to get rid of the cast warnings.
setProgressImpl = reinterpret_cast<t_setProgress>(GetProcAddress(hDll, "setProgress"));
setStatusMessageImpl = reinterpret_cast<t_setStatusMessage>(GetProcAddress(hDll, "setStatusMessage"));
setPlotThemeImpl = reinterpret_cast<t_setPlotTheme>(GetProcAddress(hDll, "setPlotTheme"));
logMessageImpl = reinterpret_cast<t_logMessage>(GetProcAddress(hDll, "logMessage"));
enableAutorunImpl = reinterpret_cast<t_enableAutorun>(GetProcAddress(hDll, "enableAutorun"));
setProblemFileImpl = reinterpret_cast<t_setProblemFile>(GetProcAddress(hDll, "setProblemFile"));
setProblemSizeImpl = reinterpret_cast<t_setProblemSize>(GetProcAddress(hDll, "setProblemSize"));
registerAlgorithmImpl = reinterpret_cast<t_registerAlgorithm>(GetProcAddress(hDll, "registerAlgorithm"));
delayImpl = reinterpret_cast<t_delay>(GetProcAddress(hDll, "delay"));
runImpl = reinterpret_cast<t_run>(GetProcAddress(hDll, "run"));
okImpl = reinterpret_cast<t_ok>(GetProcAddress(hDll, "ok"));
getProblemData1DImpl = reinterpret_cast<t_getProblemData1D>(GetProcAddress(hDll, "getProblemData1D"));
getProblemData2DImpl = reinterpret_cast<t_getProblemData2D>(GetProcAddress(hDll, "getProblemData2D"));
#pragma clang diagnostic pop
// By checking here, we can spare any future checks and if we exit main() on any errors, we can spare us any
// exception handling.
if (setProgressImpl
&& setStatusMessageImpl
&& logMessageImpl
&& setPlotThemeImpl
&& enableAutorunImpl
&& setProblemFileImpl
&& setProblemSizeImpl
&& registerAlgorithmImpl
&& delayImpl
&& runImpl
&& okImpl
&& getProblemData1DImpl
&& getProblemData2DImpl)
{
return 0;
}
else
{
FreeLibrary(hDll);
hDll = nullptr;
return -3;
}
}
void setProgress(int percentage)
{
return setProgressImpl(percentage);
}
void setStatusMessage(const std::string& message, int duration_s)
{
return setStatusMessageImpl(message, duration_s);
}
void setPlotTheme(int themeNumber)
{
return setPlotThemeImpl(themeNumber);
}
void logMessage(const std::string& message)
{
return logMessageImpl(message);
}
void enableAutorun(bool run)
{
return enableAutorunImpl(run);
}
void setProblemFile(const std::string& path)
{
return setProblemFileImpl(path);
}
void setProblemSize(int n)
{
return setProblemSizeImpl(n);
}
void registerAlgorithm(void (*func)(), const std::string& name)
{
return registerAlgorithmImpl(func, name);
}
void delay(int milliseconds)
{
return delayImpl(milliseconds);
}
int run(void (*setup)())
{
return runImpl(setup);
}
bool ok()
{
return okImpl();
}
const std::vector<float>& getProblemData1D()
{
return getProblemData1DImpl();
}
const std::vector<cute::Point>& getProblemData2D()
{
return getProblemData2DImpl();
}
void core::shutdown()
{
if (hDll)
{
FreeLibrary(hDll);
hDll = nullptr;
setProgressImpl = nullptr;
setStatusMessageImpl = nullptr;
setPlotThemeImpl = nullptr;
logMessageImpl = nullptr;
enableAutorunImpl = nullptr;
setProblemFileImpl = nullptr;
setProblemSizeImpl = nullptr;
registerAlgorithmImpl = nullptr;
delayImpl = nullptr;
runImpl = nullptr;
okImpl = nullptr;
getProblemData1DImpl = nullptr;
getProblemData2DImpl = nullptr;
}
}
} //namespace cute
...@@ -4,9 +4,5 @@ extern void setup(); ...@@ -4,9 +4,5 @@ extern void setup();
int main() int main()
{ {
if (cute::core::initialize() != 0) return cute::run(setup);
return 1;
int r = cute::run(setup);
cute::core::shutdown();
return r;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment