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:
Emmanuel BENOîT 2018-06-17 12:39:02 +02:00
parent ae2ad1f8b4
commit 30d8d3057e
9 changed files with 157 additions and 34 deletions

View file

@ -1,6 +1,24 @@
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
LDFLAGS += -L$(OUTDIR) -pthread
@ -14,9 +32,32 @@ ifeq ($(DEBUG),y)
CXXFLAGS += -g
endif
CXXFLAGS_LIB = $(CXXFLAGS)
# Libs for either Linux or Windows
ifeq ($(BUILD_FOR),linux)
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_TARGETS =
ifeq ($(BUILD_DYNAMIC_LIB),y)
@ -31,8 +72,8 @@ include src/files.mk
LIB_OBJS = $(addprefix $(OUTDIR)/,$(addsuffix .o, $(subst src/,, $(basename $(LIB_SOURCES)))))
include tests/list.mk
TEST_SUITES := $(addprefix $(OUTDIR)/test-,$(TESTS))
TEST_ALL := $(OUTDIR)/run-all-tests
TEST_SUITES := $(addsuffix $(SUFFIX_EXE), $(addprefix $(OUTDIR)/test-,$(TESTS)))
TEST_ALL := $(OUTDIR)/run-all-tests$(SUFFIX_EXE)
TEST_MAIN := $(OUTDIR)/tests/run-test.o
TEST_OBJS := $(addsuffix .o,$(addprefix $(OUTDIR)/tests/,$(TESTS))) $(TEST_MAIN)
LIBS_TESTS = -lcppunit
@ -88,7 +129,7 @@ fullclean: clean
-rmdir $(sort $(dir $(TEST_OBJS)) $(dir $(LIB_OBJS)))
-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
@ -109,10 +150,10 @@ $(LIB_STATIC): $(LIB_OBJS)
ar crD $(LIB_STATIC) $(LIB_OBJS)
# 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)
$(TEST_ALL): $(TEST_OBJS) $(LIB_LWLIB)
$(TEST_ALL): $(TEST_OBJS)
$(CXX) $(LDFLAGS) -o $@ $(TEST_OBJS) $(LIBS_TESTS)

7
TODO
View file

@ -1,2 +1,5 @@
Tests for T_FSPath
Generalize iterators
* Tests for T_FSPath
* 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

View file

@ -19,4 +19,8 @@
#include <thread>
#include <utility>
#ifdef _WIN32
# include <windows.h>
#endif // _WIN32
#endif // _H_EBCL_EXTERNALS

View file

@ -118,7 +118,7 @@ M_LSHIFT_OP( T_StringBuilder , T_SRDLocation const& ) noexcept;
// Type of an error record
enum class E_SRDErrorType {
ERROR ,
ERR ,
WARNING ,
NOTE
};
@ -137,7 +137,7 @@ class T_SRDError
T_SRDError( T_String error ,
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& operator= ( T_SRDError const& other ) noexcept;

View file

@ -7,9 +7,79 @@
using namespace ebcl;
#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_ ===========================================================*/
@ -89,11 +159,12 @@ inline void* T_DynLibLinux_::getSymbol(
return ptr;
}
using T_DynLibImpl_ = T_DynLibLinux_;
#endif // ifdef _WIN32
/*= T_DynLib =================================================================*/
using T_DynLibImpl_ = T_DynLibLinux_; // FIXME
T_DynLib::T_DynLib(
T_String const& name )
: A_PrivateImplementation( new T_DynLibImpl_( name ) )

View file

@ -104,7 +104,7 @@ T_StringBuilder& ebcl::operator<< (
void T_SRDErrors::checkAdded(
T_SRDError const& last )
{
if ( last.type( ) != E_SRDErrorType::ERROR
if ( last.type( ) != E_SRDErrorType::ERR
|| errCount_ >= MAX_ERRORS ) {
return;
}
@ -129,7 +129,7 @@ void T_SRDErrors::addAll(
RPC_SRDLocation lastLocation = nullptr;
for ( uint32_t i = 0 ; i < nErrors ; i ++ ) {
errors_.add( source[ i ] );
if ( source[ i ].type( ) == E_SRDErrorType::ERROR ) {
if ( source[ i ].type( ) == E_SRDErrorType::ERR ) {
lastLocation = &source[ i ].location( );
}
}

View file

@ -1677,14 +1677,16 @@ T_Buffer< char > T_String::toOSString( ) const
#ifdef _WIN32
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 ,
data( ) , data_->size( ) ,
( wchar_t* ) output.data( ) , n ) )
( wchar_t* ) output.data( ) , rsz * 2 ) )
{
return T_Buffer< char >( );
}
output[ n * 2 ] = output[ n * 2 + 1 ] = 0;
return output;
#else

View file

@ -454,37 +454,37 @@ void SRDLexerTest::testIntegers( )
M_CKLS_( 11 );
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 );
CPPUNIT_ASSERT_EQUAL( 0l , list[ 1 ].longValue( ) );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , list[ 1 ].longValue( ) );
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 );
CPPUNIT_ASSERT_EQUAL( 1l , list[ 3 ].longValue( ) );
CPPUNIT_ASSERT_EQUAL( int64_t( 1 ) , list[ 3 ].longValue( ) );
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 );
CPPUNIT_ASSERT_EQUAL( 123l , list[ 5 ].longValue( ) );
CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , list[ 5 ].longValue( ) );
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 );
CPPUNIT_ASSERT_EQUAL( 5000000000l , list[ 7 ].longValue( ) );
CPPUNIT_ASSERT_EQUAL( int64_t( 5000000000 ) , list[ 7 ].longValue( ) );
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 );
CPPUNIT_ASSERT_EQUAL( 0l , list[ 9 ].longValue( ) );
CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , list[ 9 ].longValue( ) );
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( )

View file

@ -537,8 +537,10 @@ void StringsBuilderTest::testAppendUnicode( )
const char t[] = STR; \
const uint32_t sz = sizeof( t ) - 1; \
if ( sz != sbo.size( ) || memcmp( sbo.data( ) , t , sz ) ) { \
const auto x( T_String( sbo ).toOSString( ) ); \
printf( "'%s' | expected '%s'\n" , x.data( ) , STR ); \
char x[ sbo.size( ) + 1 ]; \
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( !memcmp( sbo.data( ) , t , sz ) ); \