Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable full compilation and linking #1

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ Hey there embedded developers, you deserve a modern IDE!

Running this script from the root directory of your [nRF5-SDK](https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF5-SDK) will create CMakelists.txt files for all of the example projects in the SDK.

_Disclaimer: This will not let you build or flash your project from CLion but you will be able to navigate through your project and the SDK libraries._
## How to convert all examples on the SDK to CLion
_Tested on Ubuntu 16.04
1. Clone the repository or download the scripts nrf5-sdk-to-clion.sh and nrf5-make2cmake.sh
2. (optional) Add the path where the scripts are located to the PATH enviroment variable PATH
4. (optional) Create a backup for your current nrf5-SDK directory
5. `nrf5-sdk-to-clion.sh <root_to_sdk>`
6. Open _"CMakeLists.txt"_ for the desired project
7. From CLion, go to File-->Open and choose the root directory of the nRF5-SDK.
The last stage is needed since adding all of the example projects to the CMakeLists.txt file would overload CLion.

## How to convert any Makefile (with nRF5-SDK structure) to CMake
_Tested on Ubuntu 16.04
`nrf5-make2cmake.sh <path_to_Makefile>` this will create a CMakeLists.txt on the same folder of the Makefile


## How to use it
_Tested on Ubuntu 16.04 and macOS_
1. (optional) Create a backup for your current nrf5-SDK directory
2. cd into the root of the nrf5-SDK directory
3. `curl -s https://raw.githubusercontent.com/Jumperr-labs/nrf5-sdk-clion/master/nrf5-sdk-to-clion.sh | bash`
4. Open _"./CMakeLists.txt"_ and uncomment the desired project's path (you can uncomment multiple projects)
5. From CLion, go to File-->Open and choose the root directory of the nRF5-SDK.

The last stage is needed since adding all of the example projects to the CMakeLists.txt file would overload CLion.
143 changes: 143 additions & 0 deletions nrf5-make2cmake.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/usr/bin/env bash

#Copyright 2017 Jumper Labs Ltd.

#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.

set -e

nrf52_stlink="nrf52_stlink.cfg"

\cat << 'EOF3' > ${nrf52_stlink}

source [find interface/stlink-v2-1.cfg]

transport select hla_swd

source [find target/nrf52.cfg]

EOF3


tmp_makefile="CMakeLists-generator.mk"
\cat << 'EOF' > ${tmp_makefile}
LINKERSCRIPT=$$(cat Makefile | sed -n 's/\s*LINKER_SCRIPT\s*:=\s*\(.*\.ld\)/\1/p')
LINKER_SCRIPT:=$(LINKERSCRIPT)
include Makefile

OPT += -std=c99

TEMPLATE_PATH:="$$$ \{CMAKE_SOURCE_DIR\}/"$(TEMPLATE_PATH)

generate:
@echo 'cmake_minimum_required(VERSION 3.4.0)'
@echo ''
@echo 'include(nrf52.cmake) # get it from https://github.com/nvelozsavino/nordic_cmake.git'
@echo ''
@echo ''
@echo '$(GNU_INSTALL_ROOT2)'
@echo ''
$(foreach var, PROJECT_NAME, \
echo "set($(var) $($(var)))" ; \
)
@echo ''
@echo ''
$(foreach var, CFLAGS CXXFLAGS ASMFLAGS LIB_FILES, \
echo "set($(var)" ; \
echo " $($(var))" | sed -e 's/\s\+/\n\t/g'; \
echo ")" ; \
)
$(foreach var, LDFLAGS, \
echo "set($(var)" ; \
echo " $($(var))" | sed -e 's/\s\+/\n\t/g; s/-\(L\|T\)/-\1$$$ {CMAKE_SOURCE_DIR}\//g'; \
echo ")" ; \
)
@echo 'set(SRC_FILES '
@echo ' $(SRC_FILES)' | sed -e 's/\s\+/\n\t/g'
@echo ')'
@echo ''
@echo ''
@echo 'set(INC_FOLDERS'
@echo ' $(INC_FOLDERS)' | sed -e 's/\s\+/\n\t/g'
@echo ')'
@echo ''
@echo ''
@echo 'project( $$$ {PROJECT_NAME} )'
@echo 'enable_language(ASM)'
@echo ''
@echo 'NRF_SET_COMPILERS()'
@echo 'SET_COMPILATION_FLAGS()'

