lists.geany.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
List overview
Commits
March 2022
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
commits@lists.geany.org
1 participants
31 discussions
Start a n
N
ew thread
[geany/geany] 3c61af: Merge pull request #3084 from techee/basic
by Jiří Techet
14 Mar '22
14 Mar '22
Branch: refs/heads/master Author: Jiří Techet <techet(a)gmail.com> Committer: GitHub <noreply(a)github.com> Date: Mon, 14 Mar 2022 18:39:02 UTC Commit: 3c61af7fc08561bbd647164f33affc7ea257d2e8
https://github.com/geany/geany/commit/3c61af7fc08561bbd647164f33affc7ea257d…
Log Message: ----------- Merge pull request #3084 from techee/basic basic: use the upstream ctags parser Modified Paths: -------------- ctags/parsers/basic.c Modified: ctags/parsers/basic.c 223 lines changed, 157 insertions(+), 66 deletions(-) =================================================================== @@ -37,7 +37,6 @@ typedef enum { typedef struct { char const *token; BasicKind kind; - int skip; } KeyWord; static kindDefinition BasicKinds[] = { @@ -49,76 +48,182 @@ static kindDefinition BasicKinds[] = { {true, 'g', "enum", "enumerations"} }; -static KeyWord blitzbasic_keywords[] = { - {"const", K_CONST, 0}, - {"global", K_VARIABLE, 0}, - {"dim", K_VARIABLE, 0}, - {"function", K_FUNCTION, 0}, - {"type", K_TYPE, 0}, - {NULL, 0, 0} -}; +static KeyWord basic_keywords[] = { + /* freebasic */ + {"const", K_CONST}, + {"dim", K_VARIABLE}, + {"common", K_VARIABLE}, + {"function", K_FUNCTION}, + {"sub", K_FUNCTION}, + {"private sub", K_FUNCTION}, + {"public sub", K_FUNCTION}, + {"private function", K_FUNCTION}, + {"public function", K_FUNCTION}, + {"property", K_FUNCTION}, + {"constructor", K_FUNCTION}, + {"destructor", K_FUNCTION}, + {"type", K_TYPE}, + {"enum", K_ENUM}, -static KeyWord purebasic_keywords[] = { - {"newlist", K_VARIABLE, 0}, - {"global", K_VARIABLE, 0}, - {"dim", K_VARIABLE, 0}, - {"procedure", K_FUNCTION, 0}, - {"interface", K_TYPE, 0}, - {"structure", K_TYPE, 0}, - {NULL, 0, 0} -}; + /* blitzbasic, purebasic */ + {"global", K_VARIABLE}, -static KeyWord freebasic_keywords[] = { - {"const", K_CONST, 0}, - {"dim as", K_VARIABLE, 1}, - {"dim", K_VARIABLE, 0}, - {"common", K_VARIABLE, 0}, - {"function", K_FUNCTION, 0}, - {"sub", K_FUNCTION, 0}, - {"private sub", K_FUNCTION, 0}, - {"public sub", K_FUNCTION, 0}, - {"private function", K_FUNCTION, 0}, - {"public function", K_FUNCTION, 0}, - {"type", K_TYPE, 0}, - {"enum", K_ENUM, 0}, - {NULL, 0, 0} + /* purebasic */ + {"newlist", K_VARIABLE}, + {"procedure", K_FUNCTION}, + {"interface", K_TYPE}, + {"structure", K_TYPE}, + + {NULL, 0} }; /* * FUNCTION DEFINITIONS */ -/* Match the name of a tag (function, variable, type, ...) starting at pos. */ -static char const *extract_name (char const *pos, vString * name) +static const char *skipToMatching (char begin, char end, const char *pos) +{ + int counter = 1; + pos++; + while (*pos && counter > 0) + { + if (*pos == end) + counter--; + else if (*pos == begin) + counter++; + else if (*pos == '"') + pos = skipToMatching ('"', '"', pos) - 1; + pos++; + } + return pos; +} + +static const char *nextPos (const char *pos) { + if (*pos == '\0') + return pos; + + pos++; + switch (*pos) + { + case '(': + pos = skipToMatching ('(', ')', pos); + break; + case '"': + pos = skipToMatching ('"', '"', pos); + break; + } + return pos; +} + +static bool isIdentChar (char c) +{ + return c && !isspace (c) && c != '(' && c != ',' && c != '='; +} + +/* Match the name of a dim or const starting at pos. */ +static void extract_dim (char const *pos, BasicKind kind) +{ + vString *name = vStringNew (); + + if (strncasecmp (pos, "shared", 6) == 0) + pos += 6; /* skip keyword "shared" */ + while (isspace (*pos)) pos++; - vStringClear (name); - for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ','; pos++) + + /* capture "dim as String str" */ + if (strncasecmp (pos, "as", 2) == 0) + { + pos += 2; /* skip keyword "as" */ + + while (isspace (*pos)) + pos++; + while (!isspace (*pos) && *pos) /* skip next part which is a type */ + pos++; + while (isspace (*pos)) + pos++; + /* now we are at the name */ + } + /* capture "dim as foo ptr bar" */ + if (strncasecmp (pos, "ptr", 3) == 0 && isspace(*(pos+3))) + { + pos += 3; /* skip keyword "ptr" */ + while (isspace (*pos)) + pos++; + } + /* capture "dim as string * 4096 chunk" */ + if (strncmp (pos, "*", 1) == 0) + { + pos += 1; /* skip "*" */ + while (isspace (*pos) || isdigit(*pos) || ispunct(*pos)) + pos++; + } + + for (; isIdentChar (*pos); pos++) vStringPut (name, *pos); - return pos; + makeSimpleTag (name, kind); + + /* if the line contains a ',', we have multiple declarations */ + while (*pos && strchr (pos, ',')) + { + /* skip all we don't need(e.g. "..., new_array(5), " we skip "(5)") */ + while (*pos != ',' && *pos != '\'' && *pos) + pos = nextPos (pos); + + if (*pos == '\'') + break; /* break if we are in a comment */ + + while (isspace (*pos) || *pos == ',') + pos++; + + if (*pos == '\'') + break; /* break if we are in a comment */ + + vStringClear (name); + for (; isIdentChar (*pos); pos++) + vStringPut (name, *pos); + makeSimpleTag (name, kind); + } + + vStringDelete (name); +} + +/* Match the name of a tag (function, variable, type, ...) starting at pos. */ +static void extract_name (char const *pos, BasicKind kind) +{ + vString *name = vStringNew (); + for (; isIdentChar (*pos); pos++) + vStringPut (name, *pos); + makeSimpleTag (name, kind); + vStringDelete (name); } /* Match a keyword starting at p (case insensitive). */ -static int match_keyword (const char *p, KeyWord const *kw) +static bool match_keyword (const char *p, KeyWord const *kw) { - vString *name; size_t i; - int j; + const char *old_p; for (i = 0; i < strlen (kw->token); i++) { if (tolower (p[i]) != kw->token[i]) - return 0; + return false; } - name = vStringNew (); p += i; - for (j = 0; j < 1 + kw->skip; j++) - { - p = extract_name (p, name); - } - makeSimpleTag (name, kw->kind); - vStringDelete (name); - return 1; + + old_p = p; + while (isspace (*p)) + p++; + + /* create tags only if there is some space between the keyword and the identifier */ + if (old_p == p) + return false; + + if (kw->kind == K_VARIABLE) + extract_dim (p, kw->kind); /* extract_dim adds the found tag(s) */ + else + extract_name (p, kw->kind); + return true; } /* Match a "label:" style label. */ @@ -140,26 +245,12 @@ static void match_colon_label (char const *p) static void match_dot_label (char const *p) { if (*p == '.') - { - vString *name = vStringNew (); - extract_name (p + 1, name); - makeSimpleTag (name, K_LABEL); - vStringDelete (name); - } + extract_name (p + 1, K_LABEL); } static void findBasicTags (void) { const char *line; - const char *extension = fileExtension (getInputFileName ()); - KeyWord *keywords; - - if (strcmp (extension, "bb") == 0) - keywords = blitzbasic_keywords; - else if (strcmp (extension, "pb") == 0) - keywords = purebasic_keywords; - else - keywords = freebasic_keywords; while ((line = (const char *) readLineFromInputFile ()) != NULL) { @@ -183,11 +274,11 @@ static void findBasicTags (void) continue; /* In Basic, keywords always are at the start of the line. */ - for (kw = keywords; kw->token; kw++) + for (kw = basic_keywords; kw->token; kw++) if (match_keyword (p, kw)) break; /* Is it a label? */ - if (strcmp (extension, "bb") == 0) + if (*p == '.') match_dot_label (p); else match_colon_label (p); -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 344c30: Use asm parser from uctags
by Jiří Techet
14 Mar '22
14 Mar '22
Branch: refs/heads/master Author: Jiří Techet <techet(a)gmail.com> Committer: Jiří Techet <techet(a)gmail.com> Date: Mon, 20 Dec 2021 14:53:29 UTC Commit: 344c30fe095f37e667bf70041e3cf4656e09c39f
https://github.com/geany/geany/commit/344c30fe095f37e667bf70041e3cf4656e09c…
Log Message: ----------- Use asm parser from uctags Modified Paths: -------------- ctags/Makefile.am ctags/parsers/asm.c src/tagmanager/tm_parser.c Modified: ctags/Makefile.am 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -46,7 +46,7 @@ parsers = \ parsers/abaqus.c \ parsers/abc.c \ parsers/asciidoc.c \ - parsers/geany_asm.c \ + parsers/asm.c \ parsers/basic.c \ parsers/bibtex.c \ parsers/geany_c.c \ Modified: ctags/parsers/asm.c 196 lines changed, 128 insertions(+), 68 deletions(-) =================================================================== @@ -15,18 +15,23 @@ #include <string.h> +#include "cpreprocessor.h" #include "debug.h" +#include "entry.h" #include "keyword.h" #include "parse.h" #include "read.h" #include "routines.h" +#include "selectors.h" #include "vstring.h" /* * DATA DECLARATIONS */ typedef enum { - K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE + K_PSUEDO_MACRO_END = -2, + K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE, + K_SECTION, } AsmKind; typedef enum { @@ -45,11 +50,16 @@ typedef enum { OP_PROC, OP_RECORD, OP_SECTIONS, + OP_SECTION, OP_SET, OP_STRUCT, OP_LAST } opKeyword; +typedef enum { + ASM_SECTION_PLACEMENT, +} asmSectionRole; + typedef struct { opKeyword keyword; AsmKind kind; @@ -60,11 +70,17 @@ typedef struct { */ static langType Lang_asm; +static roleDefinition asmSectionRoles [] = { + { true, "placement", "placement where the assembled code goes" }, +}; + static kindDefinition AsmKinds [] = { { true, 'd', "define", "defines" }, { true, 'l', "label", "labels" }, { true, 'm', "macro", "macros" }, - { true, 't', "type", "types (structs and records)" } + { true, 't', "type", "types (structs and records)" }, + { true, 's', "section", "sections", + .referenceOnly = true, ATTACH_ROLES(asmSectionRoles)}, }; static const keywordTable AsmKeywords [] = { @@ -82,6 +98,12 @@ static const keywordTable AsmKeywords [] = { { "proc", OP_PROC }, { "record", OP_RECORD }, { "sections", OP_SECTIONS }, + + /* These are used in GNU as. */ + { "section", OP_SECTION }, + { "equiv", OP_EQU }, + { "eqv", OP_EQU }, + { "set", OP_SET }, { "struct", OP_STRUCT } }; @@ -91,7 +113,7 @@ static const opKind OpKinds [] = { { OP_ALIGN, K_NONE }, { OP_COLON_EQUAL, K_DEFINE }, { OP_END, K_NONE }, - { OP_ENDM, K_NONE }, + { OP_ENDM, K_PSUEDO_MACRO_END }, { OP_ENDMACRO, K_NONE }, { OP_ENDP, K_NONE }, { OP_ENDS, K_NONE }, @@ -102,6 +124,7 @@ static const opKind OpKinds [] = { { OP_PROC, K_LABEL }, { OP_RECORD, K_TYPE }, { OP_SECTIONS, K_NONE }, + { OP_SECTION, K_SECTION }, { OP_SET, K_DEFINE }, { OP_STRUCT, K_TYPE } }; @@ -131,33 +154,6 @@ static bool isSymbolCharacter (int c) return (bool) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL)); } -static bool readPreProc (const unsigned char *const line) -{ - bool result; - const unsigned char *cp = line; - vString *name = vStringNew (); - while (isSymbolCharacter ((int) *cp)) - { - vStringPut (name, *cp); - ++cp; - } - result = (bool) (strcmp (vStringValue (name), "define") == 0); - if (result) - { - while (isspace ((int) *cp)) - ++cp; - vStringClear (name); - while (isSymbolCharacter ((int) *cp)) - { - vStringPut (name, *cp); - ++cp; - } - makeSimpleTag (name, K_DEFINE); - } - vStringDelete (name); - return result; -} - static AsmKind operatorKind ( const vString *const operator, bool *const found) @@ -178,7 +174,7 @@ static AsmKind operatorKind ( static bool isDefineOperator (const vString *const operator) { const unsigned char *const op = - (unsigned char*) vStringValue (operator); + (unsigned char*) vStringValue (operator); const size_t length = vStringLength (operator); const bool result = (bool) (length > 0 && toupper ((int) *op) == 'D' && @@ -192,15 +188,17 @@ static void makeAsmTag ( const vString *const name, const vString *const operator, const bool labelCandidate, - const bool nameFollows) + const bool nameFollows, + const bool directive, + int *lastMacroCorkIndex) { if (vStringLength (name) > 0) { bool found; const AsmKind kind = operatorKind (operator, &found); if (found) { - if (kind != K_NONE) + if (kind > K_NONE) makeSimpleTag (name, kind); } else if (isDefineOperator (operator)) @@ -214,6 +212,37 @@ static void makeAsmTag ( if (! found) makeSimpleTag (name, K_LABEL); } + else if (directive) + { + bool found_dummy; + const AsmKind kind_for_directive = operatorKind (name, &found_dummy); + tagEntryInfo *macro_tag; + + switch (kind_for_directive) + { + case K_NONE: + break; + case K_MACRO: + *lastMacroCorkIndex = makeSimpleTag (operator, + kind_for_directive); + if (*lastMacroCorkIndex != CORK_NIL) + registerEntry (*lastMacroCorkIndex); + break; + case K_PSUEDO_MACRO_END: + macro_tag = getEntryInCorkQueue (*lastMacroCorkIndex); + if (macro_tag) + macro_tag->extensionFields.endLine = getInputLineNumber (); + *lastMacroCorkIndex = CORK_NIL; + break; + case K_SECTION: + makeSimpleRefTag (operator, + kind_for_directive, + ASM_SECTION_PLACEMENT); + break; + default: + makeSimpleTag (operator, kind_for_directive); + } + } } } @@ -240,71 +269,93 @@ static const unsigned char *readOperator ( { const unsigned char *cp = start; vStringClear (operator); - while (*cp != '\0' && ! isspace ((int) *cp)) + while (*cp != '\0' && ! isspace ((int) *cp) && *cp != ',') { vStringPut (operator, *cp); ++cp; } return cp; } +static const unsigned char *asmReadLineFromInputFile (void) +{ + static vString *line; + int c; + + line = vStringNewOrClear (line); + + while ((c = cppGetc()) != EOF) + { + if (c == '\n') + break; + else if (c == STRING_SYMBOL || c == CHAR_SYMBOL) + { + /* We cannot store these values to vString + * Store a whitespace as a dummy value for them. + */ + vStringPut (line, ' '); + } + else + vStringPut (line, c); + } + + if ((vStringLength (line) == 0)&& (c == EOF)) + return NULL; + else + return (unsigned char *)vStringValue (line); +} + static void findAsmTags (void) { vString *name = vStringNew (); vString *operator = vStringNew (); const unsigned char *line; - bool inCComment = false; - while ((line = readLineFromInputFile ()) != NULL) + cppInit (false, false, false, false, + KIND_GHOST_INDEX, 0, KIND_GHOST_INDEX, KIND_GHOST_INDEX, 0, 0, + FIELD_UNKNOWN); + + int lastMacroCorkIndex = CORK_NIL; + + while ((line = asmReadLineFromInputFile ()) != NULL) { const unsigned char *cp = line; bool labelCandidate = (bool) (! isspace ((int) *cp)); bool nameFollows = false; + bool directive = false; const bool isComment = (bool) (*cp != '\0' && strchr (";*@", *cp) != NULL); /* skip comments */ - if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0) - { - inCComment = true; - cp += 2; - } - if (inCComment) - { - do - { - if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0) - { - inCComment = false; - cp += 2; - break; - } - ++cp; - } while (*cp != '\0'); - } - if (isComment || inCComment) - continue; - - /* read preprocessor defines */ - if (*cp == '#') - { - ++cp; - readPreProc (cp); + if (isComment) continue; - } /* skip white space */ while (isspace ((int) *cp)) ++cp; /* read symbol */ - cp = readSymbol (cp, name); - if (vStringLength (name) > 0 && *cp == ':') + if (*cp == '.') { - labelCandidate = true; + directive = true; + labelCandidate = false; ++cp; } + cp = readSymbol (cp, name); + if (vStringLength (name) > 0) + { + if (*cp == ':') + { + labelCandidate = true; + ++cp; + } + else if (anyKindEntryInScope (CORK_NIL, + vStringValue (name), + K_MACRO)) + labelCandidate = false; + } + if (! isspace ((int) *cp) && *cp != '\0') continue; @@ -328,8 +379,12 @@ static void findAsmTags (void) cp = readSymbol (cp, name); nameFollows = true; } - makeAsmTag (name, operator, labelCandidate, nameFollows); + makeAsmTag (name, operator, labelCandidate, nameFollows, directive, + &lastMacroCorkIndex); } + + cppTerminate (); + vStringDelete (name); vStringDelete (operator); } @@ -351,14 +406,19 @@ extern parserDefinition* AsmParser (void) "*.[xX][68][68]", NULL }; + static selectLanguage selectors[] = { selectByArrowOfR, + NULL }; + parserDefinition* def = parserNew ("Asm"); - def->kindTable = AsmKinds; + def->kindTable = AsmKinds; def->kindCount = ARRAY_SIZE (AsmKinds); def->extensions = extensions; def->patterns = patterns; def->parser = findAsmTags; def->initialize = initialize; def->keywordTable = AsmKeywords; def->keywordCount = ARRAY_SIZE (AsmKeywords); + def->selectLanguage = selectors; + def->useCork = CORK_QUEUE | CORK_SYMTAB; return def; } Modified: src/tagmanager/tm_parser.c 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -174,6 +174,7 @@ static TMParserMapEntry map_ASM[] = { {'l', tm_tag_namespace_t}, {'m', tm_tag_function_t}, {'t', tm_tag_struct_t}, + {'s', tm_tag_undef_t}, }; /* not in universal-ctags */ -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 591c35: Merge pull request #3062 from techee/asm_parser
by Jiří Techet
14 Mar '22
14 Mar '22
Branch: refs/heads/master Author: Jiří Techet <techet(a)gmail.com> Committer: GitHub <noreply(a)github.com> Date: Mon, 14 Mar 2022 18:38:20 UTC Commit: 591c35df487ea69fafc28cedff9e737fbd0c78a5
https://github.com/geany/geany/commit/591c35df487ea69fafc28cedff9e737fbd0c7…
Log Message: ----------- Merge pull request #3062 from techee/asm_parser Use asm parser from uctags Modified Paths: -------------- ctags/Makefile.am ctags/parsers/asm.c src/tagmanager/tm_parser.c Modified: ctags/Makefile.am 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -46,7 +46,7 @@ parsers = \ parsers/abaqus.c \ parsers/abc.c \ parsers/asciidoc.c \ - parsers/geany_asm.c \ + parsers/asm.c \ parsers/basic.c \ parsers/bibtex.c \ parsers/geany_c.c \ Modified: ctags/parsers/asm.c 196 lines changed, 128 insertions(+), 68 deletions(-) =================================================================== @@ -15,18 +15,23 @@ #include <string.h> +#include "cpreprocessor.h" #include "debug.h" +#include "entry.h" #include "keyword.h" #include "parse.h" #include "read.h" #include "routines.h" +#include "selectors.h" #include "vstring.h" /* * DATA DECLARATIONS */ typedef enum { - K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE + K_PSUEDO_MACRO_END = -2, + K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE, + K_SECTION, } AsmKind; typedef enum { @@ -45,11 +50,16 @@ typedef enum { OP_PROC, OP_RECORD, OP_SECTIONS, + OP_SECTION, OP_SET, OP_STRUCT, OP_LAST } opKeyword; +typedef enum { + ASM_SECTION_PLACEMENT, +} asmSectionRole; + typedef struct { opKeyword keyword; AsmKind kind; @@ -60,11 +70,17 @@ typedef struct { */ static langType Lang_asm; +static roleDefinition asmSectionRoles [] = { + { true, "placement", "placement where the assembled code goes" }, +}; + static kindDefinition AsmKinds [] = { { true, 'd', "define", "defines" }, { true, 'l', "label", "labels" }, { true, 'm', "macro", "macros" }, - { true, 't', "type", "types (structs and records)" } + { true, 't', "type", "types (structs and records)" }, + { true, 's', "section", "sections", + .referenceOnly = true, ATTACH_ROLES(asmSectionRoles)}, }; static const keywordTable AsmKeywords [] = { @@ -82,6 +98,12 @@ static const keywordTable AsmKeywords [] = { { "proc", OP_PROC }, { "record", OP_RECORD }, { "sections", OP_SECTIONS }, + + /* These are used in GNU as. */ + { "section", OP_SECTION }, + { "equiv", OP_EQU }, + { "eqv", OP_EQU }, + { "set", OP_SET }, { "struct", OP_STRUCT } }; @@ -91,7 +113,7 @@ static const opKind OpKinds [] = { { OP_ALIGN, K_NONE }, { OP_COLON_EQUAL, K_DEFINE }, { OP_END, K_NONE }, - { OP_ENDM, K_NONE }, + { OP_ENDM, K_PSUEDO_MACRO_END }, { OP_ENDMACRO, K_NONE }, { OP_ENDP, K_NONE }, { OP_ENDS, K_NONE }, @@ -102,6 +124,7 @@ static const opKind OpKinds [] = { { OP_PROC, K_LABEL }, { OP_RECORD, K_TYPE }, { OP_SECTIONS, K_NONE }, + { OP_SECTION, K_SECTION }, { OP_SET, K_DEFINE }, { OP_STRUCT, K_TYPE } }; @@ -131,33 +154,6 @@ static bool isSymbolCharacter (int c) return (bool) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL)); } -static bool readPreProc (const unsigned char *const line) -{ - bool result; - const unsigned char *cp = line; - vString *name = vStringNew (); - while (isSymbolCharacter ((int) *cp)) - { - vStringPut (name, *cp); - ++cp; - } - result = (bool) (strcmp (vStringValue (name), "define") == 0); - if (result) - { - while (isspace ((int) *cp)) - ++cp; - vStringClear (name); - while (isSymbolCharacter ((int) *cp)) - { - vStringPut (name, *cp); - ++cp; - } - makeSimpleTag (name, K_DEFINE); - } - vStringDelete (name); - return result; -} - static AsmKind operatorKind ( const vString *const operator, bool *const found) @@ -178,7 +174,7 @@ static AsmKind operatorKind ( static bool isDefineOperator (const vString *const operator) { const unsigned char *const op = - (unsigned char*) vStringValue (operator); + (unsigned char*) vStringValue (operator); const size_t length = vStringLength (operator); const bool result = (bool) (length > 0 && toupper ((int) *op) == 'D' && @@ -192,15 +188,17 @@ static void makeAsmTag ( const vString *const name, const vString *const operator, const bool labelCandidate, - const bool nameFollows) + const bool nameFollows, + const bool directive, + int *lastMacroCorkIndex) { if (vStringLength (name) > 0) { bool found; const AsmKind kind = operatorKind (operator, &found); if (found) { - if (kind != K_NONE) + if (kind > K_NONE) makeSimpleTag (name, kind); } else if (isDefineOperator (operator)) @@ -214,6 +212,37 @@ static void makeAsmTag ( if (! found) makeSimpleTag (name, K_LABEL); } + else if (directive) + { + bool found_dummy; + const AsmKind kind_for_directive = operatorKind (name, &found_dummy); + tagEntryInfo *macro_tag; + + switch (kind_for_directive) + { + case K_NONE: + break; + case K_MACRO: + *lastMacroCorkIndex = makeSimpleTag (operator, + kind_for_directive); + if (*lastMacroCorkIndex != CORK_NIL) + registerEntry (*lastMacroCorkIndex); + break; + case K_PSUEDO_MACRO_END: + macro_tag = getEntryInCorkQueue (*lastMacroCorkIndex); + if (macro_tag) + macro_tag->extensionFields.endLine = getInputLineNumber (); + *lastMacroCorkIndex = CORK_NIL; + break; + case K_SECTION: + makeSimpleRefTag (operator, + kind_for_directive, + ASM_SECTION_PLACEMENT); + break; + default: + makeSimpleTag (operator, kind_for_directive); + } + } } } @@ -240,71 +269,93 @@ static const unsigned char *readOperator ( { const unsigned char *cp = start; vStringClear (operator); - while (*cp != '\0' && ! isspace ((int) *cp)) + while (*cp != '\0' && ! isspace ((int) *cp) && *cp != ',') { vStringPut (operator, *cp); ++cp; } return cp; } +static const unsigned char *asmReadLineFromInputFile (void) +{ + static vString *line; + int c; + + line = vStringNewOrClear (line); + + while ((c = cppGetc()) != EOF) + { + if (c == '\n') + break; + else if (c == STRING_SYMBOL || c == CHAR_SYMBOL) + { + /* We cannot store these values to vString + * Store a whitespace as a dummy value for them. + */ + vStringPut (line, ' '); + } + else + vStringPut (line, c); + } + + if ((vStringLength (line) == 0)&& (c == EOF)) + return NULL; + else + return (unsigned char *)vStringValue (line); +} + static void findAsmTags (void) { vString *name = vStringNew (); vString *operator = vStringNew (); const unsigned char *line; - bool inCComment = false; - while ((line = readLineFromInputFile ()) != NULL) + cppInit (false, false, false, false, + KIND_GHOST_INDEX, 0, KIND_GHOST_INDEX, KIND_GHOST_INDEX, 0, 0, + FIELD_UNKNOWN); + + int lastMacroCorkIndex = CORK_NIL; + + while ((line = asmReadLineFromInputFile ()) != NULL) { const unsigned char *cp = line; bool labelCandidate = (bool) (! isspace ((int) *cp)); bool nameFollows = false; + bool directive = false; const bool isComment = (bool) (*cp != '\0' && strchr (";*@", *cp) != NULL); /* skip comments */ - if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0) - { - inCComment = true; - cp += 2; - } - if (inCComment) - { - do - { - if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0) - { - inCComment = false; - cp += 2; - break; - } - ++cp; - } while (*cp != '\0'); - } - if (isComment || inCComment) - continue; - - /* read preprocessor defines */ - if (*cp == '#') - { - ++cp; - readPreProc (cp); + if (isComment) continue; - } /* skip white space */ while (isspace ((int) *cp)) ++cp; /* read symbol */ - cp = readSymbol (cp, name); - if (vStringLength (name) > 0 && *cp == ':') + if (*cp == '.') { - labelCandidate = true; + directive = true; + labelCandidate = false; ++cp; } + cp = readSymbol (cp, name); + if (vStringLength (name) > 0) + { + if (*cp == ':') + { + labelCandidate = true; + ++cp; + } + else if (anyKindEntryInScope (CORK_NIL, + vStringValue (name), + K_MACRO)) + labelCandidate = false; + } + if (! isspace ((int) *cp) && *cp != '\0') continue; @@ -328,8 +379,12 @@ static void findAsmTags (void) cp = readSymbol (cp, name); nameFollows = true; } - makeAsmTag (name, operator, labelCandidate, nameFollows); + makeAsmTag (name, operator, labelCandidate, nameFollows, directive, + &lastMacroCorkIndex); } + + cppTerminate (); + vStringDelete (name); vStringDelete (operator); } @@ -351,14 +406,19 @@ extern parserDefinition* AsmParser (void) "*.[xX][68][68]", NULL }; + static selectLanguage selectors[] = { selectByArrowOfR, + NULL }; + parserDefinition* def = parserNew ("Asm"); - def->kindTable = AsmKinds; + def->kindTable = AsmKinds; def->kindCount = ARRAY_SIZE (AsmKinds); def->extensions = extensions; def->patterns = patterns; def->parser = findAsmTags; def->initialize = initialize; def->keywordTable = AsmKeywords; def->keywordCount = ARRAY_SIZE (AsmKeywords); + def->selectLanguage = selectors; + def->useCork = CORK_QUEUE | CORK_SYMTAB; return def; } Modified: src/tagmanager/tm_parser.c 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -174,6 +174,7 @@ static TMParserMapEntry map_ASM[] = { {'l', tm_tag_namespace_t}, {'m', tm_tag_function_t}, {'t', tm_tag_struct_t}, + {'s', tm_tag_undef_t}, }; /* not in universal-ctags */ -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/infrastructure] 18dc69: Add nightly and CI build scripts to create Windows installers
by Enrico Tröger
13 Mar '22
13 Mar '22
Branch: refs/heads/add_ci_builders Author: Enrico Tröger <enrico.troeger(a)uvena.de> Committer: Enrico Tröger <enrico.troeger(a)uvena.de> Date: Sun, 13 Mar 2022 15:54:07 UTC Commit: 18dc699d256fbbc6ec0e75aefca6033365a164f8
https://github.com/geany/infrastructure/commit/18dc699d256fbbc6ec0e75aefca6…
Log Message: ----------- Add nightly and CI build scripts to create Windows installers The scripts, mainly start_build.sh, can be used for nightly builds and for CI builds. The Windows scripts use a Docker image containing a full cross compilation environment for mingw64-x86_64. They create fully working installer files for Geany and Geany-Plugins, optionally even signed if a certificate is provided. The Debian build scripts are yet to be tested and finalized. Modified Paths: -------------- README.md builders/.dockerignore builders/Dockerfile.debian builders/Dockerfile.mingw64 builders/README.md builders/certificates/.gitkeep builders/mingw64/bin/mingw-w64-i686-wine builders/mingw64/bin/mingw-w64-x86_64-wine builders/mingw64/etc/pacman.conf builders/mingw64/etc/pacman.d/mirrorlist.mingw64 builders/mingw64/etc/pacman.d/mirrorlist.msys builders/output/.gitkeep builders/scripts/build_debian_geany.sh builders/scripts/build_debian_geany_plugins.sh builders/scripts/build_mingw64_geany.sh builders/scripts/build_mingw64_geany_plugins.sh builders/scripts/update_debian_repositories.sh builders/start_build.sh Modified: README.md 11 lines changed, 10 insertions(+), 1 deletions(-) =================================================================== @@ -57,6 +57,15 @@ If you want to add or remove a repository maintained by these scripts, follow th and has files. +CI / Nightly-Builders +===================== + +The `builders` directory contains Dockerfiles and scripts to create Debian packages +as well as a cross-compiled Windows installer for Geany and Geany-Plugins. +These scripts are used for the nightly builds, for details see +[builders/README.md](builders/README.md). + + IRC Bot Plugins =============== @@ -68,6 +77,6 @@ features like a bunch of !commands. For details, read the source code. License -=============== +======= Unless stated otherwise all code in this repository is licensed of under the terms of the GNU General Public License version 2 (see COPYING in this repository). Modified: builders/.dockerignore 5 lines changed, 5 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,5 @@ +/.git +/certificates +/output +/scripts +/start_build.sh Modified: builders/Dockerfile.debian 32 lines changed, 32 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,32 @@ +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Docker image for Geany and Geany-Plugins for building Debian packages. +# + +ARG BASE_IMAGE_NAME=debian:bullseye +FROM $BASE_IMAGE_NAME + +LABEL org.opencontainers.image.title="Geany-Debian-CI" +LABEL org.opencontainers.image.description="Build image for Geany CI to support automatic building of Debian packages." +LABEL org.opencontainers.image.url="
https://github.com/geany/infrastructure
" +LABEL org.opencontainers.image.source="
https://github.com/geany/infrastructure
" +LABEL org.opencontainers.image.authors="The Geany contributors" +LABEL org.opencontainers.image.licenses="GPL-2.0" + +ENV DEBIAN_FRONTEND=noninteractive + +RUN set -ex && \ + apt-get update && \ + apt-get dist-upgrade --assume-yes && \ + apt-get install --assume-yes --no-install-recommends \ + ca-certificates wget gnupg build-essential git \ + devscripts dpkg-dev equivs fakeroot git-buildpackage \ + intltool libdistro-info-perl reprepro \ + # pre-install a few basic dependencies we probably need to reduce build time + libgtk-3-dev python3 python3-docutils python3-lxml \ + # pre-install some geany-plugins dependencies + cppcheck valac libgpgme-dev libctpl-dev liblua5.1-0-dev libmarkdown2-dev \ + # tools not necessary for build but useful for debugging + nano less Modified: builders/Dockerfile.mingw64 121 lines changed, 121 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,121 @@ +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Docker image for Geany and Geany-Plugins cross-build to Windows +# The image contains a self-compiled Pacman to install mingw-w64 +# packages and all other dependencies necessary to build the code +# and create a ready-use installer. +# For more details, see build_mingw64_geany.sh where this image is used. +# +# Intermediate container for building pacman +FROM debian:bullseye as build-pacman + +ENV PACMAN_VERSION=6.0.1 +ENV PACMAN_SHA256="0db61456e56aa49e260e891c0b025be210319e62b15521f29d3e93b00d3bf731" +ENV MSYS2_KEYRING_PKG="msys2-keyring-1~20211228-1-any.pkg.tar.zst" +ENV MSYS2_KEYRING_PKG_SHA256="1ef41c9c7c829e2612020cfa41136f552b509a8269fdb7fbbeddc59329c9b11b" +ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pacman/lib/x86_64-linux-gnu + +RUN set -ex && \ + apt-get update && \ + apt-get install --no-install-recommends --assume-yes \ + build-essential meson wget xz-utils zstd gnupg2 file zstd ca-certificates \ + pkg-config m4 libarchive-dev libssl-dev libcurl4-gnutls-dev libgpgme-dev \ + python3-setuptools + +# compile Pacman +RUN set -ex && \ + wget --no-verbose
https://sources.archlinux.org/other/pacman/pacman-${PACMAN_VERSION}.tar.xz
&& \ + echo "${PACMAN_SHA256} *pacman-${PACMAN_VERSION}.tar.xz" | sha256sum --check --strict - && \ + tar xf pacman-${PACMAN_VERSION}.tar.xz && \ + cd /pacman-${PACMAN_VERSION} && \ + meson \ + --prefix /usr/local/pacman \ + --sysconfdir=/windows/etc \ + --localstatedir=/windows/var \ + --buildtype release \ + --strip \ + -Dscriptlet-shell='/bin/bash' \ + -Ddoc='disabled' \ + -Ddoxygen='disabled' \ + -Ddoc='disabled' \ + -Di18n=false \ + build && \ + ninja -C build && \ + ninja -C build install && \ + ln -s /usr/local/pacman/bin/* /usr/local/bin/ + +COPY mingw64/etc/ /windows/etc/ + +# setup pacman-key +RUN set -ex && \ + # download MSYS2 keyring + mkdir -p /usr/local/pacman/share/pacman/keyrings/ && \ + wget --no-verbose "
https://repo.msys2.org/msys/x86_64/${MSYS2_KEYRING_PKG}
" && \ + echo "${MSYS2_KEYRING_PKG_SHA256} *${MSYS2_KEYRING_PKG}" | sha256sum --check --strict - && \ + tar -x -C /usr/local/pacman/share/pacman/keyrings/ -f "${MSYS2_KEYRING_PKG}" --strip-components 4 usr && \ + # initialize keyring + pacman-key --init && \ + pacman-key --populate msys2 + + +# Main image +FROM debian:bullseye + +LABEL org.opencontainers.image.title="Geany-Mingw-w64-CI" +LABEL org.opencontainers.image.description="Build image for Geany CI to support automatic building of Windows installers." +LABEL org.opencontainers.image.url="
https://github.com/geany/infrastructure
" +LABEL org.opencontainers.image.source="
https://github.com/geany/infrastructure
" +LABEL org.opencontainers.image.authors="The Geany contributors" +LABEL org.opencontainers.image.licenses="GPL-2.0" + +# install native tools and libraries +RUN set -ex && \ + dpkg --add-architecture i386 && \ + apt-get update && \ + apt-get install --no-install-recommends --assume-yes \ + # libraries \ + libcurl3-gnutls libgpgme11 libarchive13 libssl1.1 \ + # common useful utilities \ + wget curl less nano git gnupg2 file ca-certificates dos2unix \ + zip unzip xz-utils zstd \ + # build tools \ + build-essential automake autoconf autopoint gettext libtool check cppcheck \ + # genay-plugins autogen.sh requirements + intltool libglib2.0-dev \ + # mingw-w64 \ + gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64-x86-64-dev mingw-w64-tools \ + # install wine to test installer and created binaries + wine wine32 wine64 \ + # install NSIS and exiftool to inspect binary metadata + nsis libimage-exiftool-perl osslsigncode \ + # Geany build dependencies \ + python3-lxml python3-docutils + + +# copy pacman and scripts +COPY --from=build-pacman /windows /windows +COPY --from=build-pacman /usr/local/pacman /usr/local/pacman +COPY mingw64/bin/ /usr/local/bin/ +RUN ln -s /usr/local/pacman/bin/* /usr/local/bin/ && \ + mkdir /build + +WORKDIR /build +ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pacman/lib/x86_64-linux-gnu + +# start wine to initially create config directory +RUN /usr/local/bin/mingw-w64-i686-wine hostname.exe && \ + /usr/local/bin/mingw-w64-x86_64-wine hostname.exe && \ + # install GTK3 and all its dependencies + pacman --noconfirm -Sy mingw-w64-x86_64-gtk3 && \ + # cleanup + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + yes | pacman -Scc && \ + rm -r /usr/share/doc \ + /usr/share/locale \ + /usr/share/man \ + /windows/mingw64/share/icons \ + /windows/mingw64/share/locale \ + /windows/mingw64/share/doc Modified: builders/README.md 135 lines changed, 135 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,135 @@ +CI / Nightly-Builders +===================== + +## About + +Scripts and Dockerfiles for Geany and Geany-Plugins nightly builds. +`start_nightly_build.sh` will create (if missing) Docker images for +Debian stable and unstable as well as a Docker image for Mingw-w64 +cross-compilaton to Windows. +For the created Debian packages repositories for the distributions +(stable and unstable) will be created. + +## Scripts and files + + ├── Dockerfile.debian -> Dockerfile for Debian build image + ├── Dockerfile.mingw64 -> Dockerfile for Mingw-64 build image + ├── README.md + ├── certificates -> Certificate for signing Windows binaries and installer + │ ├── cert.pem -> Certificate public key (the filename is important) + │ └── key.pem -> Certificate secret key (the filename is important) + │ + ├── mingw64 -> Helpers and configuration for Pacman and Windows builds + │ ├── bin (these files will be built into the Windows Docker image) + │ │ ├── mingw-w64-i686-wine + │ │ └── mingw-w64-x86_64-wine + │ └── etc + │ ├── pacman.conf + │ └── pacman.d + │ └── mirrorlist.mingw64 + ├── output -> Directory where all build results are stored + │ + ├── scripts -> Build scripts to be executed within Docker containers + │ ├── build_debian_geany.sh -> Build Geany Debian packages + │ ├── build_debian_geany_plugins.sh -> Build Geany-Plugins Debian packages + │ ├── build_mingw64_geany.sh -> Build Geany Windows installer + │ ├── build_mingw64_geany_plugins.sh -> Build Geany-Plugins Windows installer + │ └── update_debian_repositories.sh -> Build repositories for Debian packages + │ + └── start_build.sh -> Run Debian and Windows build containers and start builds + +## Geany sources + +All of the scripts can either use an existing source distribution +of Geany (and Geany-Plugins) if it is mounted into the build Docker +container (as `/geany-source` resp. `/geany-plugins-source`). +If no existing source distribution is found, the scripts will clone +Geany resp. Geany-Plugins from GIT master. + +## start_build.sh + +Main entry point to (re-)build the necessary Docker images and trigger +the builds of Geany and Geany-Plugins for the various targets. + + usage: start_build.sh [-d|--distro DISTRO] [-m|--mingw64] + [-r|--rebuild-images] + -d, --distro DISTRO Build for target Debian DISTRO (e.g. "bullseye", + can be specified multiple times + -f, --force-rebuild Force rebuilding of immages even if not necessary + -g, --geany Build Geany + --geany-source Path to a Geany source directory (optional, cloned from GIT if missing) + --geany-plugins-source Path to a Geany-Plugins source directory (optional, cloned from GIT if missing) + -h Show this help screen + -l, --log-to-stdout Log build output additionally to stdout + -m, --mingw64 Build for target Mingw-w64 + -p, --geany-plugins Build Geany-Plugins + -r, --rebuild-images Rebuild Docker images before start building + (images are rebuilt automatically every 30 days) + -s, --sudo Use "sudo" for Docker commands + + +Example to build Geany and Geany-Plugins for Debian Bullseye, Debian Sid and Windows: + + bash start_build.sh --geany --geany-plugins --mingw64 --distro sid --distro bullseye + +## Debian package build + +The Debian based builds use as much as possible the official Debian package sources +from
https://salsa.debian.org/geany-team/geany.git
(and resp. for Geany-Plugins). + +Within the Debian based Docker images, packages are built from a GIT clone of Geany (unless +a source tree is provided into the container via a volume). + +### Docker image + +The Debian based Docker image is pretty straight-forward and just extends the official +"debian:$distro" images. The base image can be passed as build argument on image building and +so images for different Debian distributions (stable, sid, ...) can be built for later use. + +The Dockerfile just installs a couple of development tools and libraries which are required for +building Geany and Geany-Plugins. This is mainly to prepopulate the image with commonly used +tools and libraries. + +### Repository creation + +TBW - WIP + +#### GnuPG key + +TBW - WIP + +## Windows (Mingw64) build + +Geany and Geany-Plugins are built for Windows by cross-compiling them in a Docker container +containing all necessary tools. + +If the build was started via Github Actions from a pull request, the pull request number +will be appended to the resulting installer filename. For all other builds, the used GIT +commit short hash is used. + +The created installer for Geany will contain the +[Geany-Themes](https://github.com/geany/geany-themes) collection as well as the GTK +runtime with all necessary dependencies. + +The created installer for Geany-Plugins will contain all necessary dependencies +for the plugins to work. + +For more details, see the scripts `build_mingw64_geany.sh` and `build_mingw64_geany_plugins.sh` + +In theory, it is also possible to create release installers with this method. + +### Docker image + +The Docker image for the Windows build is based on a Debian image but has the full toolchain +for cross-compiling to mingw64 included. Additionally, the image contains a self-compiled +Pacman package manager to install packages from the MSYS2 repositories. + +### Code sign certificate + +If the directory `certificates` contains the two files `cert.pem` and `key.pem `, +then they will be used to digitally sign all created binary files (all built +`.exe` and `.dll` files). + +If the directory is empty, code signing will be skipped. + +The certificate should be in the PEM format and the key should not require a passphrase. Modified: builders/certificates/.gitkeep 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online Modified: builders/mingw64/bin/mingw-w64-i686-wine 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,4 @@ +#!/bin/sh -e + +WINEPATH="${WINEPATH};/windows/mingw32/bin" wine $@ + Modified: builders/mingw64/bin/mingw-w64-x86_64-wine 3 lines changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,3 @@ +#!/bin/sh -e + +WINEPATH="${WINEPATH};/windows/mingw64/bin" wine64 $@ Modified: builders/mingw64/etc/pacman.conf 40 lines changed, 40 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,40 @@ + +[options] +RootDir = /windows +DBPath = /windows/var/lib/pacman/ +CacheDir = /windows/var/cache/pacman/pkg/ +LogFile = /windows/var/log/pacman.log +GPGDir = /windows/etc/pacman.d/gnupg/ +HoldPkg = pacman +#XferCommand = /usr/bin/curl -C - -f %u > %o +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +#UseDelta = 0.7 +Architecture = x86_64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#TotalDownload +CheckSpace +#VerbosePkgLists + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +#SigLevel = Never +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +[mingw64] +Include = /windows/etc/pacman.d/mirrorlist.mingw64 + +[msys] +Include = /windows/etc/pacman.d/mirrorlist.msys Modified: builders/mingw64/etc/pacman.d/mirrorlist.mingw64 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,6 @@ +## +## 64-bit Mingw-w64 repository mirrorlist +## + +Server =
http://repo.msys2.org/mingw/x86_64
+Server =
http://www2.futureware.at/~nickoe/msys2-mirror/mingw/x86_64
Modified: builders/mingw64/etc/pacman.d/mirrorlist.msys 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,6 @@ +## +## MSYS repository mirrorlist +## + +Server =
http://repo.msys2.org/msys/$arch/
+Server =
http://www2.futureware.at/~nickoe/msys2-mirror/msys/$arch/
Modified: builders/output/.gitkeep 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online Modified: builders/scripts/build_debian_geany.sh 182 lines changed, 182 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,182 @@ +#!/bin/bash +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Helper script to build Debian packages for Geany. +# +# This script has to be executed within the Docker container. +# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY} +# where the resulting packages is stored. +# +# This script is meant to be run in a Docker container. +# + + +GEANY_VERSION= # will be set below from configure.ac +GEANY_GIT_REVISION= # will be set below from configure.ac +PACKAGE_VERSION= # will be set below +OUTPUT_DIRECTORY="/output" +GEANY_GIT_REPOSITORY="
https://github.com/geany/geany.git
" +GEANY_DEBIAN_REPOSITORY="
https://salsa.debian.org/geany-team/geany.git
" + +# rather static values, unlikely to be changed +GEANY_SOURCE_DIR="/geany-source" +GEANY_BUILD_DIR="/tmp/geany-build" +GEANY_DEBIAN_DIR="/tmp/geany-debian" + +# for "dch" (debian changelog) +export DEBEMAIL="devel(a)lists.geany.org" +export DEBFULLNAME="The Geany contributors" + +# stop on errors +set -e + + +log() { + echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ===========" +} + + +git_clone_geany_if_necessary() { + log "Clone Geany repository (if necessary)" + mkdir -p "$(dirname ${GEANY_BUILD_DIR})" + if [ -d ${GEANY_SOURCE_DIR} ]; then + log "Copying Geany source" + cp --archive ${GEANY_SOURCE_DIR}/ ${GEANY_BUILD_DIR}/ + else + log "Cloning Geany repository from ${GEANY_GIT_REPOSITORY}" + git clone --depth 1 ${GEANY_GIT_REPOSITORY} ${GEANY_BUILD_DIR} + fi +} + + +parse_geany_version() { + log "Parse Geany version" + GEANY_VERSION=$(sed -n -E -e 's/^AC_INIT\(\[Geany\], \[(.+)\],/\1/p' ${GEANY_BUILD_DIR}/configure.ac) + GEANY_GIT_REVISION=$(cd ${GEANY_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true) + PACKAGE_VERSION="${GEANY_VERSION}-1~$(date '+%Y%m%d')git${GEANY_GIT_REVISION}" +} + + +run_autogen_sh() { + log "Run ./autogen.sh" + cd ${GEANY_BUILD_DIR} + # run ./autogen.sh as the Debian package won't run ./autogen.sh for us + NOCONFIGURE=1 ./autogen.sh +} + +create_tarball_for_debuild() { + log "Create source tarball" + cd ${GEANY_BUILD_DIR} + # create a source tarball, keep .git included on purpose for Geany GIT build detection + tar --transform "s,^,geany-plugins-${GEANY_VERSION}/,S" \ + --create \ + --gzip \ + --file "../geany_${GEANY_VERSION}.orig.tar.gz" \ + . +} + + +git_clone_debian_geany() { + log "Clone Geany Debian repository" + git clone --depth 1 ${GEANY_DEBIAN_REPOSITORY} ${GEANY_DEBIAN_DIR} + # move debian package files to Geany GIT checkout + mv ${GEANY_DEBIAN_DIR}/debian ${GEANY_BUILD_DIR} +} + + +install_build_dependencies() { + log "Install build dependencies" + cd ${GEANY_BUILD_DIR} + apt-get --assume-yes update + apt-get --assume-yes dist-upgrade + mk-build-deps \ + --install \ + --remove \ + --tool "apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --assume-yes" + # mk-build-deps leave the following files which then break 'debuild' later on + rm -f geany-build-deps_*-?_amd64.buildinfo geany-build-deps_*-?_amd64.changes +} + + +add_changelog_entry() { + log "Add ChangeLog entry for Debian package" + cd ${GEANY_BUILD_DIR} + dch \ + --urgency low \ + --distribution unstable \ + --newversion "${PACKAGE_VERSION}" \ + "Autobuilt by CI or nightly build." +} + + +build_package() { + log "Build Debian package" + cd ${GEANY_BUILD_DIR} + + debuild -uc -us +} + + +copy_results() { + log "Copy build artefacts" + + BUILD_DIR_DIRNAME=$(dirname ${GEANY_BUILD_DIR}) + + rm -rf ${OUTPUT_DIRECTORY}/geany/* + + cp --verbose ${BUILD_DIR_DIRNAME}/geany_* ${OUTPUT_DIRECTORY}/geany + cp --verbose ${BUILD_DIR_DIRNAME}/geany-common_* ${OUTPUT_DIRECTORY}/geany + cp --verbose ${BUILD_DIR_DIRNAME}/geany-dbgsym_* ${OUTPUT_DIRECTORY}/geany +} + + +log_and_store_build_environment() { + log "Using environment" + + GTK_VERSION=$(pkg-config --modversion gtk+-3.0) + GLIB_VERSION=$(pkg-config --modversion glib-2.0) + COMPILER_VERSION=$(gcc -dumpfullversion) + + echo "Debian Distribution : $(grep PRETTY_NAME /etc/os-release | cut -d '=' -f 2)" + echo "Geany version : ${GEANY_VERSION}" + echo "Geany GIT revision : ${GEANY_GIT_REVISION}" + echo "GLib version : ${GLIB_VERSION}" + echo "GTK version : ${GTK_VERSION}" + echo "GCC version : ${COMPILER_VERSION}" + + cat <<EOT > ${OUTPUT_DIRECTORY}/geany/versions.json + { + "glib_version": "${GLIB_VERSION}", + "gtk_version": "${GTK_VERSION}", + "gcc_version": "${COMPILER_VERSION}", + } +EOT + + # dump and copy test suite log otherwise it would be lost + cat ${GEANY_BUILD_DIR}/tests/ctags/test-suite.log + cp ${GEANY_BUILD_DIR}/tests/ctags/test-suite.log ${OUTPUT_DIRECTORY}/geany +} + + +main() { + git_clone_geany_if_necessary + parse_geany_version + run_autogen_sh + create_tarball_for_debuild + + git_clone_debian_geany + install_build_dependencies + add_changelog_entry + + build_package + copy_results + + log_and_store_build_environment + + log "Done." +} + + +main Modified: builders/scripts/build_debian_geany_plugins.sh 183 lines changed, 183 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,183 @@ +#!/bin/bash +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Helper script to build Debian packages for Geany-Plugins. +# +# This script has to be executed within the Docker container. +# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY} +# where the resulting packages is stored. +# +# This script is meant to be run in a Docker container. +# + + +GEANY_PLUGINS_VERSION= # will be set below from configure.ac +GEANY_PLUGINS_GIT_REVISION= # will be set below from configure.ac +PACKAGE_VERSION= # will be set below +OUTPUT_DIRECTORY="/output" +GEANY_PLUGINS_GIT_REPOSITORY="
https://github.com/geany/geany-plugins.git
" +GEANY_PLUGINS_DEBIAN_REPOSITORY="
https://salsa.debian.org/geany-team/geany-plugins.git
" + +# rather static values, unlikely to be changed +GEANY_PLUGINS_SOURCE_DIR="/geany-plugins-source" +GEANY_PLUGINS_BUILD_DIR="/tmp/geany-plugins-build" +GEANY_PLUGINS_DEBIAN_DIR="/tmp/geany-plugins-debian" + +# for "dch" (debian changelog) +export DEBEMAIL="devel(a)lists.geany.org" +export DEBFULLNAME="The Geany contributors" + +# stop on errors +set -e + + +log() { + echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ===========" +} + + +git_clone_geany_if_necessary() { + log "Clone Geany-Plugins repository (if necessary)" + mkdir -p "$(dirname ${GEANY_PLUGINS_BUILD_DIR})" + if [ -d ${GEANY_PLUGINS_SOURCE_DIR} ]; then + log "Copying Geany-Plugins source" + cp --archive ${GEANY_PLUGINS_SOURCE_DIR}/ ${GEANY_PLUGINS_BUILD_DIR}/ + else + log "Cloning Geany-Plugins repository from ${GEANY_PLUGINS_GIT_REPOSITORY}" + git clone --depth 1 ${GEANY_PLUGINS_GIT_REPOSITORY} ${GEANY_PLUGINS_BUILD_DIR} + fi +} + + +parse_geany_plugins_version() { + log "Parse Geany-Plugins version" + GEANY_PLUGINS_VERSION=$(sed -n -E -e 's/^AC_INIT\(\[geany-plugins\], \[(.+)\]\)/\1/p' ${GEANY_PLUGINS_BUILD_DIR}/configure.ac) + GEANY_PLUGINS_GIT_REVISION=$(cd ${GEANY_PLUGINS_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true) + PACKAGE_VERSION="${GEANY_PLUGINS_VERSION}-1~$(date '+%Y%m%d')git${GEANY_PLUGINS_GIT_REVISION}" +} + + +run_autogen_sh() { + log "Run ./autogen.sh" + cd ${GEANY_PLUGINS_BUILD_DIR} + # run ./autogen.sh as the Debian package won't run ./autogen.sh for us + NOCONFIGURE=1 ./autogen.sh +} + + +create_tarball_for_debuild() { + log "Create source tarball" + cd ${GEANY_PLUGINS_BUILD_DIR} + tar --transform "s,^,geany-plugins-${GEANY_PLUGINS_VERSION}/,S" \ + --create \ + --gzip \ + --file "../geany-plugins_${GEANY_PLUGINS_VERSION}.orig.tar.gz" \ + . +} + + +git_clone_debian_geany() { + log "Clone Geany-Plugins Debian repository" + git clone --depth 1 ${GEANY_PLUGINS_DEBIAN_REPOSITORY} ${GEANY_PLUGINS_DEBIAN_DIR} + # move debian package files to Geany GIT checkout + mv ${GEANY_PLUGINS_DEBIAN_DIR}/debian ${GEANY_PLUGINS_BUILD_DIR} +} + + +install_build_dependencies() { + log "Install build dependencies" + cd ${GEANY_PLUGINS_BUILD_DIR} + # install Geany from previous build + dpkg -i \ + ${OUTPUT_DIRECTORY}/geany/geany-common_*git*_all.deb \ + ${OUTPUT_DIRECTORY}/geany/geany_*git*_amd64.deb + + apt-get --assume-yes update + apt-get --assume-yes dist-upgrade + mk-build-deps \ + --install \ + --remove \ + --tool "apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --assume-yes" + # mk-build-deps leave the following files which then break 'debuild' later on + rm -f geany-plugins-build-deps_*-?_amd64.buildinfo geany-plugins-build-deps_*-?_amd64.changes +} + + +add_changelog_entry() { + log "Add ChangeLog entry for Debian package" + cd ${GEANY_PLUGINS_BUILD_DIR} + dch \ + --urgency low \ + --distribution unstable \ + --newversion "${PACKAGE_VERSION}" \ + "Autobuilt by CI or nightly build." +} + + +build_package() { + log "Build Debian package" + cd ${GEANY_PLUGINS_BUILD_DIR} + + debuild -uc -us +} + + +copy_results() { + log "Copy build artefacts" + + BUILD_DIR_DIRNAME=$(dirname ${GEANY_PLUGINS_BUILD_DIR}) + + rm -rf ${OUTPUT_DIRECTORY}/geany-plugins/* + + cp --verbose ${BUILD_DIR_DIRNAME}/geany-plugins_* ${OUTPUT_DIRECTORY}/geany-plugins + cp --verbose ${BUILD_DIR_DIRNAME}/geany-plugins-*_* ${OUTPUT_DIRECTORY}/geany-plugins + cp --verbose ${BUILD_DIR_DIRNAME}/geany-plugin-*_* ${OUTPUT_DIRECTORY}/geany-plugins +} + + +log_and_store_build_environment() { + log "Using environment" + + GTK_VERSION=$(pkg-config --modversion gtk+-3.0) + GLIB_VERSION=$(pkg-config --modversion glib-2.0) + COMPILER_VERSION=$(gcc -dumpfullversion) + + echo "Debian Distribution : $(grep PRETTY_NAME /etc/os-release | cut -d '=' -f 2)" + echo "Geany-Plugins version : ${GEANY_PLUGINS_VERSION}" + echo "Geany-Plugins GIT revision : ${GEANY_PLUGINS_GIT_REVISION}" + echo "GLib version : ${GLIB_VERSION}" + echo "GTK version : ${GTK_VERSION}" + echo "GCC version : ${COMPILER_VERSION}" + + cat <<EOT > ${OUTPUT_DIRECTORY}/geany-plugins/versions.json + { + "glib_version": "${GLIB_VERSION}", + "gtk_version": "${GTK_VERSION}", + "gcc_version": "${COMPILER_VERSION}", + } +EOT +} + + +main() { + git_clone_geany_if_necessary + parse_geany_plugins_version + run_autogen_sh + create_tarball_for_debuild + + git_clone_debian_geany + install_build_dependencies + add_changelog_entry + + build_package + copy_results + + log_and_store_build_environment + + log "Done." +} + + +main Modified: builders/scripts/build_mingw64_geany.sh 327 lines changed, 327 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,327 @@ +#!/bin/bash +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Helper script to build Geany for Windows in a Docker container. +# The following steps are performed: +# - clone Geany repository if necessary (i.e. if it is not bind-mounted into the container) +# - cross-compile Geany for Windows 64bit and GTK3 +# - sign all binaries and installer (if /certificates exist and contains cert.pem and key.pem) +# - download Geany-Themes for bundling +# - create GTK3 bundle with all dependencies (including grep and sort) +# - create the NSIS installer in ${OUTPUT_DIRECTORY} +# - test the created NSIS installer and compiled Geany +# - test uninstaller and check there is nothing left after uninstalling +# +# This script has to be executed within the Docker container. +# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY} +# where the resulting installer binary is stored. +# +# To test the installer and Geany binary "wine" is used. +# Please note that we need to use wine32 and wine64 as the +# created installer and uninstaller binaries are 32bit whereas the created +# Geany binary is 64bit. +# + +GEANY_VERSION= # will be set below from configure.ac +GEANY_GIT_REVISION= # will be set below from configure.ac +OUTPUT_DIRECTORY="/output" +GEANY_GIT_REPOSITORY="
https://github.com/geany/geany.git
" +GEANY_THEMES_REPOSITORY="
https://github.com/geany/geany-themes.git
" + +# rather static values, unlikely to be changed +GTK_BUNDLE_DIR="/build/gtk-bundle" +GEANY_SOURCE_DIR="/geany-source" +GEANY_BUILD_DIR="/build/geany-build" +GEANY_RELEASE_DIR="/build/geany-release" +GEANY_INSTALLER_FILENAME= # will be set below +GEANY_INSTALLATION_DIR_WIN="C:\\geany_install" +GEANY_INSTALLATION_DIR=$(winepath --unix ${GEANY_INSTALLATION_DIR_WIN}) +GEANY_THEMES_DIR="/build/geany-themes" +GEANY_RELEASE_BINARY_PATTERNS=( + "${GEANY_RELEASE_DIR}/bin/geany.exe" + "${GEANY_RELEASE_DIR}/bin/*.dll" + "${GEANY_RELEASE_DIR}/lib/geany/*.dll" +) +GEANY_RELEASE_TEXTFILE_PATTERNS=( + "${GEANY_RELEASE_DIR}/*.txt" + "${GEANY_RELEASE_DIR}/share/doc/geany/*" +) + +# CI CFLAGS +CFLAGS="\ + -Wall \ + -Wextra \ + -O2 \ + -Wunused \ + -Wno-unused-parameter \ + -Wunreachable-code \ + -Wformat=2 \ + -Wundef \ + -Wpointer-arith \ + -Wwrite-strings \ + -Waggregate-return \ + -Wmissing-prototypes \ + -Wmissing-declarations \ + -Wmissing-noreturn \ + -Wmissing-format-attribute \ + -Wredundant-decls \ + -Wnested-externs \ + -Wno-deprecated-declarations" + +# cross-compilation environment +ARCH="x86_64" +MINGW_ARCH="mingw64" +HOST="x86_64-w64-mingw32" +export CC="/usr/bin/${HOST}-gcc" +export CPP="/usr/bin/${HOST}-cpp" +export CXX="/usr/bin/${HOST}-g++" +export AR="/usr/bin/${HOST}-ar" +export STRIP="/usr/bin/${HOST}-strip" +export WINDRES="/usr/bin/${HOST}-windres" +export CFLAGS="-I/windows/${MINGW_ARCH}/include/ ${CFLAGS}" +export LDFLAGS="-static-libgcc ${LDFLAGS}" +export PKG_CONFIG_SYSROOT_DIR="/windows" +export PKG_CONFIG_PATH="/windows/${MINGW_ARCH}/lib/pkgconfig/" +export PKG_CONFIG="/usr/bin/pkg-config" +export NOCONFIGURE=1 + +# stop on errors +set -e + + +log() { + echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ===========" +} + + +git_clone_geany_if_necessary() { + if [ -d ${GEANY_SOURCE_DIR} ]; then + log "Copying Geany source" + cp --archive ${GEANY_SOURCE_DIR}/ ${GEANY_BUILD_DIR}/ + else + log "Cloning Geany repository from ${GEANY_GIT_REPOSITORY}" + git clone --depth 1 ${GEANY_GIT_REPOSITORY} ${GEANY_BUILD_DIR} + fi +} + + +parse_geany_version() { + GEANY_VERSION=$(sed -n -E -e 's/^AC_INIT.\[Geany\], \[(.+)\],/\1/p' ${GEANY_BUILD_DIR}/configure.ac) + GEANY_GIT_REVISION=$(cd ${GEANY_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true) + TIMESTAMP=$(date +%Y%m%d%H%M%S) + # add pull request number if this is a CI and a PR build + if [ "${GITHUB_PULL_REQUEST}" ]; then + GEANY_VERSION="${GEANY_VERSION}_pr_${TIMESTAMP}_${GITHUB_PULL_REQUEST}" + elif [ "${CI}" -a "${GEANY_GIT_REVISION}" ]; then + GEANY_VERSION="${GEANY_VERSION}_ci_${TIMESTAMP}_${GEANY_GIT_REVISION}" + elif [ "${GEANY_GIT_REVISION}" ]; then + GEANY_VERSION="${GEANY_VERSION}_git_${TIMESTAMP}_${GEANY_GIT_REVISION}" + fi + GEANY_INSTALLER_FILENAME="geany-${GEANY_VERSION}_setup.exe" +} + + +log_environment() { + log "Using environment" + CONFIGURE_OPTIONS="--disable-silent-rules --host=${HOST} --prefix=${GEANY_RELEASE_DIR} --with-libiconv-prefix=/windows/mingw64" + echo "Geany version : ${GEANY_VERSION}" + echo "Geany GIT revision : ${GEANY_GIT_REVISION}" + echo "PATH : ${PATH}" + echo "HOST : ${HOST}" + echo "CC : ${CC}" + echo "CFLAGS : ${CFLAGS}" + echo "Configure : ${CONFIGURE_OPTIONS}" +} + + +patch_version_information() { + log "Patching version information" + + if [ -z "${GEANY_GIT_REVISION}" ] && [ -z "${CI}" ]; then + return + fi + + # parse version string and decrement the patch and/or minor levels to keep nightly build + # versions below the next release version + regex='^([0-9]*)[.]([0-9]*)([.]([0-9]*))?' + if [[ ${GEANY_VERSION} =~ $regex ]]; then + MAJOR="${BASH_REMATCH[1]}" + MINOR="${BASH_REMATCH[2]}" + PATCH="${BASH_REMATCH[4]}" + if [ -z "${PATCH}" ] || [ "${PATCH}" = "0" ]; then + MINOR="$((MINOR-1))" + PATCH="90" + else + PATCH="$((PATCH-1))" + fi + else + echo "Could not extract or parse version tag" >&2 + exit 1 + fi + # replace version information in configure.ac and for Windows binaries + sed -i -E "s/^AC_INIT.\[Geany\], \[(.+)\],/AC_INIT(\[Geany\], \[${GEANY_VERSION}\],/" ${GEANY_BUILD_DIR}/configure.ac + sed -i -E "s/^#define VER_FILEVERSION_STR[[:space:]]+\".*\"+/#define VER_FILEVERSION_STR \"${GEANY_VERSION}\"/" ${GEANY_BUILD_DIR}/geany_private.rc + sed -i -E "s/^#define VER_FILEVERSION[[:space:]]+[0-9,]+/#define VER_FILEVERSION ${MAJOR},${MINOR},${PATCH},90/" ${GEANY_BUILD_DIR}/geany_private.rc + sed -i -E "s/^[[:space:]]+version=\"[0-9.]+\"/version=\"${MAJOR}.${MINOR}.${PATCH}.90\"/" ${GEANY_BUILD_DIR}/geany.exe.manifest + sed -i -E "s/^!define PRODUCT_VERSION \"@VERSION@\"/!define PRODUCT_VERSION \"${GEANY_VERSION}\"/" ${GEANY_BUILD_DIR}/geany.nsi.in + sed -i -E "s/^!define PRODUCT_VERSION_ID \"@VERSION@.0.0\"/!define PRODUCT_VERSION_ID \"${MAJOR}.${MINOR}.${PATCH}.90\"/" ${GEANY_BUILD_DIR}/geany.nsi.in +} + + +build_geany() { + cd ${GEANY_BUILD_DIR} + log "Running autogen.sh" + ./autogen.sh + log "Running configure" + ./configure ${CONFIGURE_OPTIONS} + log "Running make" + make + log "Running install-strip" + make install-strip + + cd / +} + + +sign_file() { + echo "Sign file $1" + if [ -f /certificates/cert.pem ] && [ -f /certificates/key.pem ]; then + osslsigncode sign \ + -certs /certificates/cert.pem \ + -key /certificates/key.pem \ + -n "Geany Binary" \ + -i "
https://www.geany.org/
" \ + -ts
http://zeitstempel.dfn.de/
\ + -h sha512 \ + -in ${1} \ + -out ${1}-signed + mv ${1}-signed ${1} + else + echo "Skip signing due to missing certificate" + fi +} + + +sign_geany_binaries() { + log "Signing Geany binary files" + for binary_file_pattern in ${GEANY_RELEASE_BINARY_PATTERNS[@]}; do + for binary_file in $(ls ${binary_file_pattern}); do + sign_file ${binary_file} + done + done +} + + +convert_text_files_to_crlf() { + log "Converting line endings to CRLF in text files" + for text_file_pattern in ${GEANY_RELEASE_TEXTFILE_PATTERNS[@]}; do + for text_file in $(ls ${text_file_pattern}); do + mime_type=$(file --brief --mime-type ${text_file}) + case $mime_type in text/*) + unix2dos ${text_file} + esac + done + done +} + + +create_gtk_bundle() { + log "Creating GTK bundle" + mkdir ${GTK_BUNDLE_DIR} + cd ${GTK_BUNDLE_DIR} + bash ${GEANY_BUILD_DIR}/scripts/gtk-bundle-from-msys2.sh -x -3 + cd / +} + + +fetch_geany_themes() { + log "Cloning Geany-Themes repository from ${GEANY_THEMES_REPOSITORY}" + git clone --depth 1 ${GEANY_THEMES_REPOSITORY} ${GEANY_THEMES_DIR} +} + + +create_installer() { + log "Creating NSIS installer" + makensis \ + -V3 \ + -WX \ + -DGEANY_INSTALLER_NAME="${GEANY_INSTALLER_FILENAME}" \ + -DGEANY_RELEASE_DIR=${GEANY_RELEASE_DIR} \ + -DGEANY_THEMES_DIR=${GEANY_THEMES_DIR} \ + -DGTK_BUNDLE_DIR=${GTK_BUNDLE_DIR} \ + ${GEANY_BUILD_DIR}/geany.nsi +} + + +sign_installer() { + log "Signing NSIS installer" + sign_file ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME} +} + + +test_installer() { + log "Test NSIS installer" + exiftool -FileName -FileType -FileVersion -FileVersionNumber ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME} + # install Geany: perform a silent install and check for installed files + mingw-w64-i686-wine ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME} /S /D=${GEANY_INSTALLATION_DIR_WIN} + # check if we have something installed + test -f ${GEANY_INSTALLATION_DIR}/uninst.exe || exit 1 + test -f ${GEANY_INSTALLATION_DIR}/bin/geany.exe || exit 1 + test -f ${GEANY_INSTALLATION_DIR}/lib/geany/export.dll || exit 1 + test ! -f ${GEANY_INSTALLATION_DIR}/lib/geany/demoplugin.dll || exit 1 +} + + +log_geany_version() { + log "Log installed Geany version" + mingw-w64-x86_64-wine ${GEANY_INSTALLATION_DIR}/bin/geany.exe --version 2>/dev/null + exiftool -FileName -FileType -FileVersion -FileVersionNumber ${GEANY_INSTALLATION_DIR}/bin/geany.exe +} + + +test_uninstaller() { + log "Test NSIS uninstaller" + # uninstall Geany and test if everything is clean + mingw-w64-i686-wine ${GEANY_INSTALLATION_DIR}/uninst.exe /S + sleep 10 # it seems the uninstaller returns earlier than the files are actually removed, so wait a moment + test ! -e ${GEANY_INSTALLATION_DIR} +} + + +copy_installer_and_bundle() { + log "Copying NSIS installer and GTK bundle" + cp ${GEANY_BUILD_DIR}/${GEANY_INSTALLER_FILENAME} ${OUTPUT_DIRECTORY} + cd ${GTK_BUNDLE_DIR} + zip --quiet --recurse-paths ${OUTPUT_DIRECTORY}/gtk_bundle_$(date '+%Y%m%dT%H%M%S').zip * + cd / +} + + +main() { + git_clone_geany_if_necessary + + parse_geany_version + log_environment + patch_version_information + build_geany + sign_geany_binaries + convert_text_files_to_crlf + + create_gtk_bundle + fetch_geany_themes + create_installer + sign_installer + + test_installer + log_geany_version + test_uninstaller + + copy_installer_and_bundle + + log "Done." +} + + +main Modified: builders/scripts/build_mingw64_geany_plugins.sh 356 lines changed, 356 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,356 @@ +#!/bin/bash +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Helper script to build Geany-Plugins for Windows in a Docker container. +# The following steps are performed: +# - clone Geany-Plugins repository if necessary (i.e. if it is not bind-mounted into the container) +# - cross-compile Geany-Plugins for Windows 64bit and GTK3 +# - sign all binaries and installer (if /certificates exist and contains cert.pem and key.pem) +# - create bundle with all dependencies +# - create the NSIS installer in ${OUTPUT_DIRECTORY} +# - test the created NSIS installer +# - test uninstaller and check there is nothing unexpected left after uninstalling +# +# This script has to be executed within the Docker container. +# The Docker container should have a bind-mount for ${OUTPUT_DIRECTORY} +# where the resulting installer binary is stored. +# +# To test the installer "wine" is used. +# Please note that we need to use wine32 as the created installer and uninstaller +# binaries are 32bit. +# + +GEANY_PLUGINS_VERSION= # will be set below from configure.ac +GEANY_PLUGINS_GIT_REVISION= # will be set below from configure.ac +OUTPUT_DIRECTORY="/output" +GEANY_PLUGINS_GIT_REPOSITORY="
https://github.com/geany/geany-plugins.git
" + +# rather static values, unlikely to be changed +DEPENDENCY_BUNDLE_DIR="/build/dependencies-bundle" +GEANY_PLUGINS_SOURCE_DIR="/geany-plugins-source" +GEANY_PLUGINS_BUILD_DIR="/build/geany-plugins-build" +GEANY_PLUGINS_RELEASE_DIR="/build/geany-plugins-release" +GEANY_PLUGINS_INSTALLER_FILENAME= # will be set below +GEANY_PLUGINS_INSTALLATION_DIR_WIN="C:\\geany_plugins_install" +GEANY_PLUGINS_INSTALLATION_DIR=$(winepath --unix ${GEANY_PLUGINS_INSTALLATION_DIR_WIN}) +GEANY_PLUGINS_RELEASE_BINARY_PATTERNS=( + "${GEANY_PLUGINS_RELEASE_DIR}/lib/geany/*.dll" + "${GEANY_PLUGINS_RELEASE_DIR}/lib/geany-plugins/geanylua/libgeanylua.dll" + "${GEANY_PLUGINS_RELEASE_DIR}/bin/libgeanypluginutils*.dll" +) + +GEANY_PLUGINS_RELEASE_TEXTFILE_PATTERNS=( + "${GEANY_PLUGINS_RELEASE_DIR}/share/doc/geany-plugins/*" + "${GEANY_PLUGINS_RELEASE_DIR}/share/doc/geany-plugins/*/*" +) +GEANY_INSTALLATION_DIR="/root/.wine/drive_c/geany_install" + +GEANY_INSTALL_DIR_WIN=$(winepath --windows ${GEANY_INSTALLATION_DIR}) +GEANY_INSTALLER_EXECUTABLE=$(ls ${OUTPUT_DIRECTORY}/geany-*_setup.exe) + +# TODO move to include and use it also in Geany build script +# CI CFLAGS +CFLAGS="\ + -Wall \ + -Wextra \ + -O2 \ + -Wunused \ + -Wno-unused-parameter \ + -Wunreachable-code \ + -Wformat=2 \ + -Wundef \ + -Wpointer-arith \ + -Wwrite-strings \ + -Waggregate-return \ + -Wmissing-prototypes \ + -Wmissing-declarations \ + -Wmissing-noreturn \ + -Wmissing-format-attribute \ + -Wredundant-decls \ + -Wnested-externs \ + -Wno-deprecated-declarations" + +# cross-compilation environment +ARCH="x86_64" +MINGW_ARCH="mingw64" +HOST="x86_64-w64-mingw32" +export CC="/usr/bin/${HOST}-gcc" +export CPP="/usr/bin/${HOST}-cpp" +export CXX="/usr/bin/${HOST}-g++" +export AR="/usr/bin/${HOST}-ar" +export STRIP="/usr/bin/${HOST}-strip" +export WINDRES="/usr/bin/${HOST}-windres" +export CFLAGS="-I/windows/${MINGW_ARCH}/include/ ${CFLAGS}" +export LDFLAGS="-static-libgcc ${LDFLAGS}" +export PKG_CONFIG_SYSROOT_DIR="/windows" +export PKG_CONFIG_PATH="/windows/${MINGW_ARCH}/lib/pkgconfig/" +export PKG_CONFIG="/usr/bin/pkg-config" +export NOCONFIGURE=1 + +# stop on errors +set -e + + +log() { + echo "=========== $(date '+%Y-%m-%d %H:%M:%S %Z') $* ===========" +} + + +git_clone_geany_plugins_if_necessary() { + if [ -d ${GEANY_PLUGINS_SOURCE_DIR} ]; then + log "Copying Geany-Plugins source" + cp --archive ${GEANY_PLUGINS_SOURCE_DIR}/ ${GEANY_PLUGINS_BUILD_DIR}/ + else + log "Cloning Geany-Plugins repository from ${GEANY_PLUGINS_GIT_REPOSITORY}" + git clone --depth 1 ${GEANY_PLUGINS_GIT_REPOSITORY} ${GEANY_PLUGINS_BUILD_DIR} + fi +} + + +parse_geany_plugins_version() { + GEANY_PLUGINS_VERSION=$(sed -n -E -e 's/^AC_INIT.\[geany-plugins\], \[(.+)\]./\1/p' ${GEANY_PLUGINS_BUILD_DIR}/configure.ac) + GEANY_PLUGINS_GIT_REVISION=$(cd ${GEANY_PLUGINS_BUILD_DIR} && git rev-parse --short --revs-only HEAD 2>/dev/null || true) + TIMESTAMP=$(date +%Y%m%d%H%M%S) + # add pull request number if this is a CI and a PR build + if [ "${GITHUB_PULL_REQUEST}" ]; then + GEANY_PLUGINS_VERSION="${GEANY_PLUGINS_VERSION}_pr_${TIMESTAMP}_${GITHUB_PULL_REQUEST}" + elif [ "${CI}" -a "${GEANY_PLUGINS_GIT_REVISION}" ]; then + GEANY_PLUGINS_VERSION="${GEANY_PLUGINS_VERSION}_ci_${TIMESTAMP}_${GEANY_PLUGINS_GIT_REVISION}" + elif [ "${GEANY_PLUGINS_GIT_REVISION}" ]; then + GEANY_PLUGINS_VERSION="${GEANY_PLUGINS_VERSION}_git_${TIMESTAMP}_${GEANY_PLUGINS_GIT_REVISION}" + fi + GEANY_PLUGINS_INSTALLER_FILENAME="geany-plugins-${GEANY_PLUGINS_VERSION}_setup.exe" +} + + +log_environment() { + log "Using environment" + CONFIGURE_OPTIONS="--disable-silent-rules --host=${HOST} --prefix=${GEANY_PLUGINS_RELEASE_DIR} --with-geany-libdir=${GEANY_PLUGINS_RELEASE_DIR}/lib" + echo "Geany-Plugins version : ${GEANY_PLUGINS_VERSION}" + echo "Geany-Plugins GIT revision : ${GEANY_PLUGINS_GIT_REVISION}" + echo "Geany installer : ${GEANY_INSTALLER_EXECUTABLE}" + echo "PATH : ${PATH}" + echo "HOST : ${HOST}" + echo "CC : ${CC}" + echo "CFLAGS : ${CFLAGS}" + echo "Configure : ${CONFIGURE_OPTIONS}" +} + + +patch_version_information() { + log "Patching version information" + + if [ -z "${GEANY_PLUGINS_GIT_REVISION}" ] && [ -z "${TRAVIS_PULL_REQUEST}" ]; then + return + fi + + # parse version string and decrement the patch and/or minor levels to keep nightly build + # versions below the next release version + regex='^([0-9]*)[.]([0-9]*)([.]([0-9]*))?' + if [[ ${GEANY_PLUGINS_VERSION} =~ $regex ]]; then + MAJOR="${BASH_REMATCH[1]}" + MINOR="${BASH_REMATCH[2]}" + PATCH="${BASH_REMATCH[4]}" + if [ -z "${PATCH}" ] || [ "${PATCH}" = "0" ]; then + MINOR="$((MINOR-1))" + PATCH="90" + else + PATCH="$((PATCH-1))" + fi + else + echo "Could not extract or parse version tag" >&2 + exit 1 + fi + # replace version information in configure.ac and for Windows binaries + sed -i -E "s/^AC_INIT.\[geany-plugins\], \[(.+)\],/AC_INIT(\[geany-plugins\], \[${GEANY_PLUGINS_VERSION}\],/" ${GEANY_PLUGINS_BUILD_DIR}/configure.ac + sed -i -E "s/^!define PRODUCT_VERSION \"(.+)\"/!define PRODUCT_VERSION \"${GEANY_PLUGINS_VERSION}\"/" ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi + sed -i -E "s/^!define PRODUCT_VERSION_ID \"(.+)\"/!define PRODUCT_VERSION_ID \"${MAJOR}.${MINOR}.${PATCH}.90\"/" ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi + sed -i -E "s/^!define REQUIRED_GEANY_VERSION \"(.+)\"/!define REQUIRED_GEANY_VERSION \"${MAJOR}.${MINOR}\"/" ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi +} + + +install_dependencies() { + log "Installing build dependencies" + pacman --noconfirm -Syu + pacman --noconfirm -S \ + mingw-w64-${ARCH}-check \ + mingw-w64-${ARCH}-cppcheck \ + mingw-w64-${ARCH}-ctpl-git \ + mingw-w64-${ARCH}-enchant \ + mingw-w64-${ARCH}-gpgme \ + mingw-w64-${ARCH}-gtkspell3 \ + mingw-w64-${ARCH}-libgit2 \ + mingw-w64-${ARCH}-libsoup \ + mingw-w64-${ARCH}-lua51 +} + + +install_geany() { + log "Installing Geany (using wine)" + if [ -z "${GEANY_INSTALLER_EXECUTABLE}" -o ! -f "${GEANY_INSTALLER_EXECUTABLE}" ]; then + echo "No Geany installer found" + exit 1 + fi + mingw-w64-i686-wine ${GEANY_INSTALLER_EXECUTABLE} /S /D=${GEANY_INSTALL_DIR_WIN} + + # TODO the following steps are way too hacky: installing Geany from the installer is basically + # what we want for CI tests but the installed "geany.pc" file isn't really suitable + # for cross-compiling + + # add the Geany installation directory to the PKG_CONFIG_PATH + export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${GEANY_INSTALLATION_DIR}/lib/pkgconfig/" + # patch Geany pkg-config prefix: pkg-config always prepend "/windows" to the "prefix" variable, so we + # need to add ../ to get out of the hardcoded "/windows" path element + sed -i "s%^\(prefix=\).*$%\1/..${GEANY_INSTALLATION_DIR}%" ${GEANY_INSTALLATION_DIR}/lib/pkgconfig/geany.pc + sed -i "s%^\(exec_prefix=\).*$%\1/..${GEANY_INSTALLATION_DIR}%" ${GEANY_INSTALLATION_DIR}/lib/pkgconfig/geany.pc + # we need "${exec_prefix}/bin" additionally for libgeany-0.dll which is installed into bin/ and replace -lgeany by -lgeany-0 + sed -i "s%^Libs: -L\${libdir} -lgeany$%Libs: -L\${libdir} -L\${exec_prefix}/bin -lgeany-0%" ${GEANY_INSTALLATION_DIR}/lib/pkgconfig/geany.pc +} + + +build_geany_plugins() { + cd ${GEANY_PLUGINS_BUILD_DIR} + log "Running autogen.sh" + ./autogen.sh + log "Running configure" + ./configure ${CONFIGURE_OPTIONS} + log "Running make" + make + log "Running install-strip" + make install-strip + + cd / +} + + +sign_file() { + echo "Sign file $1" + if [ -f /certificates/cert.pem ] && [ -f /certificates/key.pem ]; then + osslsigncode sign \ + -certs /certificates/cert.pem \ + -key /certificates/key.pem \ + -n "Geany-Plugins Binary" \ + -i "
https://www.geany.org/
" \ + -ts
http://zeitstempel.dfn.de/
\ + -h sha512 \ + -in ${1} \ + -out ${1}-signed + mv ${1}-signed ${1} + else + echo "Skip signing due to missing certificate" + fi +} + + +sign_geany_plugins_binaries() { + log "Signing Geany-Plugins binary files" + for binary_file_pattern in ${GEANY_PLUGINS_RELEASE_BINARY_PATTERNS[@]}; do + for binary_file in $(ls ${binary_file_pattern}); do + sign_file ${binary_file} + done + done +} + + +convert_text_files_to_crlf() { + log "Converting line endings to CRLF in text files" + for text_file_pattern in ${GEANY_PLUGINS_RELEASE_TEXTFILE_PATTERNS[@]}; do + for text_file in $(ls ${text_file_pattern}); do + mime_type=$(file --brief --mime-type ${text_file}) + case $mime_type in text/*) + unix2dos ${text_file} + esac + done + done +} + + +create_dependencies_bundle() { + log "Creating Geany-Plugins dependencies bundle" + mkdir ${DEPENDENCY_BUNDLE_DIR} + cd ${DEPENDENCY_BUNDLE_DIR} + bash ${GEANY_PLUGINS_BUILD_DIR}/build/gtk-bundle-from-msys2.sh -x -3 + cd / +} + + +create_installer() { + log "Creating NSIS installer" + makensis \ + -V3 \ + -WX \ + -DGEANY_PLUGINS_INSTALLER_NAME="${GEANY_PLUGINS_INSTALLER_FILENAME}" \ + -DGEANY_PLUGINS_RELEASE_DIR=${GEANY_PLUGINS_RELEASE_DIR} \ + -DDEPENDENCY_BUNDLE_DIR=${DEPENDENCY_BUNDLE_DIR} \ + ${GEANY_PLUGINS_BUILD_DIR}/build/geany-plugins.nsi +} + + +sign_installer() { + log "Signing NSIS installer" + sign_file ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME} +} + + +test_installer() { + log "Test NSIS installer" + # perform a silent install and check for installed files + exiftool -FileName -FileType -FileVersion -FileVersionNumber ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME} + # install Geany-Plugins + mingw-w64-i686-wine ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME} /S /D=${GEANY_PLUGINS_INSTALLATION_DIR_WIN} + # check if we have something installed + ls -l ${GEANY_PLUGINS_INSTALLATION_DIR}/uninst-plugins.exe || exit 1 + ls -l ${GEANY_PLUGINS_INSTALLATION_DIR}/lib/geany/addons.dll || exit 1 +} + + +test_uninstaller() { + log "Test NSIS uninstaller" + # uninstall Geany-Plugins and test if everything is clean + mingw-w64-i686-wine ${GEANY_PLUGINS_INSTALLATION_DIR}/uninst-plugins.exe /S + sleep 15 # it seems the uninstaller returns earlier than the files are actually removed, so wait a moment + rest=$(find ${GEANY_PLUGINS_INSTALLATION_DIR} \( -path '*share/locale' -o -path '*share/licenses' \) -prune -false -o -true -printf '%P ') + if [ "${rest}" != " share share/locale share/licenses " ]; then + # do not treat this as error, it might happen if upstream dependencies have been updated, + # the list of files to be removed needs to be updated only before releases + echo "WARNING: Uninstaller failed to uninstall the following files files: ${rest}" + fi +} + + +copy_installer_and_bundle() { + log "Copying NSIS installer and dependencies bundle" + cp ${GEANY_PLUGINS_BUILD_DIR}/build/${GEANY_PLUGINS_INSTALLER_FILENAME} ${OUTPUT_DIRECTORY} + cd ${DEPENDENCY_BUNDLE_DIR} + zip --quiet --recurse-paths ${OUTPUT_DIRECTORY}/geany_plugins_dependencies_bundle_$(date '+%Y%m%dT%H%M%S').zip * + cd / +} + + +main() { + git_clone_geany_plugins_if_necessary + + parse_geany_plugins_version + log_environment + patch_version_information + install_dependencies + install_geany + build_geany_plugins + sign_geany_plugins_binaries + convert_text_files_to_crlf + + create_dependencies_bundle + create_installer + sign_installer + copy_installer_and_bundle + + test_installer + test_uninstaller + + log "Done." +} + + +main Modified: builders/scripts/update_debian_repositories.sh 49 lines changed, 49 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Create a Debian repository for the Debian distribution +# requested in the environment variable ${DISTRO}. +# The repository will be signed with the GnuPG key as found +# in /gnupg (which must be provided from the caller). +# +# This script is meant to be run in a Docker container. +# + + +# codename -> suite mapping +declare -A SUITES=([buster]=stable [sid]=unstable) + +# stop on errors +set -e + +# cleanup +rm -rf /repository/conf +rm -rf /repository/db +rm -rf /repository/dists +rm -rf /repository/pool + +# create repository config +mkdir /repository/conf +cat << CONF > /repository/conf/distributions +Codename: ${DISTRO} +Suite: ${SUITES[${DISTRO}]} +Components: main +Architectures: amd64 source +SignWith: ${GNUPG_KEYID} +CONF + +# create repository +reprepro --silent --gnupghome /gnupg -b /repository createsymlinks +package_paths=`find /output -name '*.deb'` +for package in ${package_paths} +do + reprepro --silent --gnupghome /gnupg -b /repository includedeb ${DISTRO} ${package} +done +# add source packages +dsc_paths=`find /output -name '*.dsc'` +for dsc in ${dsc_paths} +do + reprepro --silent --gnupghome /gnupg -b /repository includedsc ${DISTRO} ${dsc} +done Modified: builders/start_build.sh 294 lines changed, 294 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,294 @@ +#!/bin/bash +# +# Copyright 2022 The Geany contributors +# License: GPLv2 +# +# Run Debian and Windows build containers and start builds within. +# The Docker image for the containers are rebuilt automatically +# every 30 days to keep them up to date. +# +# This script has to be run outside of the containers. +# +# usage: start_build.sh [-d|--distro DISTRO] [-m|--mingw64] +# [-r|--rebuild-images] +# -d, --distro DISTRO Build for target Debian DISTRO (e.g. "bullseye", +# can be specified multiple times +# -f, --force-rebuild Force rebuilding of immages even if not necessary +# -g, --geany Build Geany +# --geany-source Path to a Geany source directory (optional, cloned from GIT if missing) +# --geany-plugins-source Path to a Geany-Plugins source directory (optional, cloned from GIT if missing) +# -h Show this help screen +# -l, --log-to-stdout Log build output additionally to stdout +# -m, --mingw64 Build for target Mingw-w64 +# -p, --geany-plugins Build Geany-Plugins +# -r, --rebuild-images Rebuild Docker images before start building +# (images are rebuilt automatically every 30 days) +# -s, --sudo Use "sudo" for Docker commands + + +DOCKER_IMAGE_MAX_AGE_DAYS=30 +# GNUPG config for the Debian repository, path and key must exist on the local machine +GNUPG_HOME=${GNUPG_HOME:-~/.gnupg} +GNUPG_KEYID=${GNUPG_KEYID:-0EE5B5AD} + +BASE_OUTPUT_DIRECTORY="${PWD}/output/" +DOCKER_CMD="docker" +GEANY_SOURCE= +GEANY_PLUGINS_SOURCE= + +# stop on errors +set -e +set -o pipefail + + +log() { + log_filename="$1" + shift + if [ "${log_filename}" = "-" ]; then + echo "========== $(date '+%Y-%m-%d %H:%M:%S %Z') $@ ==========" + else + if [ -n "${DO_LOG_TO_STDOUT}" ]; then + $@ 2>&1 | tee "${log_filename}" + else + $@ > "${log_filename}" 2>&1 + fi + fi +} + + +rebuild_image() { + image_name="$1" + dockerfile="$2" + build_args="$3" + # query image created date or use 0 if the image does not exist to trigger a build + image_date=$(${DOCKER_CMD} image inspect --format='{{.Created}}' "${image_name}" 2>/dev/null || echo -n 1970-01-01) + image_date=$(echo "${image_date}" | xargs) # trim leading and trailing whitespace + image_date_seconds=$(date --date="${image_date}" "+%s") + expire_date_seconds=$(date --date="${DOCKER_IMAGE_MAX_AGE_DAYS} days ago" "+%s") + if [ "${image_date_seconds}" -lt "${expire_date_seconds}" ] || [ -n "${DO_FORCE_IMAGE_REBUILD}" ]; then + log - "Building image ${image_name} (last build: ${image_date})" + log "${BASE_OUTPUT_DIRECTORY}/docker_image_build_${image_name}_$(date '+%Y_%m_%d_%H_%M_%S').log" \ + ${DOCKER_CMD} build \ + --no-cache \ + --file "${dockerfile}" \ + --label "org.opencontainers.image.created=$(date --iso-8601=seconds)" \ + --tag "${image_name}" \ + ${build_args} \ + . + fi +} + + +build_for_debian_distro() { + distro=${1} + IMAGE_NAME_DEBIAN="geany-debian-${distro}-ci" + OUTPUT_DIRECTORY=${BASE_OUTPUT_DIRECTORY}/${distro} + LOGFILE_GEANY=${OUTPUT_DIRECTORY}/build_debian_${distro}_geany_$(date '+%Y_%m_%d_%H_%M_%S').log + LOGFILE_GEANY_PLUGINS=${OUTPUT_DIRECTORY}/build_debian_${distro}_geany_plugins_$(date '+%Y_%m_%d_%H_%M_%S').log + + mkdir -p "${OUTPUT_DIRECTORY}/geany" "${OUTPUT_DIRECTORY}/geany-plugins" + + # (re)build Docker image + rebuild_image "${IMAGE_NAME_DEBIAN}" Dockerfile.debian "--build-arg BASE_IMAGE_NAME=debian:${distro}" + + # build Geany + if [ -n "${DO_GEANY}" ]; then + log - "Building Geany for ${distro}" + log "${LOGFILE_GEANY}" \ + ${DOCKER_CMD} run \ + --rm \ + --env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \ + --env=CI="${CI}" \ + --volume "${PWD}/scripts:/scripts/" \ + --volume "${OUTPUT_DIRECTORY}:/output/" \ + --tmpfs /tmp:rw,exec,size=1024m \ + "${IMAGE_NAME_DEBIAN}:latest" \ + bash /scripts/build_debian_geany.sh + fi + + # build Geany-Plugins + if [ -n "${DO_GEANY_PLUGINS}" ]; then + log - "Building Geany-Plugins for ${distro}" + log "${LOGFILE_GEANY_PLUGINS}" \ + ${DOCKER_CMD} run \ + --rm \ + --env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \ + --env=CI="${CI}" \ + --volume "${PWD}/scripts:/scripts/" \ + --volume "${OUTPUT_DIRECTORY}:/output/" \ + --tmpfs /tmp:rw,exec,size=1024m \ + "${IMAGE_NAME_DEBIAN}:latest" \ + bash /scripts/build_debian_geany_plugins.sh + fi + + # build/update Debian repository + log - "Update Debian repository for ${distro}" + log "${OUTPUT_DIRECTORY}/build_debian_repository_$(date '+%Y_%m_%d_%H_%M_%S').log" \ + ${DOCKER_CMD} run \ + --rm \ + --env GNUPG_KEYID="${GNUPG_KEYID}" \ + --env DISTRO="${distro}" \ + --volume "${PWD}/scripts:/scripts/" \ + --volume "${GNUPG_HOME}:/gnupg/" \ + --volume "${OUTPUT_DIRECTORY}:/output/" \ + --volume "${BASE_OUTPUT_DIRECTORY}/repositories/${distro}:/repository/" \ + "${IMAGE_NAME_DEBIAN}:latest" \ + bash /scripts/update_debian_repositories.sh +} + + +build_mingw64() { + IMAGE_NAME_WINDOWS="geany-mingw64-ci" + MINGW64_OUTPUT_DIRECTORY=${BASE_OUTPUT_DIRECTORY}/mingw64 + LOGFILE_MINGW64_GEANY=${MINGW64_OUTPUT_DIRECTORY}/build_mingw64_geany_$(date '+%Y_%m_%d_%H_%M_%S').log + LOGFILE_MINGW64_GEANY_PLUGINS=${MINGW64_OUTPUT_DIRECTORY}/build_mingw64_geany_plugins_$(date '+%Y_%m_%d_%H_%M_%S').log + mkdir -p "${MINGW64_OUTPUT_DIRECTORY}" + + # (re)build Docker image + rebuild_image ${IMAGE_NAME_WINDOWS} Dockerfile.mingw64 + + # Build Geany + if [ -n "${DO_GEANY}" ]; then + log - "Building Geany for Windows" + if [ -n "${GEANY_SOURCE}" ]; then + source_volume="--volume ${GEANY_SOURCE}:/geany-source/:ro" + else + source_volume= + fi + log "${LOGFILE_MINGW64_GEANY}" \ + ${DOCKER_CMD} run \ + --rm \ + --env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \ + --env=CI="${CI}" \ + ${source_volume} \ + --volume "${PWD}/scripts:/scripts/" \ + --volume "${PWD}/certificates/:/certificates/" \ + --volume "${MINGW64_OUTPUT_DIRECTORY}:/output/" \ + "${IMAGE_NAME_WINDOWS}:latest" \ + bash /scripts/build_mingw64_geany.sh + fi + + # Build Geany-Plugins + if [ -n "${DO_GEANY_PLUGINS}" ]; then + log - "Building Geany-Plugins for Windows" + if [ -n "${GEANY_PLUGINS_SOURCE}" ]; then + source_volume="--volume ${GEANY_PLUGINS_SOURCE}:/geany-plugins-source/:ro" + else + source_volume= + fi + log "${LOGFILE_MINGW64_GEANY_PLUGINS}" \ + ${DOCKER_CMD} run \ + --rm \ + --env=GITHUB_PULL_REQUEST="${GITHUB_PULL_REQUEST}" \ + --env=CI="${CI}" \ + ${source_volume} \ + --volume "${PWD}/scripts:/scripts/" \ + --volume "${PWD}/certificates/:/certificates/" \ + --volume "${MINGW64_OUTPUT_DIRECTORY}:/output/" \ + "${IMAGE_NAME_WINDOWS}:latest" \ + bash /scripts/build_mingw64_geany_plugins.sh + fi +} + + +usage() { + echo "usage: start_build.sh [-d|--distro DISTRO] [-m|--mingw64]" + echo " [-r|--rebuild-images]" + echo " -d, --distro DISTRO Build for target Debian DISTRO (e.g. \"bullseye\"," + echo " can be specified multiple times" + echo " -g, --geany Build Geany" + echo "--geany-source Path to a Geany source directory (optional, cloned from GIT if missing)" + echo "--geany-plugins-source Path to a Geany-Plugins source directory (optional, cloned from GIT if missing)" + echo " -h Show this help screen" + echo " -l, --log-to-stdout Log build output additionally to stdout" + echo " -m, --mingw64 Build for target Mingw-w64" + echo " -p, --geany-plugins Build Geany-Plugins" + echo " -r, --rebuild-images Rebuild Docker images before start building" + echo " (images are rebuilt automatically every ${DOCKER_IMAGE_MAX_AGE_DAYS} days)" + echo " -s, --sudo Use \"sudo\" for Docker commands" + exit 1 +} + + +parse_command_line_options() { + if [ $# -eq 0 ]; then + usage + fi + for opt in "$@"; do + case "$opt" in + -d|--distro) + DO_DISTRO="${DO_DISTRO} ${2}" + shift + shift + ;; + -f|--force-rebuild) + DO_FORCE_IMAGE_REBUILD=1 + shift + ;; + -g|--geany) + DO_GEANY=1 + shift + ;; + --geany-source) + GEANY_SOURCE="${2}" + shift + shift + ;; + --geany-plugins-source) + GEANY_PLUGINS_SOURCE="${2}" + shift + shift + ;; + -l|--log-to-stdout) + DO_LOG_TO_STDOUT=1 + shift + ;; + -m|--mingw64) + DO_MINGW64=1 + shift + ;; + -p|--geany-plugins) + DO_GEANY_PLUGINS=1 + shift + ;; + -r|--rebuild-images) + DO_IMAGE_REBUILD=1 + shift + ;; + -s|--sudo) + DOCKER_CMD="sudo docker" + shift + ;; + -h|--help) + usage + ;; + esac + done +} + + +DO_DISTRO= +DO_MINGW64= +DO_IMAGE_REBUILD= +DO_FORCE_IMAGE_REBUILD= +DO_GEANY= +DO_GEANY_PLUGINS= +DO_LOG_TO_STDOUT= +GEANY_SOURCE= +GEANY_PLUGINS_SOURCE= + + +main() { + if [ -n "${DO_DISTRO}" ]; then + for distro in ${DO_DISTRO}; do + build_for_debian_distro "${distro}" + done + fi + if [ -n "${DO_MINGW64}" ]; then + build_mingw64 + fi +} + + +parse_command_line_options $@ +main -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/infrastructure] 6362b2: Add option to force rebuilding images
by Enrico Tröger
06 Mar '22
06 Mar '22
Branch: refs/heads/add_ci_builders Author: Enrico Tröger <enrico.troeger(a)uvena.de> Committer: Enrico Tröger <enrico.troeger(a)uvena.de> Date: Sun, 06 Mar 2022 18:00:46 UTC Commit: 6362b27ae6ae7ae951262ae4d8a7bfb84e9a44bd
https://github.com/geany/infrastructure/commit/6362b27ae6ae7ae951262ae4d8a7…
Log Message: ----------- Add option to force rebuilding images Modified Paths: -------------- builders/README.md builders/start_build.sh Modified: builders/README.md 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -55,6 +55,7 @@ the builds of Geany and Geany-Plugins for the various targets. [-r|--rebuild-images] -d, --distro DISTRO Build for target Debian DISTRO (e.g. "bullseye", can be specified multiple times + -f, --force-rebuild Force rebuilding of immages even if not necessary -g, --geany Build Geany --geany-source Path to a Geany source directory (optional, cloned from GIT if missing) --geany-plugins-source Path to a Geany-Plugins source directory (optional, cloned from GIT if missing) Modified: builders/start_build.sh 8 lines changed, 7 insertions(+), 1 deletions(-) =================================================================== @@ -13,6 +13,7 @@ # [-r|--rebuild-images] # -d, --distro DISTRO Build for target Debian DISTRO (e.g. "bullseye", # can be specified multiple times +# -f, --force-rebuild Force rebuilding of immages even if not necessary # -g, --geany Build Geany # --geany-source Path to a Geany source directory (optional, cloned from GIT if missing) # --geany-plugins-source Path to a Geany-Plugins source directory (optional, cloned from GIT if missing) @@ -63,7 +64,7 @@ rebuild_image() { image_date=$(echo "${image_date}" | xargs) # trim leading and trailing whitespace image_date_seconds=$(date --date="${image_date}" "+%s") expire_date_seconds=$(date --date="${DOCKER_IMAGE_MAX_AGE_DAYS} days ago" "+%s") - if [ "${image_date_seconds}" -lt "${expire_date_seconds}" ] || [ -n "${DO_IMAGE_REBUILD}" ]; then + if [ "${image_date_seconds}" -lt "${expire_date_seconds}" ] || [ -n "${DO_FORCE_IMAGE_REBUILD}" ]; then log - "Building image ${image_name} (last build: ${image_date})" log "${BASE_OUTPUT_DIRECTORY}/docker_image_build_${image_name}_$(date '+%Y_%m_%d_%H_%M_%S').log" \ ${DOCKER_CMD} build \ @@ -219,6 +220,10 @@ parse_command_line_options() { shift shift ;; + -f|--force-rebuild) + DO_FORCE_IMAGE_REBUILD=1 + shift + ;; -g|--geany) DO_GEANY=1 shift @@ -264,6 +269,7 @@ parse_command_line_options() { DO_DISTRO= DO_MINGW64= DO_IMAGE_REBUILD= +DO_FORCE_IMAGE_REBUILD= DO_GEANY= DO_GEANY_PLUGINS= DO_LOG_TO_STDOUT= -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/infrastructure] 01031a: Update MSYS2 keyring package
by Enrico Tröger
06 Mar '22
06 Mar '22
Branch: refs/heads/add_ci_builders Author: Enrico Tröger <enrico.troeger(a)uvena.de> Committer: Enrico Tröger <enrico.troeger(a)uvena.de> Date: Sun, 06 Mar 2022 16:39:02 UTC Commit: 01031a2ccceb15f08e6910810f0a199887cd12c4
https://github.com/geany/infrastructure/commit/01031a2ccceb15f08e6910810f0a…
Log Message: ----------- Update MSYS2 keyring package Modified Paths: -------------- builders/Dockerfile.mingw64 Modified: builders/Dockerfile.mingw64 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -13,8 +13,8 @@ FROM debian:bullseye as build-pacman ENV PACMAN_VERSION=6.0.1 ENV PACMAN_SHA256="0db61456e56aa49e260e891c0b025be210319e62b15521f29d3e93b00d3bf731" -ENV MSYS2_KEYRING_PKG="msys2-keyring-1~20210904-1-any.pkg.tar.zst" -ENV MSYS2_KEYRING_PKG_SHA256="2b2d387edd7c85b27c38f9965854a600c3810714e9aedb35b40d380ff4be24a9" +ENV MSYS2_KEYRING_PKG="msys2-keyring-1~20211228-1-any.pkg.tar.zst" +ENV MSYS2_KEYRING_PKG_SHA256="1ef41c9c7c829e2612020cfa41136f552b509a8269fdb7fbbeddc59329c9b11b" ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pacman/lib/x86_64-linux-gnu RUN set -ex && \ -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/infrastructure] ef36aa: Add"ci" suffix to Docker image names
by Enrico Tröger
06 Mar '22
06 Mar '22
Branch: refs/heads/add_ci_builders Author: Enrico Tröger <enrico.troeger(a)uvena.de> Committer: Enrico Tröger <enrico.troeger(a)uvena.de> Date: Sun, 06 Mar 2022 16:07:03 UTC Commit: ef36aa1fa1fe8117906cbe3392336f063d357993
https://github.com/geany/infrastructure/commit/ef36aa1fa1fe8117906cbe339233…
Log Message: ----------- Add"ci" suffix to Docker image names Modified Paths: -------------- builders/start_build.sh Modified: builders/start_build.sh 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -79,7 +79,7 @@ rebuild_image() { build_for_debian_distro() { distro=${1} - IMAGE_NAME_DEBIAN="geany-debian-${distro}" + IMAGE_NAME_DEBIAN="geany-debian-${distro}-ci" OUTPUT_DIRECTORY=${BASE_OUTPUT_DIRECTORY}/${distro} LOGFILE_GEANY=${OUTPUT_DIRECTORY}/build_debian_${distro}_geany_$(date '+%Y_%m_%d_%H_%M_%S').log LOGFILE_GEANY_PLUGINS=${OUTPUT_DIRECTORY}/build_debian_${distro}_geany_plugins_$(date '+%Y_%m_%d_%H_%M_%S').log @@ -136,7 +136,7 @@ build_for_debian_distro() { build_mingw64() { - IMAGE_NAME_WINDOWS="geany-mingw64" + IMAGE_NAME_WINDOWS="geany-mingw64-ci" MINGW64_OUTPUT_DIRECTORY=${BASE_OUTPUT_DIRECTORY}/mingw64 LOGFILE_MINGW64_GEANY=${MINGW64_OUTPUT_DIRECTORY}/build_mingw64_geany_$(date '+%Y_%m_%d_%H_%M_%S').log LOGFILE_MINGW64_GEANY_PLUGINS=${MINGW64_OUTPUT_DIRECTORY}/build_mingw64_geany_plugins_$(date '+%Y_%m_%d_%H_%M_%S').log -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 2ed4fc: Remove pref "Use project-based session files", now always enabled
by Thomas Martitz
05 Mar '22
05 Mar '22
Branch: refs/heads/master Author: Thomas Martitz <thomas.martitz(a)mailbox.org> Committer: Thomas Martitz <thomas.martitz(a)mailbox.org> Date: Thu, 17 Feb 2022 21:40:36 UTC Commit: 2ed4fc9eb6fa12fe03de3917ebe00b4485894f8a
https://github.com/geany/geany/commit/2ed4fc9eb6fa12fe03de3917ebe00b4485894…
Log Message: ----------- Remove pref "Use project-based session files", now always enabled As per #267 we agreed that this pref makes little sense. Especially as we're considering to move the project session files to a completely separate file (so neither geany.conf nor $project.geany). Currently, if not checked, the project session files would be stored in the (new) session.conf file, overwriting the non-project session. This is what #267 is about. Modified Paths: -------------- data/geany.glade src/keyfile.c src/libmain.c src/prefs.c src/project.c src/project.h Modified: data/geany.glade 16 lines changed, 0 insertions(+), 16 deletions(-) =================================================================== @@ -1445,22 +1445,6 @@ <object class="GtkVBox" id="vbox35"> <property name="visible">True</property> <property name="can-focus">False</property> - <child> - <object class="GtkCheckButton" id="check_project_session"> - <property name="label" translatable="yes">Use project-based session files</property> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">False</property> - <property name="tooltip-text" translatable="yes">Whether to store a project's session files and open them when re-opening the project</property> - <property name="use-underline">True</property> - <property name="draw-indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> <child> <object class="GtkCheckButton" id="check_project_file_in_basedir"> <property name="label" translatable="yes">Store project file inside the project base directory</property> Modified: src/keyfile.c 2 lines changed, 0 insertions(+), 2 deletions(-) =================================================================== @@ -458,7 +458,6 @@ static void save_dialog_prefs(GKeyFile *config) /* general */ g_key_file_set_boolean(config, PACKAGE, "pref_main_load_session", prefs.load_session); - g_key_file_set_boolean(config, PACKAGE, "pref_main_project_session", project_prefs.project_session); g_key_file_set_boolean(config, PACKAGE, "pref_main_project_file_in_basedir", project_prefs.project_file_in_basedir); g_key_file_set_boolean(config, PACKAGE, "pref_main_save_winpos", prefs.save_winpos); g_key_file_set_boolean(config, PACKAGE, "pref_main_save_wingeom", prefs.save_wingeom); @@ -815,7 +814,6 @@ static void load_dialog_prefs(GKeyFile *config) prefs.confirm_exit = utils_get_setting_boolean(config, PACKAGE, "pref_main_confirm_exit", FALSE); prefs.suppress_status_messages = utils_get_setting_boolean(config, PACKAGE, "pref_main_suppress_status_messages", FALSE); prefs.load_session = utils_get_setting_boolean(config, PACKAGE, "pref_main_load_session", TRUE); - project_prefs.project_session = utils_get_setting_boolean(config, PACKAGE, "pref_main_project_session", TRUE); project_prefs.project_file_in_basedir = utils_get_setting_boolean(config, PACKAGE, "pref_main_project_file_in_basedir", FALSE); prefs.save_winpos = utils_get_setting_boolean(config, PACKAGE, "pref_main_save_winpos", TRUE); prefs.save_wingeom = utils_get_setting_boolean(config, PACKAGE, "pref_main_save_wingeom", prefs.save_winpos); Modified: src/libmain.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -957,7 +957,7 @@ static void load_startup_files(gint argc, gchar **argv) main_load_project_from_command_line(filename, FALSE); argc--, argv++; /* force session load if using project-based session files */ - load_session = project_prefs.project_session; + load_session = TRUE; g_free(filename); } Modified: src/prefs.c 6 lines changed, 0 insertions(+), 6 deletions(-) =================================================================== @@ -409,9 +409,6 @@ static void prefs_init_dialog(void) widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.load_session); - widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_session); - widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_file_in_basedir); @@ -892,9 +889,6 @@ on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session"); prefs.load_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session"); - project_prefs.project_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir"); project_prefs.project_file_in_basedir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); Modified: src/project.c 56 lines changed, 22 insertions(+), 34 deletions(-) =================================================================== @@ -50,7 +50,7 @@ #include <errno.h> -ProjectPrefs project_prefs = { NULL, FALSE, FALSE }; +ProjectPrefs project_prefs = { NULL, FALSE }; static GeanyProjectPrivate priv; @@ -112,7 +112,7 @@ static gboolean have_session_docs(void) static gboolean handle_current_session(void) { - if (!app->project && project_prefs.project_session) + if (!app->project) { /* save session in case the dialog is cancelled */ configuration_save_default_session(); @@ -275,12 +275,9 @@ gboolean project_load_file_with_session(const gchar *locale_file_name) { if (project_load_file(locale_file_name)) { - if (project_prefs.project_session) - { - configuration_open_files(); - document_new_file_if_non_open(); - ui_focus_current_document(); - } + configuration_open_files(); + document_new_file_if_non_open(); + ui_focus_current_document(); return TRUE; } return FALSE; @@ -413,12 +410,10 @@ gboolean project_close(gboolean open_default) if (!write_config()) g_warning("Project file \"%s\" could not be written", app->project->file_name); - if (project_prefs.project_session) - { - /* close all existing tabs first */ - if (!document_close_all()) - return FALSE; - } + /* close all existing tabs first */ + if (!document_close_all()) + return FALSE; + ui_set_statusbar(TRUE, _("Project \"%s\" closed."), app->project->name); destroy_project(open_default); return TRUE; @@ -461,16 +456,13 @@ static void destroy_project(gboolean open_default) apply_editor_prefs(); /* ensure that global settings are restored */ - if (project_prefs.project_session) + /* after closing all tabs let's open the tabs found in the default config */ + if (open_default && cl_options.load_session) { - /* after closing all tabs let's open the tabs found in the default config */ - if (open_default && cl_options.load_session) - { - configuration_reload_default_session(); - configuration_open_files(); - document_new_file_if_non_open(); - ui_focus_current_document(); - } + configuration_reload_default_session(); + configuration_open_files(); + document_new_file_if_non_open(); + ui_focus_current_document(); } g_signal_emit_by_name(geany_object, "project-close"); @@ -1072,15 +1064,12 @@ static gboolean load_config(const gchar *filename) apply_editor_prefs(); build_load_menu(config, GEANY_BCS_PROJ, (gpointer)p); - if (project_prefs.project_session) - { - /* save current (non-project) session (it could have been changed since program startup) */ - configuration_save_default_session(); - /* now close all open files */ - document_close_all(); - /* read session files so they can be opened with configuration_open_files() */ - configuration_load_session_files(config, FALSE); - } + /* save current (non-project) session (it could have been changed since program startup) */ + configuration_save_default_session(); + /* now close all open files */ + document_close_all(); + /* read session files so they can be opened with configuration_open_files() */ + configuration_load_session_files(config, FALSE); g_signal_emit_by_name(geany_object, "project-open", config); g_key_file_free(config); @@ -1135,8 +1124,7 @@ static gboolean write_config(void) g_key_file_set_integer(config, "long line marker", "long_line_column", p->priv->long_line_column); /* store the session files into the project too */ - if (project_prefs.project_session) - configuration_save_session_files(config); + configuration_save_session_files(config); build_save_menu(config, (gpointer)p, GEANY_BCS_PROJ); g_signal_emit_by_name(geany_object, "project-save", config); /* write the file */ Modified: src/project.h 1 lines changed, 0 insertions(+), 1 deletions(-) =================================================================== @@ -55,7 +55,6 @@ void project_write_config(void); typedef struct ProjectPrefs { gchar *session_file; - gboolean project_session; gboolean project_file_in_basedir; } ProjectPrefs; -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] a7647c: Change main_status.opening_session_files to a counter
by Thomas Martitz
05 Mar '22
05 Mar '22
Branch: refs/heads/master Author: Thomas Martitz <thomas.martitz(a)mailbox.org> Committer: Thomas Martitz <thomas.martitz(a)mailbox.org> Date: Thu, 17 Feb 2022 21:40:36 UTC Commit: a7647cd9a92c95a2b4b2bb611660ae53f0051099
https://github.com/geany/geany/commit/a7647cd9a92c95a2b4b2bb611660ae53f0051…
Log Message: ----------- Change main_status.opening_session_files to a counter This flag is actually set and cleared recursively: - libmain.c sets it before calling load_startup_files() - inside load_startup_files(), configuration_open_files() sets and clears the flag - when libmain.c clears the flag, it's already unset A counter allows such recursive usage to work as expected. Modified Paths: -------------- src/keyfile.c src/libmain.c src/main.h Modified: src/keyfile.c 8 lines changed, 5 insertions(+), 3 deletions(-) =================================================================== @@ -1317,7 +1317,7 @@ void configuration_open_files(void) gboolean failure = FALSE; /* necessary to set it to TRUE for project session support */ - main_status.opening_session_files = TRUE; + main_status.opening_session_files++; i = file_prefs.tab_order_ltr ? 0 : (session_files->len - 1); while (TRUE) @@ -1350,7 +1350,10 @@ void configuration_open_files(void) session_files = NULL; if (failure) + { ui_set_statusbar(TRUE, _("Failed to load one or more session files.")); + main_status.opening_session_files--; + } else { /* explicitly trigger a notebook page switch after unsetting main_status.opening_session_files @@ -1363,10 +1366,9 @@ void configuration_open_files(void) if (target_page == cur_page && n_pages > 0) gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), (cur_page + 1) % n_pages); - main_status.opening_session_files = FALSE; + main_status.opening_session_files--; gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), target_page); } - main_status.opening_session_files = FALSE; } Modified: src/libmain.c 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -263,7 +263,7 @@ static void main_init(void) ignore_callback = FALSE; ui_prefs.recent_queue = g_queue_new(); ui_prefs.recent_projects_queue = g_queue_new(); - main_status.opening_session_files = FALSE; + main_status.opening_session_files = 0; main_widgets.window = create_window1(); g_signal_connect(main_widgets.window, "notify::is-active", G_CALLBACK(on_window_active_changed), NULL); @@ -1194,9 +1194,9 @@ gint main_lib(gint argc, gchar **argv) tools_create_insert_custom_command_menu_items(); /* load any command line files or session files */ - main_status.opening_session_files = TRUE; + main_status.opening_session_files++; load_startup_files(argc, argv); - main_status.opening_session_files = FALSE; + main_status.opening_session_files--; /* open a new file if no other file was opened */ document_new_file_if_non_open(); Modified: src/main.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -53,7 +53,7 @@ extern CommandLineOptions cl_options; typedef struct GeanyStatus { - gboolean opening_session_files; /* state at startup while opening session files */ + gint opening_session_files; /* >0 indicates batch-opening of session files */ gboolean closing_all; /* the state while closing all tabs * (used to prevent notebook switch page signals) */ gboolean quitting; /* state when Geany is quitting completely */ -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 27982f: Disconnect default session and project session files
by Thomas Martitz
05 Mar '22
05 Mar '22
Branch: refs/heads/master Author: Thomas Martitz <thomas.martitz(a)mailbox.org> Committer: Thomas Martitz <thomas.martitz(a)mailbox.org> Date: Thu, 17 Feb 2022 21:43:54 UTC Commit: 27982f333d731607e6efcf83d03a6129f45ef05e
https://github.com/geany/geany/commit/27982f333d731607e6efcf83d03a6129f45ef…
Log Message: ----------- Disconnect default session and project session files Currently, when loading "projects" (i.e. named sessions), the file list overwrites the default session. Therefore, when loading a project, the previously opened files are lost. With this the default session is maintained separately. Any time a project is opened it is written to session.conf and can be restored later on. Modified Paths: -------------- src/keyfile.c src/keyfile.h src/libmain.c src/project.c src/projectprivate.h Modified: src/keyfile.c 110 lines changed, 57 insertions(+), 53 deletions(-) =================================================================== @@ -106,11 +106,10 @@ static gchar *scribble_text = NULL; static gint scribble_pos = -1; -static GPtrArray *session_files = NULL; +static GPtrArray *default_session_files = NULL; static gint session_notebook_page; static gint hpan_position; static gint vpan_position; -static guint document_list_update_idle_func_id = 0; static const gchar atomic_file_saving_key[] = "use_atomic_file_saving"; typedef enum @@ -665,7 +664,7 @@ void write_config_file(gchar const *filename, ConfigPayload payload) save_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects"); project_save_prefs(config); /* save project filename, etc. */ save_ui_session(config); - if (cl_options.load_session) + if (cl_options.load_session && app->project == NULL) configuration_save_session_files(config); #ifdef HAVE_VTE else if (vte_info.have_vte) @@ -717,34 +716,20 @@ static void load_recent_files(GKeyFile *config, GQueue *queue, const gchar *key) /* - * Load session list from the given keyfile, and store it in the global - * session_files variable for later file loading + * Load session list from the given keyfile and return an array containg the file names * */ -void configuration_load_session_files(GKeyFile *config, gboolean read_recent_files) +GPtrArray *configuration_load_session_files(GKeyFile *config) { guint i; gboolean have_session_files; gchar entry[16]; gchar **tmp_array; GError *error = NULL; + GPtrArray *files; session_notebook_page = utils_get_setting_integer(config, "files", "current_page", -1); - if (read_recent_files) - { - load_recent_files(config, ui_prefs.recent_queue, "recent_files"); - load_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects"); - } - - /* the project may load another list than the main setting */ - if (session_files != NULL) - { - foreach_ptr_array(tmp_array, i, session_files) - g_strfreev(tmp_array); - g_ptr_array_free(session_files, TRUE); - } - - session_files = g_ptr_array_new(); + files = g_ptr_array_new(); have_session_files = TRUE; i = 0; while (have_session_files) @@ -757,7 +742,7 @@ void configuration_load_session_files(GKeyFile *config, gboolean read_recent_fil error = NULL; have_session_files = FALSE; } - g_ptr_array_add(session_files, tmp_array); + g_ptr_array_add(files, tmp_array); i++; } @@ -770,6 +755,8 @@ void configuration_load_session_files(GKeyFile *config, gboolean read_recent_fil g_free(tmp_string); } #endif + + return files; } @@ -1170,15 +1157,17 @@ void configuration_clear_default_session(void) /* * Only reload the session part of the default configuration */ -void configuration_reload_default_session(void) +void configuration_load_default_session(void) { gchar *configfile = g_build_filename(app->configdir, SESSION_FILE, NULL); GKeyFile *config = g_key_file_new(); + g_return_if_fail(default_session_files == NULL); + g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); g_free(configfile); - configuration_load_session_files(config, FALSE); + default_session_files = configuration_load_session_files(config); g_key_file_free(config); } @@ -1217,8 +1206,8 @@ gboolean read_config_file(gchar const *filename, ConfigPayload payload) case SESSION: project_load_prefs(config); load_ui_session(config); - /* read stash prefs */ - configuration_load_session_files(config, TRUE); + load_recent_files(config, ui_prefs.recent_queue, "recent_files"); + load_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects"); break; } @@ -1307,11 +1296,33 @@ static gboolean open_session_file(gchar **tmp, guint len) return ret; } +/* trigger a notebook page switch after unsetting main_status.opening_session_files + * for callbacks to run (and update window title, encoding settings, and so on) + */ +static gboolean switch_to_session_page(gpointer data) +{ + gint n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); + gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook)); + gint target_page = session_notebook_page >= 0 ? session_notebook_page : cur_page; + + if (n_pages > 0) + { + if (target_page != cur_page) + gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), target_page); + else + g_signal_emit_by_name(GTK_NOTEBOOK(main_widgets.notebook), "switch-page", + gtk_notebook_get_nth_page(GTK_NOTEBOOK(main_widgets.notebook), target_page), + target_page); + } + session_notebook_page = -1; + + return G_SOURCE_REMOVE; +} /* Open session files * Note: notebook page switch handler and adding to recent files list is always disabled * for all files opened within this function */ -void configuration_open_files(void) +void configuration_open_files(GPtrArray *session_files) { gint i; gboolean failure = FALSE; @@ -1347,28 +1358,25 @@ void configuration_open_files(void) } g_ptr_array_free(session_files, TRUE); - session_files = NULL; if (failure) - { ui_set_statusbar(TRUE, _("Failed to load one or more session files.")); - main_status.opening_session_files--; - } else - { - /* explicitly trigger a notebook page switch after unsetting main_status.opening_session_files - * for callbacks to run (and update window title, encoding settings, and so on) */ - gint n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); - gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook)); - gint target_page = session_notebook_page >= 0 ? session_notebook_page : cur_page; - - /* if target page is current page, switch to another page first to really trigger an event */ - if (target_page == cur_page && n_pages > 0) - gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), (cur_page + 1) % n_pages); - - main_status.opening_session_files--; - gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), target_page); - } + g_idle_add(switch_to_session_page, NULL); + + main_status.opening_session_files--; +} + + +/* Open session files + * Note: notebook page switch handler and adding to recent files list is always disabled + * for all files opened within this function */ +void configuration_open_default_session(void) +{ + g_return_if_fail(default_session_files != NULL); + + configuration_open_files(default_session_files); + default_session_files = NULL; } @@ -1410,12 +1418,10 @@ void configuration_apply_settings(void) static gboolean save_configuration_cb(gpointer data) { - configuration_save(); if (app->project != NULL) - { project_write_config(); - } - document_list_update_idle_func_id = 0; + else + configuration_save_default_session(); return G_SOURCE_REMOVE; } @@ -1431,10 +1437,8 @@ static void document_list_changed_cb(GObject *obj, GeanyDocument *doc, gpointer !main_status.opening_session_files && !main_status.quitting) { - if (document_list_update_idle_func_id == 0) - { - document_list_update_idle_func_id = g_idle_add(save_configuration_cb, NULL); - } + g_idle_remove_by_data(save_configuration_cb); + g_idle_add(save_configuration_cb, save_configuration_cb); } } Modified: src/keyfile.h 8 lines changed, 5 insertions(+), 3 deletions(-) =================================================================== @@ -46,15 +46,17 @@ void configuration_save(void); gboolean configuration_load(void); -void configuration_open_files(void); +void configuration_open_files(GPtrArray *session_files); -void configuration_reload_default_session(void); +void configuration_load_default_session(void); + +void configuration_open_default_session(void); void configuration_save_default_session(void); void configuration_clear_default_session(void); -void configuration_load_session_files(GKeyFile *config, gboolean read_recent_files); +GPtrArray *configuration_load_session_files(GKeyFile *config); void configuration_save_session_files(GKeyFile *config); Modified: src/libmain.c 13 lines changed, 12 insertions(+), 1 deletions(-) =================================================================== @@ -46,6 +46,7 @@ #include "navqueue.h" #include "notebook.h" #include "plugins.h" +#include "projectprivate.h" #include "prefs.h" #include "printing.h" #include "sidebar.h" @@ -970,13 +971,23 @@ static void load_startup_files(gint argc, gchar **argv) { if (app->project == NULL) load_session_project_file(); + if (app->project == NULL) + configuration_load_default_session(); load_session = TRUE; } if (load_session) { /* load session files into tabs, as they are found in the session_files variable */ - configuration_open_files(); + if (app->project != NULL) + { + configuration_open_files(app->project->priv->session_files); + app->project->priv->session_files = NULL; + } + else + { + configuration_open_default_session(); + } if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) == 0) { Modified: src/project.c 22 lines changed, 13 insertions(+), 9 deletions(-) =================================================================== @@ -265,8 +265,8 @@ static void run_new_dialog(PropertyDialogElements *e) else { // reload any documents that were closed - configuration_reload_default_session(); - configuration_open_files(); + configuration_load_default_session(); + configuration_open_default_session(); } } @@ -275,7 +275,8 @@ gboolean project_load_file_with_session(const gchar *locale_file_name) { if (project_load_file(locale_file_name)) { - configuration_open_files(); + configuration_open_files(app->project->priv->session_files); + app->project->priv->session_files = NULL; document_new_file_if_non_open(); ui_focus_current_document(); return TRUE; @@ -459,8 +460,8 @@ static void destroy_project(gboolean open_default) /* after closing all tabs let's open the tabs found in the default config */ if (open_default && cl_options.load_session) { - configuration_reload_default_session(); - configuration_open_files(); + configuration_load_default_session(); + configuration_open_default_session(); document_new_file_if_non_open(); ui_focus_current_document(); } @@ -1065,11 +1066,14 @@ static gboolean load_config(const gchar *filename) build_load_menu(config, GEANY_BCS_PROJ, (gpointer)p); /* save current (non-project) session (it could have been changed since program startup) */ - configuration_save_default_session(); - /* now close all open files */ - document_close_all(); + if (!main_status.opening_session_files) + { + configuration_save_default_session(); + /* now close all open files */ + document_close_all(); + } /* read session files so they can be opened with configuration_open_files() */ - configuration_load_session_files(config, FALSE); + p->priv->session_files = configuration_load_session_files(config); g_signal_emit_by_name(geany_object, "project-open", config); g_key_file_free(config); Modified: src/projectprivate.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -45,6 +45,7 @@ typedef struct GeanyProjectPrivate gint long_line_column; /* Long line marker position. */ GPtrArray *build_filetypes_list; /* Project has custom filetype builds for these. */ + GPtrArray *session_files; } GeanyProjectPrivate; -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
← Newer
1
2
3
4
Older →
Jump to page:
1
2
3
4
Results per page:
10
25
50
100
200