Change the SHELL used in TI Code Composer Studio's auto-generated Makefiles on Windows 10 - code-composer

I need the makefile generated by TI Code Composer Studio 10 to use SHELL = sh.exe instead of SHELL = cmd.exe. The insertion of the SHELL line seems to be specific to TI and not Eclipse. I can't figure out how to do this. I've tried setting environment variables at the system level and in the project build settings. I've tried running TI CCS from a bash shell hoping it might pick up its own environment. I've also looked through the Eclipse sources for generating the makefile.
Example:
Everything from SHELL to just before the -include line is TI specific.
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
SHELL = cmd.exe
CG_TOOL_ROOT := C:/ti/ccs1040/ccs/tools/compiler/ti-cgt-msp430_20.2.5.LTS
GEN_OPTS__FLAG :=
GEN_CMDS__FLAG :=
ORDERED_OBJS += \
"./msp430fr60x7_1.obj" \
"../lnk_msp430fr6047.cmd" \
$(GEN_CMDS__FLAG) \
-llibmpu_init.a \
-llibmath.a \
-llibc.a \
-include ../makefile.init
Reason: gmake creates batch files for commands like echo and our computers have security software that block randomly created batch files from running. If run from bash/sh, gmake doesn't use intermediate batch files.
Update: I may have a workaround by telling the project to invoke gmake like this: sh.exe -c gmake.exe args. That isn't working fully though as the args do not get passed.