@echo ''
@echo 'set(PROJECT_CMAKE_INCLUDE "$$$ {CMAKE_SOURCE_DIR}/project.cmake" CACHE STRING "Project CMake Include")'
@echo 'if(EXISTS $$$ {PROJECT_CMAKE_INCLUDE} )'
@echo ' include($$$ {PROJECT_CMAKE_INCLUDE})'
@echo 'endif()'

@echo ''
@echo ''

@echo 'include_directories($$$ {INC_FOLDERS})'
@echo 'add_executable($$$ {PROJECT_NAME} $$$ {SRC_FILES})'

@echo 'target_link_libraries($$$ {PROJECT_NAME} PUBLIC $$$ {LIBS_CLEAN} $$$ {LIB_FILES_CLEAN})'
@echo ''
@echo ''

@echo 'message(FATAL_ERROR "Set SOFTDEVICE variables with the Softdevice hex file and info and comment this error")'
@echo 'set(SOFTDEVICE_HEX_FILE "<PATH TO SOFTDEVICE HEX FILE>")'
@echo 'set(SOFTDEVICE_FWID_REQ "<FWID_REQ>")'
@echo 'set(SOFTDEVICE_FWID_ID "<FWID_ID>")'
@echo ''
@echo ''

@echo 'set(FW_VERSION "v0.0.1") #Firmware Version'
@echo 'set(OUTPUT_FOLDER "$$$ {CMAKE_SOURCE_DIR}/build/$$$ {FW_VERSION}/")'
@echo 'set(OBJ_NAME "$$$ {OUTPUT_FOLDER}/$$$ {PROJECT_NAME}")'
@echo ''
@echo ''

@echo 'set(APP_HEX_FILE $$$ {TARGET_HEX_FILE})'
@echo 'set(APP_HEX_FILE-CREATE TRUE)'
@echo 'set(BOOTLOADER_VERSION 1)'

@echo 'SET_COMPILER_OPTIONS($$$ {PROJECT_NAME})'
@echo 'PRINT_SIZE_OF_TARGETS($$$ {PROJECT_NAME})'
@echo 'ADD_HEX_BIN_TARGETS($$$ {PROJECT_NAME} $$$ {OBJ_NAME})'
@echo 'NRF_FLASH_TARGET($$$ {PROJECT_NAME} $$$ {TARGET_HEX_FILE})'
@echo ''

@echo 'if (NOT BOOTLOADER_HEX_FILE)'
@echo ' message(WARNING "Add -DBOOTLOADER_HEX_FILE=<path_to_bootloader_hex_file> to CMake env variables")'
@echo 'endif()'

@echo 'if (NOT KEY_PEM_FILE)'
@echo ' message(WARNING "Add -DKEY_PEM_FILE=<path_to_pem_key_file> to CMake env variables")'
@echo 'endif()'
@echo 'GENERATE_UPDATE_FLASH_TARGET($$$ {PROJECT_NAME} "APP" $$$ {OBJ_NAME}.zip)'
EOF



makefile=$1
\pwd
dir=`\dirname ${makefile}`
\echo "Creating CMakeLists.txt for ${makefile}"
\pushd ${dir} > /dev/null
\make -s -f ${tmp_makefile} generate > CMakeLists.txt
\popd > /dev/null
\rm ${tmp_makefile}

