From b0c009363d0638c17d8c55cedaf6ba2a2943d5ea Mon Sep 17 00:00:00 2001 From: Scott Olsen Date: Fri, 27 Jan 2023 16:30:36 -0500 Subject: [PATCH 1/6] fix: projectGetCFlags Fixes `(Project.get-config "cflags")` so that it actually returns the project's C flag field. Previously it was returning the project's preprocessor calls. --- src/ProjectConfig.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProjectConfig.hs b/src/ProjectConfig.hs index 473c4c811..686229111 100644 --- a/src/ProjectConfig.hs +++ b/src/ProjectConfig.hs @@ -46,7 +46,7 @@ projectGetPreproc proj = -- | Get the project's C compiler flags. projectGetCFlags :: ProjectGetter projectGetCFlags proj = - let fs = projectPreproc proj + let fs = projectCFlags proj in wrapList (map wrapString fs) -- | Set the project's C compiler flags From 74d0321c63acc4dfc9a98a6515cb2f1f51b0b035 Mon Sep 17 00:00:00 2001 From: Scott Olsen Date: Fri, 27 Jan 2023 16:34:35 -0500 Subject: [PATCH 2/6] refactor!: change project flag setting behavior This commit alters the project configuration compiler flag setting behavior to allow users to override default project flags. Flag setting commands (cflag, libflag, pkgconfigflag) now take lists of strings as arguments. Previously, they were append-only and accepted string arguments. Now, to override flags, users can call: ``` (Project.get-config "cflag") => (...a bunch of default platform flags; "-wall" ...) (Project.config "cflag" '("-my" "-new" "-flags")) (Project.get-config "cflag") => ("-my" "-new" "-flags") ``` In order to append flags, users now need to `cons` to a `config-get`: ``` (Project.config "cflag" (cons "-new" (Project.get-config "cflag"))) ``` BREAKING CHANGE: Code that relies on the previous behavior will break, as calling these functions with non-list arguments is now an error. I considered a softer path whereby we'd overload the current behavior to avoid breaking existing users; however, the result would be confusing. Passing a list would result in overriding the project field while passing a single string would result in an append. A user might conceivably wonder why passing a list doesn't result in a multi-append. Ultimately I felt making a breaking change would be less confusing than this compatibility preserving behavior down the line. --- src/Obj.hs | 4 +++ src/ProjectConfig.hs | 60 +++++++++++++++----------------------------- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/src/Obj.hs b/src/Obj.hs index 1372fbfa6..9eba9e0de 100644 --- a/src/Obj.hs +++ b/src/Obj.hs @@ -218,6 +218,10 @@ isBool :: XObj -> Bool isBool (XObj (Bol _) _ _) = True isBool _ = False +isStr :: XObj -> Bool +isStr (XObj (Str _) _ _) = True +isStr _ = False + isExternalFunction :: XObj -> Bool isExternalFunction (XObj (Lst (XObj (External _) _ _ : _)) _ _) = True isExternalFunction _ = False diff --git a/src/ProjectConfig.hs b/src/ProjectConfig.hs index 686229111..ebeff9efd 100644 --- a/src/ProjectConfig.hs +++ b/src/ProjectConfig.hs @@ -1,9 +1,17 @@ -- | Defines a frontend for manipulating Project level data. module ProjectConfig (projectKeyMap) where +import Data.Either (rights) import Info import qualified Map import Obj + ( XObj(XObj), + Obj(Str, Lst, Bol), + unwrapStringXObj, + wrapString, + wrapList, + wrapArray, + isStr ) import Project import Util @@ -50,20 +58,11 @@ projectGetCFlags proj = in wrapList (map wrapString fs) -- | Set the project's C compiler flags --- --- NOTE: This retains existing behavior in which one can only add one flag at --- a time and the flags are append only. A slightly more functional interface --- would take a list of flags as arguments; e.g. to add *one* flag: --- --- (Project.config "cflags" (cons "-my-flag" (Project.get-config "cflags"))) --- --- or to wipe the flags whole-cloth (e.g. for a different target) --- --- (Project.config "cflags" ("-my" "-new" "-flags")) --- --- likewise for flag removal etc. projectSetCFlags :: ProjectSetter -projectSetCFlags proj (XObj (Str f) _ _) = Right (proj {projectCFlags = addIfNotPresent f (projectCFlags proj)}) +projectSetCFlags proj (XObj (Lst flags) _ _) = + if not $ all isStr flags + then Left "can't use a non-string as a C compiler flag" + else Right proj {projectCFlags = rights $ map unwrapStringXObj flags} projectSetCFlags _ _ = Left "can't use a non-string as a C compiler flag" -- | Get the project's C compiler library flags. @@ -73,20 +72,11 @@ projectGetLibFlags proj = in wrapList (map wrapString ls) -- | Set the project's C compiler library flags --- --- NOTE: This retains existing behavior in which one can only add one flag at --- a time and the flags are append only. A slightly more functional interface --- would take a list of flags as arguments; e.g. to add *one* flag: --- --- (Project.config "libflags" (cons "-lmylib" (Project.get-config "libflags"))) --- --- or to wipe the flags whole-cloth (e.g. for a different target) --- --- (Project.config "libflags" ("-lmy" "-lnew" "-llibflags")) --- --- likewise for flag removal etc. projectSetLibFlags :: ProjectSetter -projectSetLibFlags proj (XObj (Str flag) _ _) = Right (proj {projectLibFlags = addIfNotPresent flag (projectLibFlags proj)}) +projectSetLibFlags proj (XObj (Lst flags) _ _) = + if not $ all isStr flags + then Left "can't use a non-string as a C compiler library flag" + else Right proj {projectLibFlags = rights $ map unwrapStringXObj flags} projectSetLibFlags _ _ = Left "can't use non-string as library flag" -- | Get the pkg-config flags for the project. @@ -96,21 +86,11 @@ projectGetPkgConfigFlags proj = in wrapArray (map wrapString fs) -- | Set the project's pkg-config flags --- --- NOTE: This retains existing behavior in which one can only add one flag at --- a time and the flags are append only. A slightly more functional interface --- would take a list of flags as arguments; e.g. to add *one* flag: --- --- (Project.config "pkgconfigflags" (cons "-lmylib" (Project.get-config --- "pkgconfigflags"))) --- --- or to wipe the flags whole-cloth (e.g. for a different target) --- --- (Project.config "pkgconfigflags" ("-lmy" "-lnew" "-llibflags")) --- --- likewise for flag removal etc. projectSetPkgConfigFlags :: ProjectSetter -projectSetPkgConfigFlags proj (XObj (Str flag) _ _) = Right (proj {projectPkgConfigFlags = addIfNotPresent flag (projectPkgConfigFlags proj)}) +projectSetPkgConfigFlags proj (XObj (Lst flags) _ _) = + if not $ all isStr flags + then Left "can't use a non-string as a C compiler library flag" + else Right proj {projectPkgConfigFlags = rights $ map unwrapStringXObj flags} projectSetPkgConfigFlags _ _ = Left "can't use non-string as pkg-config flag" projectGetEchoC :: ProjectGetter From 57f111708d2a8a9f7e4c104c0749c1f152567acf Mon Sep 17 00:00:00 2001 From: Scott Olsen Date: Fri, 27 Jan 2023 16:54:40 -0500 Subject: [PATCH 3/6] feat: add flag append macros Provides convenience macros for appending flags to project flag fields cflag, libflag, and pkgconfigflag. --- core/Project.carp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/Project.carp b/core/Project.carp index 8c465d14a..978089b39 100644 --- a/core/Project.carp +++ b/core/Project.carp @@ -13,3 +13,13 @@ Example usage: `(save-docs Int Float String)`") (defmacro save-docs [:rest modules] (eval (list 'save-docs-ex (list quote (collect-into modules array)) []))) + +(defmodule Project + (hidden append-flag) + (defndynamic append-flag [flag-set flag] + (Project.config flag-set (cons flag (Project.get-config flag-set)))) + + (defmacro append-cflag [flag] (Project.append-flag "cflag" flag)) + (defmacro append-libflag [flag] (Project.append-flag "libflag" flag)) + (defmacro append-pkgflag [flag] (Project.append-flag "pkgconfigflag" flag)) +) From e5c9be751875e89bf60f72f978e94f0b7b549bf9 Mon Sep 17 00:00:00 2001 From: scottolsen Date: Tue, 31 Jan 2023 09:45:25 -0500 Subject: [PATCH 4/6] fix: update flag-setting calls to reflect behavior changes Updates some project configuration calls in the Core library to follow the new configuration behavior (pass complete flag sets and not individual strings). --- core/Dynamic.carp | 4 ++-- core/SDL_mixer.carp | 4 +++- core/SDL_ttf.carp | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/Dynamic.carp b/core/Dynamic.carp index e62b214ab..fda6d51a9 100644 --- a/core/Dynamic.carp +++ b/core/Dynamic.carp @@ -95,10 +95,10 @@ integers [`imod`](#imod).") ;; The following functions are not put into a module for now: (defndynamic add-cflag [flag] - (eval (list 'Project.config "cflag" flag))) + (eval (list 'Project.config "cflag" (cons flag (Project.get-config "cflag"))))) (defndynamic add-lib [lib] - (eval (list 'Project.config "libflag" lib))) + (eval (list 'Project.config "libflag" (cons lib (Project.get-config "libflag"))))) (defndynamic pkg-config [pkg flags] (Dynamic.String.concat (Dynamic.append diff --git a/core/SDL_mixer.carp b/core/SDL_mixer.carp index cf139c9f8..d519e3ef6 100644 --- a/core/SDL_mixer.carp +++ b/core/SDL_mixer.carp @@ -1,6 +1,8 @@ (system-include "SDL2/SDL_mixer.h") (add-pkg "SDL2_mixer") -(Project.config "cflag" "-Wno-incompatible-pointer-types-discards-qualifiers") +(Project.config "cflag" + (cons "-Wno-incompatible-pointer-types-discards-qualifiers" + (Project.get-config "cflag"))) (register-type Mix_Chunk) (register-type Mix_Music) diff --git a/core/SDL_ttf.carp b/core/SDL_ttf.carp index dc46b2388..0ef1439af 100644 --- a/core/SDL_ttf.carp +++ b/core/SDL_ttf.carp @@ -1,6 +1,8 @@ (system-include "SDL2/SDL_ttf.h") (add-pkg "SDL2_ttf") -(Project.config "cflag" "-Wno-incompatible-pointer-types-discards-qualifiers") +(Project.config "cflag" + (cons "-Wno-incompatible-pointer-types-discards-qualifiers" + (Project.get-config "cflag"))) (register-type TTF_Font) From 09565f002f0321f2b36f0f375c24a12c35f560d6 Mon Sep 17 00:00:00 2001 From: scottolsen Date: Tue, 31 Jan 2023 11:13:42 -0500 Subject: [PATCH 5/6] fix: update add-*flag helpers To account for the new flag setting configuration behavior. --- core/Dynamic.carp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/Dynamic.carp b/core/Dynamic.carp index fda6d51a9..ff72b7efd 100644 --- a/core/Dynamic.carp +++ b/core/Dynamic.carp @@ -95,10 +95,10 @@ integers [`imod`](#imod).") ;; The following functions are not put into a module for now: (defndynamic add-cflag [flag] - (eval (list 'Project.config "cflag" (cons flag (Project.get-config "cflag"))))) + (Project.config "cflag" (cons flag (Project.get-config "cflag")))) (defndynamic add-lib [lib] - (eval (list 'Project.config "libflag" (cons lib (Project.get-config "libflag"))))) + (Project.config "libflag" (cons lib (Project.get-config "libflag")))) (defndynamic pkg-config [pkg flags] (Dynamic.String.concat (Dynamic.append From a28385a06c21e1491904916ef9185056a84fdf02 Mon Sep 17 00:00:00 2001 From: scottolsen Date: Tue, 31 Jan 2023 11:14:11 -0500 Subject: [PATCH 6/6] fix: temporary kludge for clang Adds a preload eval to set the -Wnounknown-warning-option flag in clang -- this way, when different versions don't support our default flag set, they can still run tests. Otherwise passing an unknown flag to clang results in a compilation error. --- scripts/carp.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/carp.sh b/scripts/carp.sh index 6e90cf4a9..dcedc1f1c 100755 --- a/scripts/carp.sh +++ b/scripts/carp.sh @@ -10,4 +10,6 @@ then CARP="$CARP $BUILD_OPTS --" fi export CARP_DIR=`pwd` -$CARP $CARP_OPTS "$@" +# TODO: Temporary band-aid to make different versions of clang run tests OK when supported flag sets differ +EVAL='(Project.config "cflag" (cons "-Wno-unknown-warning-option" (Project.get-config "cflag")))' +$CARP --eval-preload "\'$EVAL\'" $CARP_OPTS "$@"