This document records some notes on porting parallel-preprocessor to Windows 10
C++ demangle, needs boost if using msvc comppiler
Windows has no complete "signal.h" support.
#include <csignal>
sigemptyset() // no such on windows? mingw32?mingw has problem with filesystem, and there is no easy solution. and As the official OpenCASCADE has been built with VC141 (VS2017) The binary compatibility of mingw and visual C++ is doubtable in produciton scenarion.
mxe/mxe#2220 the gcc 9 patch seems to fix this issue https://sourceforge.net/p/mingw-w64/bugs/737/
there is the error message
D:/Software/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/fs_path.h:237:47: error: no match for 'operator!=' (operand types are 'std::filesystem::__cxx11::path' and 'std::filesystem::__cxx11::path') || (__p.has_root_name() && __p.root_name() != root_name()))
Stop trying on mingw.
-
Visual C++ does not define
__cplusplusproperly to detect C++ std supported. Visual C++ support C++9x or just C++14, skipped c++11#ifndef _MSC_VER&& __cplusplus < 201402L -
NMake does not support parallel compiling, but msbuild has parallel support
-
To let visual C++ to support
not, and, orkeywords,#include <iso646.h> -
Clang' command line options is comptable with C++, but visual studio is distinct.
-
VC (or even MingG32?) link to OCCT *.lib (import lib), and to run needs *.dll files
-
some macro is needed to assist symbol import and export from dll,
DLLimport
-- Found the following Boost libraries: -- system 'libboost_filesystem-vc140-mt-gd-x64-1_67.lib'
LINK : fatal error LNK1104: cannot open file 'libboost_filesystem-vc141-mt-gd-x64-1_67.lib'
There are static libraries (LIB) and dynamic libraries (DLL) - but note that .LIB files can be either static libraries (containing object files) or import libraries (containing symbols to allow the linker to link to a DLL).
*.exp symbol export file (.exp) for the program, dumpbin /exports
*.def symbol definition file, __declspec(dllexport)
*.lib could be import library, for linker to link and find symbols
*.ilk - this file is for incremental linking
*.pdb - Program database (.pdb) files, also called symbol files, map identifiers and statements in your project's source code to corresponding identifiers and instructions in compiled apps. These mapping files link the debugger to your source code, which enables debugging.
Typically DLLs go in a folder named “bin”, and import libraries go in a folder named “lib”
** header only library does not needs, __declspec(dllexport), only for impl in cpp files**
You can export data, functions, classes, or class member functions from a DLL using the __declspec(dllexport) keyword.
__declspec(dllexport) adds the export directive to the object file so you do not need to use a .def file.
MingW32 still needs this __declspec(dllexport) for windows.
In short, when building this module, __declspec(dllexport) should be used in header files to export symbols, while to use those symbols(functions/types) in another module,
__declspec(dllimport) should be used in the header files. A more flexible solution: for each cmake SHARED library target. e.g. define
#if _WIN32
# ifdef APP_DLL_EXPORT
# define AppExport __declspec(dllexport)
# else
# define AppExport __declspec(dllimport)
# endif
#else
# define AppExport
#endifUse the macro for each class, struct, enum class AppExport Processor
Also def the option, for the target, to export symbols
if(WIN32)
target_compile_definitions(MyApp PRIVATE APP_DLL_EXPORT=1) # DLL export on windows
endif()with this definition, cmake can geneate pppApp.lib, but it is not in the output lib folder lib , but in another folder in the build directory PPP/pppApp.lib
TODO: let cmake collect those *.lib and put into lib output folder.
for header only library, that is not necessary?
extern "C"
{ // only need to export C interface if used by C++ source code
#include "third-party/mm_io.h"
}set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
free function means not member functions of any class/struct.
They do need __declspec(dllexport) , but if no other module use it, it is internal function, there is no need to export the function.
However, in the case of function template, the keyword __declspec(dllexport) needs to be present explicitly for the symbols to be present on the dynamic library.
template AppExport void HelpingRegistration<double>( double );
AppExport void my_function(void);error C2491: definition of dllimport static data member not allowed
check cmake for that module, e.g. copy-and-paste, but forget to change target name to the new target name
if(WIN32)
target_compile_definitions(MyApp PRIVATE APP_DLL_EXPORT=1) # DLL export on windows
endif()static variable may cause some trouble.
There is no need to specify __declspec(dllexport), since template class impl usually in header file.
A template will only be compiled with spedified template parameter. Thus there will be nothing in the dll to link against. In order to use a template you always need to include both: declaration and definition. You cannot put the definitions in a .cpp file like ordinary classes/functions. http://www.cplusplus.com/forum/windows/199689/
If moving impl into cpp file, got misisng symbol error, when used by another target/module.
I believe you need to export the specializations. Have you tried this in your .cpp file:
template class EXPORT TemplatedStaticLib<double>;
template class EXPORT TemplatedStaticLib<std::string>;
//and pretty much the same in your header:
template class EXPORT TemplateStaticLib<double>;
template class EXPORT TemplateStaticLib<std::string>;
warning C4661: 'PPP::SparseMatrix PPP::SparseMatrix::readMatrixMarketFile(const std::string &)': no suitable definition provided for explicit template instantiation request
for typedef
- use all third-party headers in cpp file, without exposed any symbol to public header files
- SparseMatrix is a template class, its implementation should be only in header file, so mm_io.h must be included in SparseMatrix.h, In this situation, modified mm_io.h by adding "AppExport" macro
- loguru.h's LOG_F() can print real line number, and it is a submodule. Therefore do not modify loguru.h directly, by appending
AppExportto each functions in loguru.hpp but including loguru.cpp in each build target (*.dll, *.so), to solve the problem of symbol not defined/exported.
#if defined(_WIN32)
#include "../third-party/loguru/loguru.cpp"
#endifhttps://stackoverflow.com/questions/24511376/how-to-dllexport-a-class-derived-from-stdruntime-error How to dllexport a class derived from std::runtime_error?
class __declspec(dllexport) BaseException : public std::runtime_error
However, this gives me
warning C4275: non – DLL-interface class 'std::runtime_error' used as base for DLL-interface class 'BaseException'.
warning C4273: 'Geom::GeometryFixer::init': inconsistent dll linkage warning C4275: non dll-interface class 'std::exception' used as base for dll-interface class 'PPP::ProcessorError'
Solutions: Export it. Ignore it. In-line it.
warning C4275: non dll-interface class used as base for dll-interface class
if(MSVC)
target_compile_options(fmt PRIVATE /wd4251 /wd4275)
endif()