Windows "compatibility"
* Makefile changes allowing for cross-compilation * SRDData: had to rename an enum member from ERROR to ERR because apparently creating a macro called ERROR is a thing in the windows headers * DynLib: ported * Strings: fixes in toOSString, untested for now * Fixes in some tests * TODO list update
This commit is contained in:
parent
ae2ad1f8b4
commit
30d8d3057e
9 changed files with 157 additions and 34 deletions
|
@ -1,6 +1,24 @@
|
||||||
include $(CONFIG)
|
include $(CONFIG)
|
||||||
|
BUILD_FOR ?= linux
|
||||||
|
|
||||||
CPPFLAGS += -Iinclude -I$(OUTDIR) -I$(OUTDIR)/data -DEBCL_BUILD
|
# Select compiler (g++ for linux, mingw-w64/posix for windows)
|
||||||
|
ifeq ($(BUILD_FOR),linux)
|
||||||
|
CXX=x86_64-linux-gnu-g++
|
||||||
|
else
|
||||||
|
ifeq ($(BUILD_FOR),win)
|
||||||
|
CXX=x86_64-w64-mingw32-g++-posix
|
||||||
|
else
|
||||||
|
$(error Invalid target "$(BUILD_FOR)")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# FIXME: temporarily used for Windows build
|
||||||
|
ifeq ($(BUILD_FOR),win)
|
||||||
|
CPPFLAGS += -I/tmp/cppunit/include
|
||||||
|
LDFLAGS += -L/tmp/cppunit/src/cppunit/.libs/
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPPFLAGS += -Iinclude -I$(OUTDIR) -I$(OUTDIR)/data -DEBCL_BUILD -D_USE_MATH_DEFINES
|
||||||
CXXFLAGS += -std=c++14 -Wall -Wextra
|
CXXFLAGS += -std=c++14 -Wall -Wextra
|
||||||
LDFLAGS += -L$(OUTDIR) -pthread
|
LDFLAGS += -L$(OUTDIR) -pthread
|
||||||
|
|
||||||
|
@ -14,9 +32,32 @@ ifeq ($(DEBUG),y)
|
||||||
CXXFLAGS += -g
|
CXXFLAGS += -g
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CXXFLAGS_LIB = $(CXXFLAGS)
|
# Libs for either Linux or Windows
|
||||||
|
ifeq ($(BUILD_FOR),linux)
|
||||||
LIBS_LIB = -ldl -latomic
|
LIBS_LIB = -ldl -latomic
|
||||||
LIB_DYNAMIC = $(OUTDIR)/libebcorelib.so
|
else
|
||||||
|
ifeq ($(BUILD_FOR),win)
|
||||||
|
LIBS_LIB = -latomic
|
||||||
|
else
|
||||||
|
$(error Invalid target "$(BUILD_FOR)")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Library and progam suffixes
|
||||||
|
ifeq ($(BUILD_FOR),linux)
|
||||||
|
SUFFIX_LIB=.so
|
||||||
|
SUFFIX_EXE=
|
||||||
|
else
|
||||||
|
ifeq ($(BUILD_FOR),win)
|
||||||
|
SUFFIX_LIB=.dll
|
||||||
|
SUFFIX_EXE=.exe
|
||||||
|
else
|
||||||
|
$(error Invalid target "$(BUILD_FOR)")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
CXXFLAGS_LIB = $(CXXFLAGS)
|
||||||
|
LIB_DYNAMIC = $(OUTDIR)/libebcorelib$(SUFFIX_LIB)
|
||||||
LIB_STATIC = $(OUTDIR)/libebcorelib.a
|
LIB_STATIC = $(OUTDIR)/libebcorelib.a
|
||||||
LIB_TARGETS =
|
LIB_TARGETS =
|
||||||
ifeq ($(BUILD_DYNAMIC_LIB),y)
|
ifeq ($(BUILD_DYNAMIC_LIB),y)
|
||||||
|
@ -31,8 +72,8 @@ include src/files.mk
|
||||||
LIB_OBJS = $(addprefix $(OUTDIR)/,$(addsuffix .o, $(subst src/,, $(basename $(LIB_SOURCES)))))
|
LIB_OBJS = $(addprefix $(OUTDIR)/,$(addsuffix .o, $(subst src/,, $(basename $(LIB_SOURCES)))))
|
||||||
|
|
||||||
include tests/list.mk
|
include tests/list.mk
|
||||||
TEST_SUITES := $(addprefix $(OUTDIR)/test-,$(TESTS))
|
TEST_SUITES := $(addsuffix $(SUFFIX_EXE), $(addprefix $(OUTDIR)/test-,$(TESTS)))
|
||||||
TEST_ALL := $(OUTDIR)/run-all-tests
|
TEST_ALL := $(OUTDIR)/run-all-tests$(SUFFIX_EXE)
|
||||||
TEST_MAIN := $(OUTDIR)/tests/run-test.o
|
TEST_MAIN := $(OUTDIR)/tests/run-test.o
|
||||||
TEST_OBJS := $(addsuffix .o,$(addprefix $(OUTDIR)/tests/,$(TESTS))) $(TEST_MAIN)
|
TEST_OBJS := $(addsuffix .o,$(addprefix $(OUTDIR)/tests/,$(TESTS))) $(TEST_MAIN)
|
||||||
LIBS_TESTS = -lcppunit
|
LIBS_TESTS = -lcppunit
|
||||||
|
@ -88,7 +129,7 @@ fullclean: clean
|
||||||
-rmdir $(sort $(dir $(TEST_OBJS)) $(dir $(LIB_OBJS)))
|
-rmdir $(sort $(dir $(TEST_OBJS)) $(dir $(LIB_OBJS)))
|
||||||
-rmdir $(OUTDIR)
|
-rmdir $(OUTDIR)
|
||||||
|
|
||||||
tests: $(LIB_LWLIB) $(TEST_OBJS) $(TEST_SUITES) $(TEST_ALL)
|
tests: $(TEST_OBJS) $(TEST_SUITES) $(TEST_ALL)
|
||||||
|
|
||||||
|
|
||||||
.PHONY: all run debug run-tests clean fullclean tests
|
.PHONY: all run debug run-tests clean fullclean tests
|
||||||
|
@ -109,10 +150,10 @@ $(LIB_STATIC): $(LIB_OBJS)
|
||||||
ar crD $(LIB_STATIC) $(LIB_OBJS)
|
ar crD $(LIB_STATIC) $(LIB_OBJS)
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
$(TEST_SUITES): $(OUTDIR)/test-%: $(OUTDIR)/tests/%.o $(TEST_MAIN) $(TEST_NEEDS)
|
$(TEST_SUITES): $(OUTDIR)/test-%$(SUFFIX_EXE): $(OUTDIR)/tests/%.o $(TEST_MAIN) $(TEST_NEEDS)
|
||||||
$(CXX) $(LDFLAGS) -o $@ $< $(TEST_MAIN) $(LIBS_TESTS)
|
$(CXX) $(LDFLAGS) -o $@ $< $(TEST_MAIN) $(LIBS_TESTS)
|
||||||
|
|
||||||
$(TEST_ALL): $(TEST_OBJS) $(LIB_LWLIB)
|
$(TEST_ALL): $(TEST_OBJS)
|
||||||
$(CXX) $(LDFLAGS) -o $@ $(TEST_OBJS) $(LIBS_TESTS)
|
$(CXX) $(LDFLAGS) -o $@ $(TEST_OBJS) $(LIBS_TESTS)
|
||||||
|
|
||||||
|
|
||||||
|
|
7
TODO
7
TODO
|
@ -1,2 +1,5 @@
|
||||||
Tests for T_FSPath
|
* Tests for T_FSPath
|
||||||
Generalize iterators
|
* Generalize iterators
|
||||||
|
* Fix output of appendDouble so it's consistent on both Linux
|
||||||
|
and Windows
|
||||||
|
* Reimplement threading so it avoids yet another DLL on windows
|
||||||
|
|
|
@ -19,4 +19,8 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
#endif // _H_EBCL_EXTERNALS
|
#endif // _H_EBCL_EXTERNALS
|
||||||
|
|
|
@ -118,7 +118,7 @@ M_LSHIFT_OP( T_StringBuilder , T_SRDLocation const& ) noexcept;
|
||||||
|
|
||||||
// Type of an error record
|
// Type of an error record
|
||||||
enum class E_SRDErrorType {
|
enum class E_SRDErrorType {
|
||||||
ERROR ,
|
ERR ,
|
||||||
WARNING ,
|
WARNING ,
|
||||||
NOTE
|
NOTE
|
||||||
};
|
};
|
||||||
|
@ -137,7 +137,7 @@ class T_SRDError
|
||||||
|
|
||||||
T_SRDError( T_String error ,
|
T_SRDError( T_String error ,
|
||||||
T_SRDLocation location ,
|
T_SRDLocation location ,
|
||||||
E_SRDErrorType type = E_SRDErrorType::ERROR ) noexcept;
|
E_SRDErrorType type = E_SRDErrorType::ERR ) noexcept;
|
||||||
|
|
||||||
T_SRDError( T_SRDError const& other ) noexcept;
|
T_SRDError( T_SRDError const& other ) noexcept;
|
||||||
T_SRDError& operator= ( T_SRDError const& other ) noexcept;
|
T_SRDError& operator= ( T_SRDError const& other ) noexcept;
|
||||||
|
|
|
@ -7,9 +7,79 @@
|
||||||
using namespace ebcl;
|
using namespace ebcl;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# error "Not implemented"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
/*= T_DynLibWindows ==========================================================*/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct T_DynLibWindows_
|
||||||
|
{
|
||||||
|
T_Buffer< char > path;
|
||||||
|
T_String error;
|
||||||
|
HMODULE lib;
|
||||||
|
|
||||||
|
explicit T_DynLibWindows_( T_String const& path ) noexcept;
|
||||||
|
explicit T_DynLibWindows_( char const* const path ) noexcept;
|
||||||
|
~T_DynLibWindows_( ) noexcept;
|
||||||
|
|
||||||
|
bool load( ) noexcept;
|
||||||
|
void unload( ) noexcept;
|
||||||
|
|
||||||
|
bool isLoaded( ) const noexcept;
|
||||||
|
|
||||||
|
void* getSymbol( char const* const symbol ) noexcept;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
inline T_DynLibWindows_::T_DynLibWindows_(
|
||||||
|
T_String const& path ) noexcept
|
||||||
|
: path( path.toOSString( ) ) , lib( nullptr )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline T_DynLibWindows_::T_DynLibWindows_(
|
||||||
|
char const* const path ) noexcept
|
||||||
|
: path( path , strlen( path ) ) , lib( nullptr )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline T_DynLibWindows_::~T_DynLibWindows_( ) noexcept
|
||||||
|
{
|
||||||
|
unload( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
inline bool T_DynLibWindows_::load( ) noexcept
|
||||||
|
{
|
||||||
|
lib = LoadLibraryW( (wchar_t const*) path.data( ) );
|
||||||
|
return lib != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void T_DynLibWindows_::unload( ) noexcept
|
||||||
|
{
|
||||||
|
if ( lib != nullptr ) {
|
||||||
|
FreeLibrary( lib );
|
||||||
|
lib = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool T_DynLibWindows_::isLoaded( ) const noexcept
|
||||||
|
{
|
||||||
|
return lib != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
inline void* T_DynLibWindows_::getSymbol(
|
||||||
|
char const* const symbol ) noexcept
|
||||||
|
{
|
||||||
|
return (void*) GetProcAddress( lib , symbol );
|
||||||
|
}
|
||||||
|
|
||||||
|
using T_DynLibImpl_ = T_DynLibWindows_;
|
||||||
|
|
||||||
|
|
||||||
|
#else // ifdef _WIN32
|
||||||
|
|
||||||
/*= T_DynLibLinux_ ===========================================================*/
|
/*= T_DynLibLinux_ ===========================================================*/
|
||||||
|
|
||||||
|
@ -89,11 +159,12 @@ inline void* T_DynLibLinux_::getSymbol(
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using T_DynLibImpl_ = T_DynLibLinux_;
|
||||||
|
|
||||||
|
#endif // ifdef _WIN32
|
||||||
|
|
||||||
/*= T_DynLib =================================================================*/
|
/*= T_DynLib =================================================================*/
|
||||||
|
|
||||||
using T_DynLibImpl_ = T_DynLibLinux_; // FIXME
|
|
||||||
|
|
||||||
T_DynLib::T_DynLib(
|
T_DynLib::T_DynLib(
|
||||||
T_String const& name )
|
T_String const& name )
|
||||||
: A_PrivateImplementation( new T_DynLibImpl_( name ) )
|
: A_PrivateImplementation( new T_DynLibImpl_( name ) )
|
||||||
|
|
|
@ -104,7 +104,7 @@ T_StringBuilder& ebcl::operator<< (
|
||||||
void T_SRDErrors::checkAdded(
|
void T_SRDErrors::checkAdded(
|
||||||
T_SRDError const& last )
|
T_SRDError const& last )
|
||||||
{
|
{
|
||||||
if ( last.type( ) != E_SRDErrorType::ERROR
|
if ( last.type( ) != E_SRDErrorType::ERR
|
||||||
|| errCount_ >= MAX_ERRORS ) {
|
|| errCount_ >= MAX_ERRORS ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ void T_SRDErrors::addAll(
|
||||||
RPC_SRDLocation lastLocation = nullptr;
|
RPC_SRDLocation lastLocation = nullptr;
|
||||||
for ( uint32_t i = 0 ; i < nErrors ; i ++ ) {
|
for ( uint32_t i = 0 ; i < nErrors ; i ++ ) {
|
||||||
errors_.add( source[ i ] );
|
errors_.add( source[ i ] );
|
||||||
if ( source[ i ].type( ) == E_SRDErrorType::ERROR ) {
|
if ( source[ i ].type( ) == E_SRDErrorType::ERR ) {
|
||||||
lastLocation = &source[ i ].location( );
|
lastLocation = &source[ i ].location( );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1677,14 +1677,16 @@ T_Buffer< char > T_String::toOSString( ) const
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
const auto n( data_->length( ) );
|
const auto n( data_->length( ) );
|
||||||
T_Buffer< char > output( ( n + 1 ) * 2 );
|
const auto rsz( MultiByteToWideChar( CP_UTF8 , 0 ,
|
||||||
|
data( ) , data_->size( ) ,
|
||||||
|
nullptr , 0 ) );
|
||||||
|
T_Buffer< char > output( rsz * 2 );
|
||||||
if ( !MultiByteToWideChar( CP_UTF8 , 0 ,
|
if ( !MultiByteToWideChar( CP_UTF8 , 0 ,
|
||||||
data( ) , data_->size( ) ,
|
data( ) , data_->size( ) ,
|
||||||
( wchar_t* ) output.data( ) , n ) )
|
( wchar_t* ) output.data( ) , rsz * 2 ) )
|
||||||
{
|
{
|
||||||
return T_Buffer< char >( );
|
return T_Buffer< char >( );
|
||||||
}
|
}
|
||||||
output[ n * 2 ] = output[ n * 2 + 1 ] = 0;
|
|
||||||
return output;
|
return output;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -454,37 +454,37 @@ void SRDLexerTest::testIntegers( )
|
||||||
M_CKLS_( 11 );
|
M_CKLS_( 11 );
|
||||||
|
|
||||||
M_CKTOK_( 0 , INT , 1 , 1 );
|
M_CKTOK_( 0 , INT , 1 , 1 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 0l , list[ 0 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , list[ 0 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 1 , INT , 1 , 3 );
|
M_CKTOK_( 1 , INT , 1 , 3 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 0l , list[ 1 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , list[ 1 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 2 , INT , 1 , 7 );
|
M_CKTOK_( 2 , INT , 1 , 7 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 0l , list[ 2 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , list[ 2 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 3 , INT , 1 , 10 );
|
M_CKTOK_( 3 , INT , 1 , 10 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 1l , list[ 3 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 1 ) , list[ 3 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 4 , INT , 1 , 12 );
|
M_CKTOK_( 4 , INT , 1 , 12 );
|
||||||
CPPUNIT_ASSERT_EQUAL( -1l , list[ 4 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( -1 ) , list[ 4 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 5 , INT , 1 , 15 );
|
M_CKTOK_( 5 , INT , 1 , 15 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 123l , list[ 5 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , list[ 5 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 6 , INT , 1 , 19 );
|
M_CKTOK_( 6 , INT , 1 , 19 );
|
||||||
CPPUNIT_ASSERT_EQUAL( -123l , list[ 6 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( -123 ) , list[ 6 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 7 , LONG , 1 , 24 );
|
M_CKTOK_( 7 , LONG , 1 , 24 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 5000000000l , list[ 7 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 5000000000 ) , list[ 7 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 8 , LONG , 1 , 35 );
|
M_CKTOK_( 8 , LONG , 1 , 35 );
|
||||||
CPPUNIT_ASSERT_EQUAL( -5000000000l , list[ 8 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( -5000000000 ) , list[ 8 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 9 , INT , 1 , 47 );
|
M_CKTOK_( 9 , INT , 1 , 47 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 0l , list[ 9 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , list[ 9 ].longValue( ) );
|
||||||
|
|
||||||
M_CKTOK_( 10 , INT , 1 , 94 );
|
M_CKTOK_( 10 , INT , 1 , 94 );
|
||||||
CPPUNIT_ASSERT_EQUAL( 123l , list[ 10 ].longValue( ) );
|
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , list[ 10 ].longValue( ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SRDLexerTest::testFloatValid( )
|
void SRDLexerTest::testFloatValid( )
|
||||||
|
|
|
@ -537,8 +537,10 @@ void StringsBuilderTest::testAppendUnicode( )
|
||||||
const char t[] = STR; \
|
const char t[] = STR; \
|
||||||
const uint32_t sz = sizeof( t ) - 1; \
|
const uint32_t sz = sizeof( t ) - 1; \
|
||||||
if ( sz != sbo.size( ) || memcmp( sbo.data( ) , t , sz ) ) { \
|
if ( sz != sbo.size( ) || memcmp( sbo.data( ) , t , sz ) ) { \
|
||||||
const auto x( T_String( sbo ).toOSString( ) ); \
|
char x[ sbo.size( ) + 1 ]; \
|
||||||
printf( "'%s' | expected '%s'\n" , x.data( ) , STR ); \
|
x[ sizeof( x ) - 1 ] = 0; \
|
||||||
|
memcpy( x , sbo.data( ) , sizeof( x ) - 1 ); \
|
||||||
|
printf( "'%s' | expected '%s'\n" , x , STR ); \
|
||||||
} \
|
} \
|
||||||
CPPUNIT_ASSERT_EQUAL( sz , sbo.size( ) ); \
|
CPPUNIT_ASSERT_EQUAL( sz , sbo.size( ) ); \
|
||||||
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , t , sz ) ); \
|
CPPUNIT_ASSERT( !memcmp( sbo.data( ) , t , sz ) ); \
|
||||||
|
|
Loading…
Reference in a new issue