From f04ab838abd90fb70f7d6ef77fdacdf07f09ba4d Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Tue, 10 Sep 2013 17:44:32 +0300 Subject: [PATCH] Build fixes for Windows/Visual C++ --- compat/pb_syshdr.h | 23 ++++++++++++++ tests/SConstruct | 52 +++++++++++++++++++++++++------ tests/alltypes/SConscript | 8 ++--- tests/alltypes/encode_alltypes.c | 26 +++++++++------- tests/basic_buffer/SConscript | 8 ++--- tests/basic_buffer/decode_buffer.c | 11 +++++-- tests/basic_buffer/encode_buffer.c | 11 +++++-- tests/common/test_helpers.h | 17 ++++++++++ tests/cxx_main_program/SConscript | 8 ++--- tests/decode_unittests/SConscript | 4 +-- tests/decode_unittests/decode_unittests.c | 2 +- tests/encode_unittests/SConscript | 4 +-- tests/site_scons/site_init.py | 16 +++++++--- 13 files changed, 141 insertions(+), 49 deletions(-) create mode 100644 tests/common/test_helpers.h diff --git a/compat/pb_syshdr.h b/compat/pb_syshdr.h index c170c8de..b69a1671 100644 --- a/compat/pb_syshdr.h +++ b/compat/pb_syshdr.h @@ -12,6 +12,9 @@ #define _PB_SYSHDR_H_ /* stdint.h subset */ +#ifdef HAVE_STDINT_H +#include +#else /* You will need to modify these to match the word size of your platform. */ typedef signed char int8_t; typedef unsigned char uint8_t; @@ -21,8 +24,13 @@ typedef signed int int32_t; typedef unsigned int uint32_t; typedef signed long long int64_t; typedef unsigned long long uint64_t; +#endif /* stddef.h subset */ +#ifdef HAVE_STDDEF_H +#include +#else + typedef uint32_t size_t; #define offsetof(st, m) ((size_t)(&((st *)0)->m)) @@ -30,12 +38,26 @@ typedef uint32_t size_t; #define NULL 0 #endif +#endif + /* stdbool.h subset */ +#ifdef HAVE_STDBOOL_H +#include +#else + +#ifndef __cplusplus typedef int bool; #define false 0 #define true 1 +#endif + +#endif /* string.h subset */ +#ifdef HAVE_STRING_H +#include +#else + /* Implementations are from the Public Domain C Library (PDCLib). */ static size_t strlen( const char * s ) { @@ -67,5 +89,6 @@ static void * memset( void * s, int c, size_t n ) } return s; } +#endif #endif diff --git a/tests/SConstruct b/tests/SConstruct index a690aff0..8bbb31d1 100644 --- a/tests/SConstruct +++ b/tests/SConstruct @@ -1,4 +1,5 @@ -env = DefaultEnvironment() +import os +env = Environment(ENV = {'PATH': os.environ['PATH']}) # Add the builders defined in site_init.py add_nanopb_builders(env) @@ -7,18 +8,49 @@ add_nanopb_builders(env) env.Append(CPPPATH = ["#../", "#common"]) # Path for finding nanopb.proto -env.Append(PROTOCPATH = ['#../generator', '/usr/include', '.']) +env.Append(PROTOCPATH = '#../generator') -# Define the include path to find nanopb.proto -env.Append(PROTOCPATH = ['#../generator', '/usr/include', '.']) +# Check the compilation environment, unless we are just cleaning up. +if not env.GetOption('clean'): + conf = Configure(env) -# If the platform doesn't support C99, use our own header file instead. -conf = Configure(env) -if not conf.CheckCHeader('stdbool.h'): - conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'}) - conf.env.Append(CPPPATH = "#../compat") -env = conf.Finish() + # If the platform doesn't support C99, use our own header file instead. + stdbool = conf.CheckCHeader('stdbool.h') + stdint = conf.CheckCHeader('stdint.h') + stddef = conf.CheckCHeader('stddef.h') + string = conf.CheckCHeader('string.h') + if not stdbool or not stdint or not stddef or not string: + conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'}) + conf.env.Append(CPPPATH = "#../compat") + + if stdbool: conf.env.Append(CPPDEFINES = {'HAVE_STDBOOL_H': 1}) + if stdint: conf.env.Append(CPPDEFINES = {'HAVE_STDINT_H': 1}) + if stddef: conf.env.Append(CPPDEFINES = {'HAVE_STDDEF_H': 1}) + if string: conf.env.Append(CPPDEFINES = {'HAVE_STRING_H': 1}) + + # Check if we can use pkg-config to find protobuf include path + status, output = conf.TryAction('pkg-config protobuf --variable=includedir > $TARGET') + if status: + conf.env.Append(PROTOCPATH = output.strip()) + else: + conf.env.Append(PROTOCPATH = '/usr/include') + + # End the config stuff + env = conf.Finish() +# Initialize the CCFLAGS according to the compiler +if 'cl' in env['CC']: + # Microsoft Visual C++ + + # Debug info on, warning level 2 for tests, warnings as errors + env.Append(CCFLAGS = '/Zi /W2 /WX') + env.Append(LINKFLAGS = '/DEBUG') + + # PB_RETURN_ERROR triggers C4127 because of while(0) + env.Append(CCFLAGS = '/wd4127') + + + # Now include the SConscript files from all subdirectories SConscript(Glob('*/SConscript'), exports = 'env') diff --git a/tests/alltypes/SConscript b/tests/alltypes/SConscript index 3c8adc48..8aa45b6b 100644 --- a/tests/alltypes/SConscript +++ b/tests/alltypes/SConscript @@ -4,9 +4,9 @@ Import("env") env.NanopbProto("alltypes") -env.Program(["encode_alltypes.c", "alltypes.pb.c", "#common/pb_encode.o"]) -env.Program(["decode_alltypes.c", "alltypes.pb.c", "#common/pb_decode.o"]) +enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "#common/pb_encode.o"]) +dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "#common/pb_decode.o"]) -env.RunTest("encode_alltypes") -env.RunTest(["decode_alltypes", "encode_alltypes.output"]) +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) diff --git a/tests/alltypes/encode_alltypes.c b/tests/alltypes/encode_alltypes.c index 982ad3c8..802e1574 100644 --- a/tests/alltypes/encode_alltypes.c +++ b/tests/alltypes/encode_alltypes.c @@ -113,18 +113,20 @@ int main(int argc, char **argv) alltypes.end = 1099; - uint8_t buffer[1024]; - pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); - - /* Now encode it and check if we succeeded. */ - if (pb_encode(&stream, AllTypes_fields, &alltypes)) - { - fwrite(buffer, 1, stream.bytes_written, stdout); - return 0; /* Success */ - } - else { - fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); - return 1; /* Failure */ + uint8_t buffer[1024]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } } } diff --git a/tests/basic_buffer/SConscript b/tests/basic_buffer/SConscript index 5b85e132..349fb14f 100644 --- a/tests/basic_buffer/SConscript +++ b/tests/basic_buffer/SConscript @@ -2,11 +2,11 @@ Import("env") -env.Program(["encode_buffer.c", "#common/person.pb.c", "#common/pb_encode.o"]) -env.Program(["decode_buffer.c", "#common/person.pb.c", "#common/pb_decode.o"]) +enc = env.Program(["encode_buffer.c", "#common/person.pb.c", "#common/pb_encode.o"]) +dec = env.Program(["decode_buffer.c", "#common/person.pb.c", "#common/pb_decode.o"]) -env.RunTest("encode_buffer") -env.RunTest(["decode_buffer", "encode_buffer.output"]) +env.RunTest(enc) +env.RunTest([dec, "encode_buffer.output"]) env.Decode(["encode_buffer.output", "#common/person.proto"], MESSAGE = "Person") env.Compare(["decode_buffer.output", "encode_buffer.decoded"]) diff --git a/tests/basic_buffer/decode_buffer.c b/tests/basic_buffer/decode_buffer.c index 56bbd8f8..d231c916 100644 --- a/tests/basic_buffer/decode_buffer.c +++ b/tests/basic_buffer/decode_buffer.c @@ -9,6 +9,7 @@ #include #include #include "person.pb.h" +#include "test_helpers.h" /* This function is called once from main(), it handles the decoding and printing. */ @@ -59,9 +60,13 @@ bool print_person(pb_istream_t *stream) int main() { - /* Read the data into buffer */ uint8_t buffer[512]; - size_t count = fread(buffer, 1, sizeof(buffer), stdin); + pb_istream_t stream; + size_t count; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); if (!feof(stdin)) { @@ -70,7 +75,7 @@ int main() } /* Construct a pb_istream_t for reading from the buffer */ - pb_istream_t stream = pb_istream_from_buffer(buffer, count); + stream = pb_istream_from_buffer(buffer, count); /* Decode and print out the stuff */ if (!print_person(&stream)) diff --git a/tests/basic_buffer/encode_buffer.c b/tests/basic_buffer/encode_buffer.c index 742c99f4..d3e4f6e6 100644 --- a/tests/basic_buffer/encode_buffer.c +++ b/tests/basic_buffer/encode_buffer.c @@ -6,9 +6,13 @@ #include #include #include "person.pb.h" +#include "test_helpers.h" int main() { + uint8_t buffer[512]; + pb_ostream_t stream; + /* Initialize the structure with constants */ Person person = {"Test Person 99", 99, true, "test@person.com", 3, {{"555-12345678", true, Person_PhoneType_MOBILE}, @@ -16,12 +20,13 @@ int main() {"1234-5678", true, Person_PhoneType_WORK}, }}; - uint8_t buffer[512]; - pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); /* Now encode it and check if we succeeded. */ if (pb_encode(&stream, Person_fields, &person)) - { + { + /* Write the result data to stdout */ + SET_BINARY_MODE(stdout); fwrite(buffer, 1, stream.bytes_written, stdout); return 0; /* Success */ } diff --git a/tests/common/test_helpers.h b/tests/common/test_helpers.h new file mode 100644 index 00000000..f77760a5 --- /dev/null +++ b/tests/common/test_helpers.h @@ -0,0 +1,17 @@ +/* Compatibility helpers for the test programs. */ + +#ifndef _TEST_HELPERS_H_ +#define _TEST_HELPERS_H_ + +#ifdef _WIN32 +#include +#include +#define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) + +#else +#define SET_BINARY_MODE(file) + +#endif + + +#endif diff --git a/tests/cxx_main_program/SConscript b/tests/cxx_main_program/SConscript index b5482319..0d0a25ca 100644 --- a/tests/cxx_main_program/SConscript +++ b/tests/cxx_main_program/SConscript @@ -13,8 +13,8 @@ Command("encode_alltypes.cxx", "#alltypes/encode_alltypes.c", c) Command("decode_alltypes.cxx", "#alltypes/decode_alltypes.c", c) # Now build and run the test normally. -env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx"]) -env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx"]) +enc = env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx"]) +dec = env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx"]) -env.RunTest("encode_alltypes") -env.RunTest(["decode_alltypes", "encode_alltypes.output"]) +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) diff --git a/tests/decode_unittests/SConscript b/tests/decode_unittests/SConscript index 860d7738..5e0f8407 100644 --- a/tests/decode_unittests/SConscript +++ b/tests/decode_unittests/SConscript @@ -1,4 +1,4 @@ Import('env') -env.Program(["decode_unittests.c", "#common/unittestproto.pb.c", "#common/pb_decode.o"]) -env.RunTest('decode_unittests') +p = env.Program(["decode_unittests.c", "#common/unittestproto.pb.c", "#common/pb_decode.o"]) +env.RunTest(p) diff --git a/tests/decode_unittests/decode_unittests.c b/tests/decode_unittests/decode_unittests.c index 6ad05f00..9c447a57 100644 --- a/tests/decode_unittests/decode_unittests.c +++ b/tests/decode_unittests/decode_unittests.c @@ -291,7 +291,7 @@ int main() { pb_istream_t s; - IntegerContainer dest = {}; + IntegerContainer dest = {{0}}; COMMENT("Testing pb_decode_delimited") TEST((s = S("\x09\x0A\x07\x0A\x05\x01\x02\x03\x04\x05"), diff --git a/tests/encode_unittests/SConscript b/tests/encode_unittests/SConscript index 0864a910..6a5ffcff 100644 --- a/tests/encode_unittests/SConscript +++ b/tests/encode_unittests/SConscript @@ -1,5 +1,5 @@ # Build and run the stand-alone unit tests for the nanopb encoder part. Import('env') -env.Program(["encode_unittests.c", "#common/unittestproto.pb.c", "#common/pb_encode.o"]) -env.RunTest('encode_unittests') +p = env.Program(["encode_unittests.c", "#common/unittestproto.pb.c", "#common/pb_encode.o"]) +env.RunTest(p) diff --git a/tests/site_scons/site_init.py b/tests/site_scons/site_init.py index 1383067d..b69db646 100644 --- a/tests/site_scons/site_init.py +++ b/tests/site_scons/site_init.py @@ -1,6 +1,13 @@ import subprocess import sys +try: + # Make terminal colors work on windows + import colorama + colorama.init() +except ImportError: + pass + def add_nanopb_builders(env): '''Add the necessary builder commands for nanopb tests.''' @@ -14,6 +21,7 @@ def add_nanopb_builders(env): src_suffix = '.proto') env.Append(BUILDERS = {'Proto': proto_file_builder}) env.SetDefault(PROTOC = 'protoc') + env.SetDefault(PROTOCPATH = ['.']) # Build command for running nanopb generator import os.path @@ -50,9 +58,9 @@ def add_nanopb_builders(env): stderr = sys.stderr) result = pipe.wait() if result == 0: - print '\033[92m[ OK ]\033[0m Ran ' + str(source[0]) + print '\033[32m[ OK ]\033[0m Ran ' + str(source[0]) else: - print '\033[91m[FAIL]\033[0m Program ' + str(source[0]) + ' returned ' + str(result) + print '\033[31m[FAIL]\033[0m Program ' + str(source[0]) + ' returned ' + str(result) return result run_test_builder = Builder(action = run_test, @@ -73,10 +81,10 @@ def add_nanopb_builders(env): data1 = open(str(source[0]), 'rb').read() data2 = open(str(source[1]), 'rb').read() if data1 == data2: - print '\033[92m[ OK ]\033[0m Files equal: ' + str(source[0]) + ' and ' + str(source[1]) + print '\033[32m[ OK ]\033[0m Files equal: ' + str(source[0]) + ' and ' + str(source[1]) return 0 else: - print '\033[91m[FAIL]\033[0m Files differ: ' + str(source[0]) + ' and ' + str(source[1]) + print '\033[31m[FAIL]\033[0m Files differ: ' + str(source[0]) + ' and ' + str(source[1]) return 1 compare_builder = Builder(action = compare_files, -- 2.16.6