Unfortunately that example project doesn’t work for me. Something about the way it’s trying to modify the path to add the IAR bin/ directory isn’t working on my system, so it can’t find any of the IAR tools on configure.
Using the following settings in iar-toolchain.cmake:
# Action: Set the `<arch>` to the compiler's target architecture
# Examples: 430, 8051, arm, avr, riscv, rx, rl78, rh850, stm8 or v850
set(CMAKE_SYSTEM_PROCESSOR arm)
# Action: Set the `IAR_INSTALL_DIR` to the tool installation path
set(IAR_INSTALL_DIR "C:\\Program Files\\IAR Systems\\Embedded Workbench 9.0\\arm")
And running the command `C:\Workspaces\IARExamples\cmake-tutorial\examples\using-libs\arm>cmake -G “Ninja Multi-Config” -B_builds --toolchain …/…/iar-toolchain.cmake```
I get the following output for the example program:
-- The C compiler identification is unknown
CMake Error at CMakeLists.txt:3 (project):
The CMAKE_C_COMPILER:
iccarm
is not a full path and was not found in the PATH.
Tell CMake where to find the compiler by setting either the environment
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
the compiler, or to the compiler name if it is in the PATH.
-- Configuring incomplete, errors occurred!
See also "C:/Workspaces/IARExamples/cmake-tutorial/examples/using-libs/arm/_builds/CMakeFiles/CMakeOutput.log".
See also "C:/Workspaces/IARExamples/cmake-tutorial/examples/using-libs/arm/_builds/CMakeFiles/CMakeError.log".
C:\Workspaces\IARExamples\cmake-tutorial\examples\using-libs\arm>
C:\Workspaces\IARExamples\cmake-tutorial\examples\using-libs\arm>
C:\Workspaces\IARExamples\cmake-tutorial\examples\using-libs\arm>
C:\Workspaces\IARExamples\cmake-tutorial\examples\using-libs\arm>cmake -G "Ninja Multi-Config" -B_builds --toolchain ../../iar-toolchain.cmake
-- The C compiler identification is unknown
CMake Error at CMakeLists.txt:3 (project):
The CMAKE_C_COMPILER:
iccarm
is not a full path and was not found in the PATH.
Tell CMake where to find the compiler by setting either the environment
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
the compiler, or to the compiler name if it is in the PATH.
-- Configuring incomplete, errors occurred!
See also "C:/Workspaces/IARExamples/cmake-tutorial/examples/using-libs/arm/_builds/CMakeFiles/CMakeOutput.log".
See also "C:/Workspaces/IARExamples/cmake-tutorial/examples/using-libs/arm/_builds/CMakeFiles/CMakeError.log".
I think instead of modifying the PATH like this toolchain example does, it would be better to use a find_package script to locate the IAR toolchain and use complete paths for the C compiler, etc. This is because the build environment might not be the same as the configure environment, so changes to the PATH can be lost.
@felipe-iar OK, I do get a bit futher with that, but I get the following error:
-- The C compiler identification is IAR ARM 9.10.2
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: C:/Program Files/IAR Systems/Embedded Workbench 9.0/arm/bin/iccarm.exe
-- Check for working C compiler: C:/Program Files/IAR Systems/Embedded Workbench 9.0/arm/bin/iccarm.exe - broken
CMake Error at C:/Program Files/CMake/share/cmake-3.22/Modules/CMakeTestCCompiler.cmake:69 (message):
The C compiler
"C:/Program Files/IAR Systems/Embedded Workbench 9.0/arm/bin/iccarm.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Workspaces/IARExamples/cmake-tutorial/examples/using-libs/arm/_builds/CMakeFiles/CMakeTmp
Run Build Command(s):C:/PROGRA~1/Ninja/ninja.exe cmTC_264de && [1/2] Building C object CMakeFiles\cmTC_264de.dir\Debug\testCCompiler.c.o
[2/2] Linking C static library Debug\libcmTC_264de.a
FAILED: Debug/libcmTC_264de.a
cmd.exe /C "cd . && C:\Strawberry\c\bin\ar.exe Debug\libcmTC_264de.a --create CMakeFiles\cmTC_264de.dir\Debug\testCCompiler.c.o && cd ."
C:\Strawberry\c\bin\ar.exe: unknown option -- e
Usage: C:\Strawberry\c\bin\ar.exe [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file...
C:\Strawberry\c\bin\ar.exe -M [<mri-script]
commands:
d - delete file(s) from the archive
m[ab] - move file(s) in the archive
p - print file(s) found in the archive
q[f] - quick append file(s) to the archive
r[ab][f][u] - replace existing or insert new file(s) into the archive
s - act as ranlib
t[O][v] - display contents of the archive
x[o] - extract file(s) from the archive
command specific modifiers:
[a] - put file(s) after [member-name]
[b] - put file(s) before [member-name] (same as [i])
[D] - use zero for timestamps and uids/gids
[U] - use actual timestamps and uids/gids (default)
[N] - use instance [count] of name
[f] - truncate inserted file names
[P] - use full path names when matching
[o] - preserve original dates
[O] - display offsets of files in the archive
[u] - only replace files that are newer than current archive contents
generic modifiers:
[c] - do not warn if the library had to be created
[s] - create an archive index (cf. ranlib)
[S] - do not build a symbol table
[T] - make a thin archive
[v] - be verbose
[V] - display the version number
@<file> - read options from <file>
--target=BFDNAME - specify the target object format as BFDNAME
optional:
--plugin <p> - load the specified plugin
emulation options:
No emulation specific options
C:\Strawberry\c\bin\ar.exe: supported targets: pe-x86-64 pei-x86-64 pe-bigobj-x86-64 elf64-x86-64 elf64-l1om elf64-k1om pe-i386 pei-i386 elf32-i386 elf32-iamcu elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:3 (project)
-- Configuring incomplete, errors occurred!
It looks like it found the wrong binutils, not the ones associated with IAR?
Thank you for your detailed description of the problem.
About the suggestion of prepending the ${TOOLKIT_DIR}/bin to the PATH variable from within the iar-toolchain.cmake toolchain file, I can mention that, according to the CMake Documentation (reference), if we change the PATH environment variable, the change will only take effect while CMake is running. If echo %PATH% is executed after the CMake’s configuration step, it will be revealed that the ${TOOLKIT_DIR}/bin is not sticky when used that way. Of course, please keep in mind that this is not the only possible solution and was was chosen as “default” for the tutorial for 2 simple reasons: portability and backward compatibility. There are 10 different compiler’s target architectures on multiple operating systems supported in CMake and we tried to make sure that most of them would be covered. Also, this technique allows us to use the selected installation of the IAR tools without the need of setting the system’s global PATH outside CMake.
As per the Strawberry’s archiver interfering in the process, that’s a new one to me. It is also a bit strange, because pre-pending the ${TOOLKIT_DIR}/bin should be taking precedence, as it would be “theoretically” placed prior the C:\Strawberry folder.
As a test, you could try to slightly change the iar-toolchain.cmake using a snippet similar to this:
# Add the selected IAR toolchain to the PATH (only while CMake is running)
if(UNIX)
set(ENV{PATH} "${TOOLKIT_DIR}/bin:$ENV{PATH}")
else()
set(ENV{PATH} "${TOOLKIT_DIR}/bin;$ENV{PATH}")
endif()
message(STATUS "PATH is: $ENV{PATH}")
Maybe CMake is checking for GNU tool names (ld, ar, etc) before the IAR names and because a full path isn’t given to the compiler it checks the system path first?
When I specify the full path to the compiler like this:
# CMake requires individual variables for the C Compiler, C++ Compiler and Assembler
set(CMAKE_C_COMPILER "${TOOLKIT_DIR}/bin/icc${CMAKE_SYSTEM_PROCESSOR}.exe")
set(CMAKE_CXX_COMPILER "${TOOLKIT_DIR}/bin/icc${CMAKE_SYSTEM_PROCESSOR}.exe")
set(CMAKE_ASM_COMPILER "${TOOLKIT_DIR}/bin/iasm${CMAKE_SYSTEM_PROCESSOR}.exe")
Nicely noticed, @pfox89. This might be, in fact, the root cause of the problem. Please give me some time to investigate this issue from my end. Thank you very much for taking time to test. I hope it helps.
In order to try to reproduce such issue, I installed the latest version of the StrawberryPerl on my station, so I got the ar.exe available on the PATH. The tutorial examples worked without having to specify the full path on the CMAKE_<lang>_COMPILER variable.
C:\cmake\examples\using-libs\arm>cmake -G "Ninja Multi-Config" -B_builds --toolchain ../../iar-toolchain.cmake
-- The C compiler identification is IAR ARM 9.10.2
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/IAR_Systems/EWARM/9.10.2/arm/bin/iccarm.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/cmake/examples/using-libs/arm/_builds
C:\cmake\examples\using-libs\arm>cmake --build _builds --config Debug --verbose
[1/6] C:\IAR_Systems\EWARM\9.10.2\arm\bin\iccarm.exe --silent C:\cmake\examples\using-libs\arm\lib\src\add.c -DCMAKE_INTDIR=\"Debug\" -IC:\cmake\examples\using-libs\arm\lib\include -IC:\cmake\examples\using-libs\arm\lib\src -r --cpu Cortex-M4 --dlib_config normal -e --dependencies=ns lib\CMakeFiles\myMath.dir\Debug\src\add.c.o.d -o lib\CMakeFiles\myMath.dir\Debug\src\add.c.o
[2/6] C:\IAR_Systems\EWARM\9.10.2\arm\bin\iccarm.exe --silent C:\cmake\examples\using-libs\arm\lib\src\mul.c -DCMAKE_INTDIR=\"Debug\" -IC:\cmake\examples\using-libs\arm\lib\include -IC:\cmake\examples\using-libs\arm\lib\src -r --cpu Cortex-M4 --dlib_config normal -e --dependencies=ns lib\CMakeFiles\myMath.dir\Debug\src\mul.c.o.d -o lib\CMakeFiles\myMath.dir\Debug\src\mul.c.o
[3/6] C:\IAR_Systems\EWARM\9.10.2\arm\bin\iccarm.exe --silent C:\cmake\examples\using-libs\arm\lib\src\sub.c -DCMAKE_INTDIR=\"Debug\" -IC:\cmake\examples\using-libs\arm\lib\include -IC:\cmake\examples\using-libs\arm\lib\src -r --cpu Cortex-M4 --dlib_config normal -e --dependencies=ns lib\CMakeFiles\myMath.dir\Debug\src\sub.c.o.d -o lib\CMakeFiles\myMath.dir\Debug\src\sub.c.o
[4/6] C:\IAR_Systems\EWARM\9.10.2\arm\bin\iccarm.exe --silent C:\cmake\examples\using-libs\arm\app\src\main.c -DCMAKE_INTDIR=\"Debug\" -IC:\cmake\examples\using-libs\arm\lib\include -r --dlib_config normal --cpu Cortex-M4 --fpu VFPv4_sp -e --dependencies=ns app\CMakeFiles\myProgram.dir\Debug\src\main.c.o.d -o app\CMakeFiles\myProgram.dir\Debug\src\main.c.o
[5/6] cmd.exe /C "cd . && C:\IAR_Systems\EWARM\9.10.2\arm\bin\iarchive.exe lib\Debug\libmyMath.a --create lib\CMakeFiles\myMath.dir\Debug\src\add.c.o lib\CMakeFiles\myMath.dir\Debug\src\sub.c.o lib\CMakeFiles\myMath.dir\Debug\src\mul.c.o && cd ."
[6/6] cmd.exe /C "cd . && C:\IAR_Systems\EWARM\9.10.2\arm\bin\ilinkarm.exe --silent app\CMakeFiles\myProgram.dir\Debug\src\main.c.o --semihosting --redirect ___write=___write_buffered --map C:/cmake/examples/using-libs/arm/_builds/app/Debug/myProgram.elf.map --config C:/IAR_Systems/EWarm/9.10.2/arm/config/linker/ST/stm32f407xG.icf lib\Debug\libmyMath.a -o app\Debug\myProgram.elf && cd ."
C:\cmake\examples\using-libs\arm>ar
Usage: ar [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file...
ar -M [<mri-script]
<...>
emulation options:
No emulation specific options
ar: supported targets: pe-x86-64 pei-x86-64 pe-bigobj-x86-64 elf64-x86-64 elf64-l1om elf64-k1om pe-i386 pei-i386 elf32-i386 elf32-iamcu elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex
C:\cmake\examples\using-libs\arm>echo %PATH%
C:\cmake\cmake-3.22.0-rc1-windows-x86_64\bin;C:\Windows;C:\WINDOWS\system32;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\;C:\Program Files (x86)\Windows Kits\10\Microsoft Application Virtualization\Sequencer\;C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;
C:\cmake\examples\using-libs\arm>
Ah, it looks like this was partially my mistake. After correcting the path, I didn’t delete the build directory before re-configuring. Because the path was wrong on my first attempt, it had cached binutils paths that it had found in the system PATH, which happened to be the ones from Strawberry Perl on my system.
It works if I start with a clean build directory. It might be worth at least noting this pitfall in the documentation.
In the long run, it might be better if CMake failed quickly if it can’t find the specified compiler, rather than continuing to search and potentially putting wrong values in the cache.
Thanks for the feedback. Perhaps it is a good idea to provide an explicit distinction between IAR_INSTALL_DIR and TOOLKIT_DIR/bin in the tutorial’s “Configuring the toolchain file” section.
It seems that for ma generating the scripts for the build system works fine, but once it comes to building it - it fails to open header files from IAR:
C:\Projects\Flow6_E4\Firmware>cmake -B_builds -G "Ninja Multi-Config" --toolchain iar-toolchain.cmake
-- Compiling RL78l1C driver
CMake Warning at user/CMakeLists.txt:22 (message):
EncryptionW.lib EncryptionW.a need to be added
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Projects/Flow6_E4/Firmware/_builds
C:\Projects\Flow6_E4\Firmware>cmake --build _builds
[1/84] Building C object CMakeFiles\AXM_meter.dir\Debug\Flow_measurements\flow\Src\flow.c.o
FAILED: CMakeFiles/AXM_meter.dir/Debug/Flow_measurements/flow/Src/flow.c.o
C:\PROGRA~2\IARSYS~1\EMBEDD~1.0\rl78\bin\iccrl78.exe --silent "C:\Projects\Flow6_E4\Firmware\Flow measurements\flow\Src\flow.c" -DUSE_ASM=1 -DCMAKE_INTDIR=\"Debug\" -IC:\Projects\Flow6_E4\Firmware -r -D RL78L1C --code_model=far --data_model=near --calling_convention=v2 --near_const_location=rom0 --double=32 --dlib_config "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0/rl78/lib/dllrl78fnf23n.h" --core s3 --dependencies=ns CMakeFiles\AXM_meter.dir\Debug\Flow_measurements\flow\Src\flow.c.o.d -o CMakeFiles\AXM_meter.dir\Debug\Flow_measurements\flow\Src\flow.c.o
#include _DLIB_CONFIG_FILE_HEADER_NAME
^
"C:\PROGRA~2\IARSYS~1\EMBEDD~1.0\rl78\inc\c\DLib_Defaults.h",39 Fatal error[Pe1696]:
cannot open source file "C:\Program Files (x86)\IAR Systems\Embedded
Workbench 8.0/rl78/lib/dllrl78fnf23n.h"
Fatal error detected, aborting.
[2/84] Building C object CMakeFiles\AXM_meter.dir\Debug\main.c.o
FAILED: CMakeFiles/AXM_meter.dir/Debug/main.c.o
According to the fatal error message [Pe1696], it seems like the DLIB configuration header file does not exist. Could be dlrl78fnf23n.h the header your project would need?
Yes. it does need it. But it is present on system. I’m working on currently working project to be compiled on CMake. So compiling over IAR - all OK, over Cmake I get that error. Also both IAR and CMake during compilation have:
Glad you were able to get it going. Whenever using pathnames contaning spaces in CMake, enclosing the string between double quotes will process the string correctly. Portability-wise, using forward slashes in pathnames is a good idea. There is no real benefit in using strings containing backward slashes. It definetely will cause problems in Continuous Integration scenarios where the IAR Build Tools are used on Linux.