Darwin, updating to 23.11

Hi folks,

I’m trying to update my nix-darwin configuration to 23.11. I’ve been sitting pretty at 22.11 for quite a while now but realize that it’s a bit too old and many of my dependencies are in limbo.

I am using an M2 Macbook Pro - so this is aarch64-darwin. Currently on Ventura 13.6.4 - I will update to Sonoma to see if that changes anything here.

My flake includes:

inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-23.11-darwin";
    darwin = {
      url = "github:lnl7/nix-darwin/master";
      inputs.nixpkgs.follows = "nixpkgs";
    };

I’m failing on building a component - jam-2.6.1. This is a dependency for some other components.

@nix { "action": "setPhase", "phase": "unpackPhase" }
Running phase: unpackPhase
unpacking source archive /nix/store/22gb70vrp3s027d10h28qwp20k0lmf0l-jam-2.6.1.tar
source root is jam-2.6.1
setting SOURCE_DATE_EPOCH to timestamp 1561072376 of file jam-2.6.1/yyacc
@nix { "action": "setPhase", "phase": "patchPhase" }
Running phase: patchPhase
@nix { "action": "setPhase", "phase": "updateAutotoolsGnuConfigScriptsPhase" }
Running phase: updateAutotoolsGnuConfigScriptsPhase
@nix { "action": "setPhase", "phase": "configurePhase" }
Running phase: configurePhase
no configure script, doing nothing
@nix { "action": "setPhase", "phase": "buildPhase" }
Running phase: buildPhase
cc -o ./jam0  builtins.c command.c compile.c execas400.c execunix.c execvms.c expand.c filent.c fileos2.c fileunix.c filevms.c glob.c hash.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c newstr.c option.c parse.c pathunix.c pathvms.c regexp.c rules.c scan.c search.c timestamp.c variable.c 
e[1mexpand.c:211:13: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
                if( colon = strchr( varname, MAGIC_COLON ) )
e[0;1;32m                    ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mexpand.c:211:13: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
                if( colon = strchr( varname, MAGIC_COLON ) )
e[0;1;32m                          ^
e[0me[0;32m                    (                                     )
e[0me[1mexpand.c:211:13: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
                if( colon = strchr( varname, MAGIC_COLON ) )
e[0;1;32m                          ^
e[0me[0;32m                          ==
e[0me[1mexpand.c:221:15: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
                if( bracket = strchr( varname, MAGIC_LEFT ) )
e[0;1;32m                    ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mexpand.c:221:15: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
                if( bracket = strchr( varname, MAGIC_LEFT ) )
e[0;1;32m                            ^
e[0me[0;32m                    (                                      )
e[0me[1mexpand.c:221:15: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
                if( bracket = strchr( varname, MAGIC_LEFT ) )
e[0;1;32m                            ^
e[0me[0;32m                            ==
e[0me[1mexpand.c:225:16: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
                    if( dash = strchr( bracket + 1, '-' ) )
e[0;1;32m                        ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mexpand.c:225:16: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
                    if( dash = strchr( bracket + 1, '-' ) )
e[0;1;32m                             ^
e[0me[0;32m                        (                                )
e[0me[1mexpand.c:225:16: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
                    if( dash = strchr( bracket + 1, '-' ) )
e[0;1;32m                             ^
e[0me[0;32m                             ==
e[0me[1mexpand.c:451:17: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
            else if( p = strchr( mods, MAGIC_COLON ) )
e[0;1;32m                     ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mexpand.c:451:17: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
            else if( p = strchr( mods, MAGIC_COLON ) )
e[0;1;32m                       ^
e[0me[0;32m                     (                              )
e[0me[1mexpand.c:451:17: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
            else if( p = strchr( mods, MAGIC_COLON ) )
e[0;1;32m                       ^
e[0me[0;32m                       ==
e[0m4 warnings generated.
e[1mfileunix.c:143:16: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        while( dirent = readdir( d ) )
e[0;1;32m               ~~~~~~~^~~~~~~~~~~~~~
e[0me[1mfileunix.c:143:16: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        while( dirent = readdir( d ) )
e[0;1;32m                      ^
e[0me[0;32m               (                    )
e[0me[1mfileunix.c:143:16: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        while( dirent = readdir( d ) )
e[0;1;32m                      ^
e[0me[0;32m                      ==
e[0m1 warning generated.
e[1mhash.c:242:12: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
                if( here = ( *tab++ != (ITEM *)0 ) )
e[0;1;32m                    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mhash.c:242:12: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
                if( here = ( *tab++ != (ITEM *)0 ) )
e[0;1;32m                         ^
e[0me[0;32m                    (                             )
e[0me[1mhash.c:242:12: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
                if( here = ( *tab++ != (ITEM *)0 ) )
e[0;1;32m                         ^
e[0me[0;32m                         ==
e[0m1 warning generated.
e[1mjam.c:169:1: e[0me[0;1;31merror: e[0me[1mtype specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]e[0m
main( int argc, char **argv, char **arg_environ )
e[0;1;32m^
e[0me[0;32mint
e[0me[1mjam.c:236:16: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        for( n = 0; s = getoptval( optv, 'd', n ); n++ )
e[0;1;32m                    ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mjam.c:236:16: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        for( n = 0; s = getoptval( optv, 'd', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                    (                            )
e[0me[1mjam.c:236:16: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        for( n = 0; s = getoptval( optv, 'd', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                      ==
e[0me[1mjam.c:320:16: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        for( n = 0; s = getoptval( optv, 's', n ); n++ )
e[0;1;32m                    ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mjam.c:320:16: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        for( n = 0; s = getoptval( optv, 's', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                    (                            )
e[0me[1mjam.c:320:16: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        for( n = 0; s = getoptval( optv, 's', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                      ==
e[0me[1mjam.c:334:16: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        for( n = 0; s = getoptval( optv, 'f', n ); n++ )
e[0;1;32m                    ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mjam.c:334:16: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        for( n = 0; s = getoptval( optv, 'f', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                    (                            )
e[0me[1mjam.c:334:16: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        for( n = 0; s = getoptval( optv, 'f', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                      ==
e[0me[1mjam.c:344:16: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        for( n = 0; s = getoptval( optv, 't', n ); n++ )
e[0;1;32m                    ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mjam.c:344:16: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        for( n = 0; s = getoptval( optv, 't', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                    (                            )
e[0me[1mjam.c:344:16: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        for( n = 0; s = getoptval( optv, 't', n ); n++ )
e[0;1;32m                      ^
e[0me[0;32m                      ==
e[0me[1mjam.c:349:8: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        if( s = getoptval( optv, 'o', 0 ) )
e[0;1;32m            ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mjam.c:349:8: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        if( s = getoptval( optv, 'o', 0 ) )
e[0;1;32m              ^
e[0me[0;32m            (                            )
e[0me[1mjam.c:349:8: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        if( s = getoptval( optv, 'o', 0 ) )
e[0;1;32m              ^
e[0me[0;32m              ==
e[0m5 warnings and 1 error generated.
e[1mlists.c:193:15: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
            while( p = (char *)memchr( op, '"',  ep - op ) )
e[0;1;32m                   ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mlists.c:193:15: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
            while( p = (char *)memchr( op, '"',  ep - op ) )
e[0;1;32m                     ^
e[0me[0;32m                   (                                      )
e[0me[1mlists.c:193:15: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
            while( p = (char *)memchr( op, '"',  ep - op ) )
e[0;1;32m                     ^
e[0me[0;32m                     ==
e[0m1 warning generated.
e[1mmake.c:191:34: e[0me[0;1;35mwarning: e[0me[1madding 'int' to a string does not append to the string [-Wstring-plus-int]e[0m
            printf( "make\t--\t%s%s\n", spaces( depth ), t->name );
e[0;1;32m                                        ^~~~~~~~~~~~~~~
e[0me[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                     ~~~~~~~~~~~~~~~~~~~^~~~
e[0me[1mmake.c:191:34: e[0me[0;1;30mnote: e[0muse array indexing to silence this warninge[0m
e[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                                        ^
e[0me[1mmake.c:247:4: e[0me[0;1;35mwarning: e[0me[1madding 'int' to a string does not append to the string [-Wstring-plus-int]e[0m
                        spaces( depth ), t->name, t->boundname );
e[0;1;32m                        ^~~~~~~~~~~~~~~
e[0me[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                     ~~~~~~~~~~~~~~~~~~~^~~~
e[0me[1mmake.c:247:4: e[0me[0;1;30mnote: e[0muse array indexing to silence this warninge[0m
e[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                                        ^
e[0me[1mmake.c:256:4: e[0me[0;1;35mwarning: e[0me[1madding 'int' to a string does not append to the string [-Wstring-plus-int]e[0m
                        spaces( depth ), t->name, target_bind[ t->binding ] );
e[0;1;32m                        ^~~~~~~~~~~~~~~
e[0me[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                     ~~~~~~~~~~~~~~~~~~~^~~~
e[0me[1mmake.c:256:4: e[0me[0;1;30mnote: e[0muse array indexing to silence this warninge[0m
e[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                                        ^
e[0me[1mmake.c:261:4: e[0me[0;1;35mwarning: e[0me[1madding 'int' to a string does not append to the string [-Wstring-plus-int]e[0m
                        spaces( depth ), t->name, ctime( &t->time ) );
e[0;1;32m                        ^~~~~~~~~~~~~~~
e[0me[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                     ~~~~~~~~~~~~~~~~~~~^~~~
e[0me[1mmake.c:261:4: e[0me[0;1;30mnote: e[0muse array indexing to silence this warninge[0m
e[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                                        ^
e[0me[1mmake.c:485:3: e[0me[0;1;35mwarning: e[0me[1madding 'int' to a string does not append to the string [-Wstring-plus-int]e[0m
                spaces( depth ), t->name );
e[0;1;32m                ^~~~~~~~~~~~~~~
e[0me[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                     ~~~~~~~~~~~~~~~~~~~^~~~
e[0me[1mmake.c:485:3: e[0me[0;1;30mnote: e[0muse array indexing to silence this warninge[0m
e[1mmake.c:109:41: e[0me[0;1;30mnote: e[0mexpanded from macro 'spaces'e[0m
# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
e[0;1;32m                                        ^
e[0m5 warnings generated.
e[1mmake1.c:392:8: e[0me[0;1;31merror: e[0me[1mcall to undeclared function 'unlink'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]e[0m
                if( !unlink( targets->string ) )
e[0;1;32m                     ^
e[0me[1mmake1.c:392:8: e[0me[0;1;30mnote: e[0mdid you mean 'unlinkat'?e[0m
e[1m/nix/store/q51sb8fzdavjbkmnp5xhv9mb0g93a53j-libSystem-11.0.0/include/sys/unistd.h:212:9: e[0me[0;1;30mnote: e[0m'unlinkat' declared heree[0m
int     unlinkat(int, const char *, int) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
e[0;1;32m        ^
e[0m1 error generated.
e[1mparse.c:102:20: e[0me[0;1;31merror: e[0me[1mcall to undeclared function 'yylineno'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]e[0m
            p->yylineno = yylineno();
e[0;1;32m                          ^
e[0me[1mparse.c:102:20: e[0me[0;1;30mnote: e[0mdid you mean 'yylineo'?e[0m
e[1m./scan.h:53:5: e[0me[0;1;30mnote: e[0m'yylineo' declared heree[0m
int yylineo();
e[0;1;32m    ^
e[0m1 error generated.
e[1mpathunix.c:114:11: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        while( q = (char *)memchr( q, '.', end - q ) )
e[0;1;32m               ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e[0me[1mpathunix.c:114:11: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        while( q = (char *)memchr( q, '.', end - q ) )
e[0;1;32m                 ^
e[0me[0;32m               (                                    )
e[0me[1mpathunix.c:114:11: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        while( q = (char *)memchr( q, '.', end - q ) )
e[0;1;32m                 ^
e[0me[0;32m                 ==
e[0m1 warning generated.
e[1msearch.c:37:14: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        if( varlist = var_get( "LOCATE" ) )
e[0;1;32m            ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
e[0me[1msearch.c:37:14: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        if( varlist = var_get( "LOCATE" ) )
e[0;1;32m                    ^
e[0me[0;32m            (                            )
e[0me[1msearch.c:37:14: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        if( varlist = var_get( "LOCATE" ) )
e[0;1;32m                    ^
e[0me[0;32m                    ==
e[0me[1msearch.c:51:19: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
        else if( varlist = var_get( "SEARCH" ) )
e[0;1;32m                 ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
e[0me[1msearch.c:51:19: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
        else if( varlist = var_get( "SEARCH" ) )
e[0;1;32m                         ^
e[0me[0;32m                 (                            )
e[0me[1msearch.c:51:19: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
        else if( varlist = var_get( "SEARCH" ) )
e[0;1;32m                         ^
e[0me[0;32m                         ==
e[0m2 warnings generated.
e[1mvariable.c:86:14: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
            if( val = strchr( *e, '=' ) )
e[0;1;32m                ~~~~^~~~~~~~~~~~~~~~~~~
e[0me[1mvariable.c:86:14: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
            if( val = strchr( *e, '=' ) )
e[0;1;32m                    ^
e[0me[0;32m                (                      )
e[0me[1mvariable.c:86:14: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
            if( val = strchr( *e, '=' ) )
e[0;1;32m                    ^
e[0me[0;32m                    ==
e[0me[1mvariable.c:110:24: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
                for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 )
e[0;1;32m                                   ~~^~~~~~~~~~~~~~~~~~~~~
e[0me[1mvariable.c:110:24: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
                for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 )
e[0;1;32m                                     ^
e[0me[0;32m                                   (                      )
e[0me[1mvariable.c:110:24: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
                for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 )
e[0;1;32m                                     ^
e[0me[0;32m                                     ==
e[0me[1mvariable.c:197:13: e[0me[0;1;35mwarning: e[0me[1musing the result of an assignment as a condition without parentheses [-Wparentheses]e[0m
                    if( l = list_next( l ) )
e[0;1;32m                        ~~^~~~~~~~~~~~~~~~
e[0me[1mvariable.c:197:13: e[0me[0;1;30mnote: e[0mplace parentheses around the assignment to silence this warninge[0m
                    if( l = list_next( l ) )
e[0;1;32m                          ^
e[0me[0;32m                        (                 )
e[0me[1mvariable.c:197:13: e[0me[0;1;30mnote: e[0muse '==' to turn this assignment into an equality comparisone[0m
                    if( l = list_next( l ) )
e[0;1;32m                          ^
e[0me[0;32m                          ==
e[0m3 warnings generated.
make: *** [Makefile:115: jam0] Error 1

Guessing from the builds in Hydra (Hydra - nixpkgs:trunk:jam.x86_64-darwin), which break with the same messages around then but start working on December 30th, I suspect the issue’s been fixed but not backported (perhaps in jam: set std=c89 by abl · Pull Request #277024 · NixOS/nixpkgs · GitHub).

I agree that the PR @abathur identified is most likely the solution to this problem. I requested a backport: [Backport release-23.11] jam: set std=c89 by github-actions[bot] · Pull Request #289409 · NixOS/nixpkgs · GitHub

1 Like

Confirmed, this fixed it. Thank you so much, @abathur / @impl.

2 Likes