echo '************************************'
echo 'Enjoy using CLION with the NRF5-SDK!'
echo '************************************'
178 changes: 147 additions & 31 deletions nrf5-sdk-to-clion.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,160 @@
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
function create_cmake {
set -e

set -e
tmp_makefile=$(mktemp)

tmp_makefile="/tmp/CMakeLists-generator.mk"
\cat << 'EOF' > ${tmp_makefile}
LINKERSCRIPT:=`cat Makefile | sed -n 's/.*LINKER_SCRIPT\s\+:=\s\+\(.*\.ld\).*/\1/p'`
LINKER_SCRIPT:="$$$ \{CMAKE_SOURCE_DIR\}/"$(LINKERSCRIPT)
include Makefile
OPT += -std=c99

\cat << 'EOF' > ${tmp_makefile}
include Makefile
TEMPLATE_PATH:="$$$ \{CMAKE_SOURCE_DIR\}/"$(TEMPLATE_PATH)

generate:
$(foreach var, PROJECT_NAME SDK_ROOT PROJ_DIR SRC_FILES INC_FOLDERS CFLAGS CXXFLAGS, \
echo "set($(var) $($(var)))" ; \
echo ; \
)

@echo 'cmake_minimum_required(VERSION 2.4.0)'
@echo 'project($$$ {PROJECT_NAME})'
generate:
@echo 'cmake_minimum_required(VERSION 3.4.0)'

@echo 'list(APPEND CFLAGS "-undef" "-D__GNUC__")'
@echo 'list(FILTER CFLAGS EXCLUDE REGEX mcpu)'
@echo 'string(REPLACE ";" " " CFLAGS "$$$ {CFLAGS}")'
@echo 'set(CMAKE_C_FLAGS $$$ {CFLAGS})'
@echo 'FUNCTION(SET_COMPILER_OPTIONS TARGET)'
@echo ' target_compile_options($$$ {TARGET} PRIVATE'
@echo ' $$$ <$$$ <COMPILE_LANGUAGE:C>:$$$ {CFLAGS}>'
@echo ' $$$ <$$$ <COMPILE_LANGUAGE:CXX>:$$$ {CXXFLAGS}>'
@echo ' $$$ <$$$ <COMPILE_LANGUAGE:ASM>:$$$ {ASMFLAGS}>'
@echo ' )'
@echo 'ENDFUNCTION()'

@echo 'include_directories($$$ {INC_FOLDERS})'
@echo 'add_executable($$$ {PROJECT_NAME} $$$ {SRC_FILES})'
EOF
@echo ''
@echo ''

\echo "cmake_minimum_required(VERSION 2.8.9)" > CMakeLists.txt
@echo 'FUNCTION(PRINT_SIZE_OF_TARGETS TARGET)'
@echo ' SET(FILENAME "$$$ {CMAKE_BINARY_DIR}/$$$ {TARGET}")'
@echo ' add_custom_command(TARGET $$$ {TARGET} POST_BUILD COMMAND $$$ {CMAKE_SIZE} $$$ {FILENAME})'
@echo 'ENDFUNCTION()'

for makefile in `\find ./examples -name Makefile` ; do
dir=`\dirname ${makefile}`
\echo "Creating CMakeLists.txt for ${makefile}"
\pushd ${dir} > /dev/null
\make -s -f ${tmp_makefile} generate > CMakeLists.txt
\popd > /dev/null
\echo "#add_subdirectory(${dir})" >> CMakeLists.txt
done
\rm ${tmp_makefile}
@echo ''
@echo ''

@echo 'FUNCTION(ADD_HEX_BIN_TARGETS TARGET)'
@echo ' SET(FILENAME "$$$ {CMAKE_BINARY_DIR}/$$$ {TARGET}")'
@echo ' add_custom_command(TARGET $$$ {TARGET} POST_BUILD COMMAND $$$ {CMAKE_OBJCOPY} -Oihex $$$ {FILENAME} $$$ {FILENAME}.hex)'
@echo ' add_custom_command(TARGET $$$ {TARGET} POST_BUILD COMMAND $$$ {CMAKE_OBJCOPY} -Obinary $$$ {FILENAME} $$$ {FILENAME}.bin)'
@echo 'ENDFUNCTION()'

@echo ''
@echo ''


@echo 'SET(CMAKE_SYSTEM_NAME Generic)'
@echo 'SET(CMAKE_SYSTEM_PROCESSOR arm)'
@echo 'INCLUDE(CMakeForceCompiler)'

@echo '$(GNU_INSTALL_ROOT2)'
@echo ''

@echo ''
@echo ''
@echo ''
@echo ''


$(foreach var, PROJECT_NAME SDK_ROOT PROJ_DIR OUTPUT_DIRECTORY LDFLAGS, \
echo "set($(var) $($(var)))" ; \
)
@echo ''
@echo ''

$(foreach var, CFLAGS CXXFLAGS ASMFLAGS LIB_FILES , \
echo "set($(var)" ; \
echo " $($(var))" | sed -e 's/\s\+/\n\t/g'; \
echo ")" ; \
)

@echo 'set(SRC_FILES '
@echo ' $(SRC_FILES)' | sed -e 's/\s\+/\n\t/g'
@echo ')'
@echo ''
@echo ''

@echo 'set(INC_FOLDERS'
@echo ' $(INC_FOLDERS)' | sed -e 's/\s\+/\n\t/g'
@echo ')'
@echo ''
@echo ''



@echo 'foreach(LIB $$$ {LIB_FILES})'
@echo 'find_file(LIB_FILE_$$$ {LIB} $$$ {LIB} $$$ {CMAKE_SOURCE_DIR})'
@echo ' if (NOT LIB_FILE_$$$ {LIB})'
@echo ' list(APPEND LIBS $$$ {LIB})'
@echo ' else ()'
@echo ' list(APPEND LIB_FILES_CLEAN $$$ {LIB_FILE_$$$ {LIB}})'
@echo ' endif()'
@echo 'endforeach()'

@echo ''
@echo ''


@echo 'string(REPLACE ";" " " LDFLAGS "$$$ {LDFLAGS}")'

@echo ''
@echo ''

echo '************************************'
echo 'Enjoy using CLION with the NRF5-SDK!'
echo '************************************'
@echo 'set(CMAKE_C_FLAGS "" CACHE INTERNAL "c compiler flags")'
@echo 'set(CMAKE_CXX_FLAGS "" CACHE INTERNAL "c++ compiler flags")'
@echo 'set(CMAKE_ASM_FLAGS "" CACHE INTERNAL "asm compiler flags")'
@echo 'set(CMAKE_EXE_LINKER_FLAGS $$$ {LDFLAGS} CACHE INTERNAL "executable linker flags")'

@echo ''
@echo ''

@echo 'set(CMAKE_C_COMPILER $(CC))'
@echo 'set(CMAKE_CXX_COMPILER $(CXX))'
@echo 'set(CMAKE_ASM_COMPILER $(AS))'
@echo 'set(CMAKE_SIZE $(SIZE))'
@echo ''
@echo ''

@echo ''
@echo ''



@echo 'project($$$ {PROJECT_NAME})'
@echo 'enable_language(ASM)'

@echo ''
@echo ''

@echo 'set(LIBS $$$ {LIB_FILES})'

@echo 'include_directories($$$ {INC_FOLDERS})'
@echo 'add_executable($$$ {PROJECT_NAME} $$$ {SRC_FILES})'
@echo 'target_link_libraries($$$ {PROJECT_NAME} PUBLIC $$$ {LIB_FILES_CLEAN})'

@echo ''
@echo ''


@echo 'SET_COMPILER_OPTIONS($$$ {PROJECT_NAME})'
@echo 'PRINT_SIZE_OF_TARGETS($$$ {PROJECT_NAME})'
@echo 'ADD_HEX_BIN_TARGETS($$$ {PROJECT_NAME})'
EOF


dir=`\dirname $1`
\echo "Creating CMakeLists.txt for $1"
\pushd ${dir} > /dev/null
\make -s -f ${tmp_makefile} generate > CMakeLists.txt
\popd > /dev/null
\rm ${tmp_makefile}

}

for makefile in `\find $1 -name Makefile` ; do
create_cmake ${makefile}
done