After confirming with TI that the SHELL is hardcoded, this workaround is the solution.
You'll need to:
Create a make.sh shell script to run the real gmake.exe
Create a makefile.defs to fix some SHELL and RM variables inside the TI generated makefile
Install another sh.exe. I used the one installed with Git for Windows. The cygwin sh.exe that comes with the TI compiler doesn't work. This is a shame, because it would be nice to have a solution not requiring another tool.
First, modify your project build settings to run the make script. In TI Code Composer Studio:
Project Menu -> Show Build Settings -> CCS Build -> Builder
[ ] Uncheck "Use default build command"
Build Command: C:/Progra~1/Git/bin/sh.exe ${PROJECT_ROOT}/make.sh ${CCS_UTILS_DIR}/bin/gmake -k -j 8
Note: You have to use the MS-DOS short path for "Program Files," because it's 2021, and Eclipse can't handle spaces in a path.
Create make.sh in the PROJECT_ROOT directory:
#!C:/Progra~1/Git/bin/sh.exe
# The cygwin provided shell from TI doesn't work with make. Use the one from Git instead or even SourceTree's embedded Git shell.
# In TI CCS, Project -> Show Build Settings -> CCS Build -> Builder -> Build Command (Uncheck Use default build command)
# Build Command: C:/Progra~1/Git/bin/sh.exe ${PROJECT_ROOT}/make.sh ${CCS_UTILS_DIR}/bin/gmake -k -j 8
echo "$#"
# debugging
#echo $#
#env | sort
if [ $# -eq 0 ]; then
echo Nothing to do. >&2
exit
fi
export MAKESHELL="$SHELL"
# echo MAKESHELL is \'$MAKESHELL\' inside the script, but will be translated to the DOS path inside make.
"$#"
Create makefile.defs in the PROJECT_ROOT directory. The Eclipse generated makefile includes this file at the very end allowing it to override any settings set by TI.
# The invoking shell sets MAKESHELL so we can grab it here.
SHELL = $(MAKESHELL)
RM = rm -f
$(info "MAKEFLAGS is $(MAKEFLAGS)")
$(info "MAKECMDGOALS is $(MAKECMDGOALS)")
# $(info "SHELL is $(SHELL)")
# $(info "CWD is $(CWD)")
# $(info "PATH is ${PATH}")

Related

Makefile internal command on linux functional but not macos

Within a Makefile on linux, we can excute shell/bash commands with it to move directories or excute another files. However when porting the same Makefile over to macOS, all the commands are not readible (therefore path and execution are broken). Is there a universal command or workflow that can work on both?
Example of Makefile
.ONESHELL:
COMMAND ?= none
GIT_HASH ?= githash
alpine:
#cd images/alpine
#make ${COMMAND} GIT_HASH=${GIT_HASH} ALPINE_VERSION=3.6.5 TAG=3.6
so in a linux box both #CD and #MAKE are executed but not for macOS Catalina. I would like to make it universal so that both system will respect the appropriate command that follows.
Chances are that your MacOS box uses its default GNU make version (3.81). .ONESHELL was introduced with 3.82. Upgrade with Homebrew or MacPort. Anyway, better avoid make in recipes, prefer $(MAKE), and instead of cd; make you can use GNU make's -C option: $(MAKE) -C images/alpine ...

How to get CMake variable of package in shellscript

I want to find the Qt5WaylandClient_PRIVATE_INCLUDE_DIRS variable which is set by the Qt5WaylandClient package. How can I get it from the shell (dash)? Something like this:
cmake -find_package(Qt5WaylandClient) -get_variable Qt5WaylandClient_PRIVATE_INCLUDE_DIRS
or
cmake -file path/to/my/CMakeLists.txt -get_variable Qt5WaylandClient_PRIVATE_INCLUDE_DIRS
CMake does have a --find-package command line option, but it is not well supported, nor well-documented. There is an answer describing its functionality here, but that's probably not what you're looking for.
Initially, it appears you could just run cmake in script mode, using -P, on a CMake file containing your find_package(Qt5WaylandCleint) command and print its variables to the console.
cmake -P MyFindQt5WaylandClient.cmake
However, running find_package() outside the confines of a CMake project does not work. It yields several errors because CMake doesn't know anything about the system or your target language. So, you must create a minimal CMake project, then run find_package(). Something like this CMakeLists.txt file should work:
cmake_minimum_required(VERSION 3.16)
project(MyProj)
find_package(Qt5WaylandClient REQUIRED)
# Print the desired variable.
message("${Qt5WaylandClient_PRIVATE_INCLUDE_DIRS}")
You can then run cmake from the command line, and this will print the Qt5WaylandClient_PRIVATE_INCLUDE_DIRS variable to the console. You can use the -S and -B command line options to specify the CMake source and binary directories, respectively.
cmake -S . -B build

How to alias a particular cmake command

I'm trying to work around a QtCreator bug (https://bugreports.qt.io/browse/QTCREATORBUG-20972) where QtCreator fails to open a CMake project because it is trying to create a socket file in /tmp/RANDOM_PATH/socket whereas "RANDOM_PATH" does not exist.
I can reproduce the issue manually with:
$ /usr/bin/cmake -E server --pipe=/tmp/not-existing-path/socket
--experimental CMake Error: Internal Error with /tmp/not-existing-path/socket: EACCES
The suggestion given in https://bugreports.qt.io/browse/QTCREATORBUG-18444 is to create an alias of cmake which would report
"serverMode":false
when given the command
cmake -E capabilities
which on my machine (Ubuntu 18.04) outputs:
{"generators":[{"extraGenerators":[],"name":"Watcom WMake","platformSupport":false,"toolsetSupport":false},{"extraGenerators":["CodeBlocks","CodeLite","Sublime Text 2","Kate","Eclipse CDT4","KDevelop3"],"name":"Unix Makefiles","platformSupport":false,"toolsetSupport":false},{"extraGenerators":["CodeBlocks","CodeLite","Sublime Text 2","Kate","Eclipse CDT4"],"name":"Ninja","platformSupport":false,"toolsetSupport":false}],"serverMode":true,"version":{"isDirty":false,"major":3,"minor":10,"patch":2,"string":"3.10.2","suffix":""}}
What's the easiest way to achieve this?
I've tried to add such an alias:
cmake='cmake | sed "s/\"serverMode\":true/\"serverMode\":false/g"'
, but the issue is that the "sed" command needs to be after the arguments given to cmake, and not before.
I see from that bug report:
If you want to run a newer cmake without server-mode, then you will need to write a wrapper around cmake that removes the server-mode support indicator from the output reported by
cmake -E capabilities
That would be something like
cmake() {
if [[ "$*" == "-E capabilities" ]]; then
command cmake "$#" | jq -c 'del(.serverMode)'
else
command cmake "$#"
fi
}
You make have to make that a standalone script rather than a shell function.

Can I change gcc default options without using command-line?

I am plagued by the Gentoo bug #580414.
In short, the default options mislead configure into not detecting standard include files because some headers contain this code:
#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0
# if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
, and __OPTIMIZE__ is off by default and _FORTIFY_SOURCE is on by default, and the generated warning is perceived as an error, indicating that "stdint.h", "stdlib.h" and many others are absent. Compilation eventually fails and I cannot install programs or even upgrade the gcc itself.
Can I simply put something in environment vars or in the /etc directory to turn on -O or turn off _FORTIFY_SOURCE for every invocation of gcc without editing gentoo build scripts?
Tried in /etc/portage/make.conf
EPATCH_USER_EXCLUDE='*10_all_default-fortify-source*'
CFLAGS="-O2 -O -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0"
CFLAGS_FOR_BUILD="-O2 -O -U_FORTIFY_SOURCE"
without any improvement.
There is no such environment variable. CFLAGS in make.conf won't work because the build systems usually do something like this:
$(CC) $(CFLAGS) $(MY_HARDCODED_CFLAGS)
thus overwriting your flags.
But to mangle any argument passed to gcc, you can use the following workaround.
create a directory, eg. under /usr/local/bin/
create a script which will mangle its arguments as you wish and then passes them to gcc or "/usr/bin/" + basename(argv[0]) (beware of infinite recursion)
make this script executable
create symlinks to the script in that directory with names like gcc, cc, x86_64-pc-linux-gnu-gcc
put a bunch of lines like this into /etc/portage/bashrc:
the_dir="/usr/local/bin/THE_DIR"
if [[ "${PATH}" != *"${the_dir}"* ]] ; then
export PATH="${the_dir}:${PATH}"
fi
Also to save yourself from possible problems in the future, do not forget to put a note about this change somewhere. (As should be done with any workaround anyway.)
Just documenting the commands I actually used to resolve the issue.
mv /usr/bin/i686-pc-linux-gnu-gcc /usr/bin/i686-pc-linux-gnu-gcc.OLD
cat >/usr/bin/i686-pc-linux-gnu-gcc
/usr/bin/i686-pc-linux-gnu-gcc.OLD -O "$#"
ctrl+D
chmod +x /usr/bin/i686-pc-linux-gnu-gcc
cp /usr/i686-pc-linux-gnu/gcc-bin/4.6.3/i686-pc-linux-gnu-gcc /usr/i686-pc-linux-gnu/gcc-bin/4.6.3/i686-pc-linux-gnuu-gcc
mv /usr/bin/i686-pc-linux-gnu-g++ /usr/bin/i686-pc-linux-gnuu-g++
cat >/usr/bin/i686-pc-linux-gnu-g++
/usr/bin/i686-pc-linux-gnuu-g++ -O "$#"
ctrl+D
chmod +x /usr/bin/i686-pc-linux-gnu-g++
cp /usr/i686-pc-linux-gnu/gcc-bin/4.6.3/i686-pc-linux-gnu-g++ /usr/i686-pc-linux-gnu/gcc-bin/4.6.3/i686-pc-linux-gnuu-g++
cp /etc/env.d/gcc/i686-pc-linux-gnu-4.6.3.O /etc/env.d/gcc/i686-pc-linux-gnuu-4.6.3
The credit all goes to rindeal. Recap:
identify the binaries that get invoked as compilers
rename them
in their place, create shell scripts that prepend "-O"
create a gcc profile to appease gcc-config
emerge all the unwieldy packages!

figure out ld command arguments from xcode run script build phase

How can I determine what will be the arguments of the ld command in the build process from inside a script running as "run script build phase"?
I was looking at xcodebuild -dry-run as an option, but then I need to understand what should be the arguments I supply it.
Any idea for a robust solution?
EDIT:
It seems that xcodebuild doesn't support LD and LDPLUSPLUS when the project includes swift source code. So the solution that #fpotter offered doesn't work on project with swift.
Any thoughts?
Xcode doesn't expose a nice way to do this. In a Run Script build phase, all you have to work with are the Xcode build settings provided to you in the environment.
If you really need the entire argument list to ld, there's a hack you can use. With the LD and LDPLUSPLUS build settings, you can make Xcode call a script of your own instead of the real ld. From that script, you could capture the args, call through to the real linker, and then do whatever post processing you like there rather than in a Run Script build phase.
Here's how you could do that:
Create an .xcconfig for your target.
It should look like this:
LD = $(SRCROOT)/ld-wrapper/clang
LDPLUSPLUS = $(SRCROOT)/ld-wrapper/clang++
SRCROOT points to your project's directory. The LDPLUSPLUS line is only required if your app has C++ or ObjC++ code. If you don't want to create an xcconfig, you can also add these as User-Defined build settings via the Xcode UI.
Create wrapper scripts for Xcode to call.
Install a script like this at <your project root>/ld-wrapper/wrapper.sh:
#!/bin/bash
set -o errexit
# Choose which clang to run (clang or clang++) depending on how we're invoked.
# If we're invoked via the 'clang' link, we'll run 'clang'. If we're invoked
# via the 'clang++' link, we'll run 'clang++'.
CLANG_PATH="$DEVELOPER_DIR"/Toolchains/XcodeDefault.xctoolchain/usr/bin/$(basename "$0")
"$CLANG_PATH" "$#"
echo "clang args: $#"
echo "do any post processing here."
Create symlinks for the wrapper script for clang and clang++:
cd <project root>/ld-wrapper
ln -s wrapper.sh clang
ln -s wrapper.sh clang++
That's it. It's ugly, but it works.

Resources