MantisBT - CMake
View Issue Details
0014653CMakeModulespublic2013-12-16 08:572014-06-02 08:37
John Theos 
 
normalminoralways
closedsuspended 
GenericWindowsXP
CMake 2.8.12 
 
0014653: Looking at add support for Cosmic
I'm looking at developing modules for the Cosmic HCS12 embedded compiler suite. This product is widely used in automotive and an evaluation version of the compiler is available here http://www.cosmic-software.com/hc12.php [^] (evaluaation includes all the documentation).

I have the C compiler working with CMake but it's not ideal in the way it operates (it isn't autodetected). Additionally the librarian - used in building static modules - isn't finding the files, which no doubt has a lot to do with the compiler puts said files.

Attached are the files I have added/modified in the Modules/Compiler section of CMake.
Notes:
- The object files created by the compiler have the bytes 0xCC 0x01 0x05 at the beginning of the object file (compiler identification?)
- The linker requires an .lkf file to produce an H12 file (binary)
No tags attached.
zip CosmicTest.zip.zip (12,731) 2013-12-16 08:57
https://public.kitware.com/Bug/file/5019/CosmicTest.zip.zip
Issue History
2013-12-16 08:57John TheosNew Issue
2013-12-16 08:57John TheosFile Added: CosmicTest.zip.zip
2013-12-18 11:27Brad KingNote Added: 0034789
2013-12-18 12:03John TheosNote Added: 0034792
2013-12-18 12:04John TheosNote Edited: 0034792bug_revision_view_page.php?bugnote_id=34792#r1337
2013-12-18 15:52Brad KingNote Added: 0034807
2013-12-18 16:32John TheosNote Added: 0034811
2013-12-18 16:50Brad KingNote Added: 0034812
2013-12-18 18:52John TheosNote Added: 0034813
2013-12-18 19:38John TheosNote Edited: 0034813bug_revision_view_page.php?bugnote_id=34813#r1341
2013-12-19 09:35Brad KingNote Added: 0034815
2013-12-19 09:54John TheosNote Added: 0034817
2013-12-19 09:55John TheosNote Edited: 0034817bug_revision_view_page.php?bugnote_id=34817#r1343
2013-12-19 14:04Brad KingNote Added: 0034826
2013-12-19 18:44John TheosNote Added: 0034832
2013-12-20 09:14Brad KingNote Added: 0034836
2013-12-20 10:35John TheosNote Added: 0034837
2013-12-20 11:07Brad KingNote Added: 0034838
2013-12-20 11:19John TheosNote Added: 0034840
2013-12-20 11:57Brad KingNote Added: 0034843
2013-12-20 15:11John TheosNote Added: 0034844
2013-12-20 15:19Brad KingNote Added: 0034845
2013-12-21 10:07John TheosNote Added: 0034847
2013-12-23 10:40Brad KingStatusnew => resolved
2013-12-23 10:40Brad KingResolutionopen => suspended
2014-06-02 08:37Robert MaynardNote Added: 0036063
2014-06-02 08:37Robert MaynardStatusresolved => closed

Notes
(0034789)
Brad King   
2013-12-18 11:27   
Does the compiler identify itself with a preprocessor macro? It should be added to "Modules/CMakeCCompilerId.c.in".
(0034792)
John Theos   
2013-12-18 12:03   
(edited on: 2013-12-18 12:04)
The compiler does indeed identify itself by providing the version number. So it does something the line of:

-d"__VERS__=\"4.5i\""

so I have added the following in CMakeCCompilerId.c.in

--------------------------------------------------------------------
/* IAR Systems compiler for embedded systems.
   http://www.iar.com [^] */
#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"

#elif defined(__VERS__)
#define COMPILER_ID "COSMIC"
--------------------------------------------------------------------

but that doesn't seem to help in identifying the compiler.


I look at the error log being generated and I get this:
--------------------------------------------------------------------
Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: J:/S12RamCode_boot/cosmic/cx6812.exe
Build flags:
Id flags:

The output was:
1
can't open file ot/cosmic/cx6812


Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: J:/S12RamCode_boot/cosmic/cx6812.exe
Build flags:
Id flags: -c

The output was:
1
j:/s12ramcode_boot/cosmic/cx6812: unknown option -c


Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: J:/S12RamCode_boot/cosmic/cx6812.exe
Build flags:
Id flags: -Aa

The output was:
1
j:/s12ramcode_boot/cosmic/cx6812: unknown option -Aa


Checking whether the C compiler is IAR using "" did not match "IAR .+ Compiler":
COSMIC Software 68HC12 Compiler Driver V4.5i
usage: j:/s12ramcode_boot/cosmic/cx6812 [options] files
    -a*> assembler options
    -ce* path for error files
    -cl* path for listing files
    -co* path for object files
    -d*> define symbol
    -ex prefix executables
    -e create error file
    -f* configuration file
    -g*> code generator options
    -i*> path for include
    -l create listing
    -no do not use optimizer
    -o*> optimizer options
    -p*> parser options
    -sm create only dependencies
    -sp create only preprocessor file
    -s create only assembler file
    -t* path for temporary files
    -v verbose
    -x do not execute
    +*> select compiler option
--------------------------------------------------------------------

(0034807)
Brad King   
2013-12-18 15:52   
The compiler id runs "$CC CMakeCCompilerId.c" and searches for output binaries that contain certain string literals produced by the preprocessor and compiler. Most compilers produce something with that simple command. We also try a few variations like "$CC -c CMakeCCompilerId.c". It looks like this compiler's default output file name is "ot/cosmic/cx6812" and of course the "ot/cosmic" directory does not exist in the compiler id test directory.

Look in CMakeFiles/<cmake-version>/CompilerIdC for the CMakeCCompilerId.c source. Set that as your current working directory and try finding a way to invoke the compiler that produces something without error. Does using an option like "-po." help?
(0034811)
John Theos   
2013-12-18 16:32   
Brad, tried what you asked for and here are the results (with the verbose option set - that is the only option I'm setting in this case.).

----------------------------------------------------------------------------
cx6812 -v CMakeCCompilerId.c
CMakeCCompilerId.c:
        "cp6812" -o "\s2jc.cx1" -u -d"__VERS__=\"V4.5i\"" "CMakeCCompilerId.c"
        "cg6812" -o "\s2jc.cx2" "\s2jc.cx1"
        "co6812" -o "\s2jc.cx1" "\s2jc.cx2"
        "ca6812" -o "CMakeCCompilerId.o" "\s2jc.cx1"
----------------------------------------------------------------------------

Because no output file was specified (or no target directory) the object file was created in the same location.


----------------------------------------------------------------------------
12/18/2013 04:25 PM <DIR> .
12/18/2013 04:25 PM <DIR> ..
12/14/2013 09:06 PM 12,379 CMakeCCompilerId.c
12/18/2013 04:25 PM 349 CMakeCCompilerId.o
12/14/2013 09:06 PM 9,728 CompilerIdC.exe
12/14/2013 09:06 PM 1,363 CompilerIdC.vcproj
12/14/2013 09:06 PM <DIR> Debug
----------------------------------------------------------------------------

Is there any way to debug the calls that are being performed while we are trying to determine the compiler? Specifically if I can message() out the compiler tests I can see why/how they are being malformed.
(0034812)
Brad King   
2013-12-18 16:50   
Re 0014653:0034811: See Modules/CMakeDetermineCompilerId.cmake in the CMAKE_DETERMINE_COMPILER_ID_BUILD for the execute_process call used to launch the compiler. You could add a message just before that.
(0034813)
John Theos   
2013-12-18 18:52   
(edited on: 2013-12-18 19:38)
Here's an interesting situation.

I wrote a test script to call the compiler and verify that it's doing what I expect it to. The code looks like this:

-----------------------------------------------------------------------
cmake_minimum_required(VERSION 2.8)


SET(COMPILER "J:/S12RamCode_boot/cosmic/cx6812.exe")
SET(COMPILER_ID_FLAGS_LIST "-v")
SET(src "CMakeCCompilerId.c")

execute_process(
    COMMAND ${COMPILER}
            ${COMPILER_ID_ARG1}
            ${COMPILER_ID_FLAGS_LIST}
            ${testflags}
            "${src}"
)

-----------------------------------------------------------------------

When I run this script using the -P option I get the following output:

can't open file ot/cosmic/cx6812


If however I change the compiler path to:
SET(COMPILER "J:\\S12RamCode_boot\\cosmic\\cx6812.exe")

I get the following output:

cmake -P test.cmake
CMakeCCompilerId.c:
        "cp6812" -o "\s2tc.cx1" -u -d"__VERS__=\"V4.5i\"" "CMakeCCompilerId.c"
        "cg6812" -o "\s2tc.cx2" "\s2tc.cx1"
        "co6812" -o "\s2tc.cx1" "\s2tc.cx2"
        "ca6812" -o "CMakeCCompilerId.o" "\s2tc.cx1"

and all is good.

So I created a new directory tree named test and re-ran a similar test using the following settings:
SET(COMPILER "J:/test/cosmic/cx6812.exe")
SET(COMPILER_ID_FLAGS_LIST "-v")
SET(src "CMakeCCompilerId.c")

and it gave me an output of:
can't open file x6812

Any thoughts on what is going on?

EDIT:

It appears that sticking the drive letter in the front is causing the issue. If I set the compiler this way:
SET (COMPILER "../test/cosmic/cx6812.exe") it runs just fine.
but this:
SET (COMPILER "J:/test/cosmic/cx6812.exe") which is essentially the same thing ends up truncating the J:/test/cosmic/c portion of call.

(0034815)
Brad King   
2013-12-19 09:35   
Windows processes have a single-string command line as passed to the system CreateProcess call. It is up to each launched process to parse its own command line. Most programs typically declare main() and get argument parsing from the MSC runtime:

 http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft%28v=vs.85%29.aspx [^]

However, this compiler appears to do its own command-line parsing and is somehow confused by the forward slashes in argv[0].

In CMakeDetermineCompilerId try replacing

  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" ...)

with

  string(REPLACE "/" "\\" _compiler "${CMAKE_${lang}_COMPILER}")
  execute_process(COMMAND "${_compiler}" ...)

locally to see if it works around this problem. Of course if this patch goes upstream it will have to be conditional on being a Windows path with a drive letter.
(0034817)
John Theos   
2013-12-19 09:54   
(edited on: 2013-12-19 09:55)
That fixed the issue with the compiler being found and moves us a bit further.

See the error list below:
------------------------------------------------------------------------
Run Build Command:J:/S12RamCode_boot/cosmic/make.exe "cmTryCompileExec3628536407/fast"
/j/S12RamCode_boot/cosmic/make -f CMakeFiles/cmTryCompileExec3628536407.dir/build.make CMakeFiles/cmTryCompileExec3628536407.dir/build
make[1]: Entering directory `/j/S12RamCode_boot/binary_cosmic/CMakeFiles/CMakeTmp'
"/C/Program Files/CMake 2.8/bin/cmake.exe" -E cmake_progress_report /J/S12RamCode_boot/binary_cosmic/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec3628536407.dir/testCCompiler.c.o
/J/S12RamCode_boot/cosmic/cx6812.exe -v /J/S12RamCode_boot/binary_cosmic/CMakeFiles/CMakeTmp/testCCompiler.c
j:/S12RamCode_boot/binary_cosmic/CMakeFiles/CMakeTmp/testCCompiler.c:
    "cp6812" -o "\s17c.cx1" -u -d"__VERS__=\"V4.5i\"" "j:/S12RamCode_boot/binary_cosmic/CMakeFiles/CMakeTmp/testCCompiler.c"
    "cg6812" -o "\s17c.cx2" "\s17c.cx1"
    "co6812" -o "\s17c.cx1" "\s17c.cx2"
    "ca6812" -o "j:/S12RamCode_boot/binary_cosmic/CMakeFiles/CMakeTmp/testCCompiler.o" "\s17c.cx1"
Linking C executable cmTryCompileExec3628536407
/J/S12RamCode_boot/cosmic/clnk.exe -e errors.txt -o cmTryCompileExec3628536407.h12 -m cmTryCompileExec3628536407.map
#error clnk :1 missing command file
---------------------------------------------------------------------------

Obviously this compiler will not build .exe files for Windows (it will link H12 files if the linker is provided with an .lkf file). So without actually linking an .exe how do we verify that this compiler is working?

Is there a way to peer into the .o file and confirm that this compiler did what it was supposed to (the first three bytes are a marker)

Really appreciate the assistance and everything I'm learning wrt CMake.

(0034826)
Brad King   
2013-12-19 14:04   
If it is cross-compiling, read this page:

 http://www.cmake.org/Wiki/CMake_Cross_Compiling [^]

The toolchain file can tell CMake not to run the test for working compiler.
(0034832)
John Theos   
2013-12-19 18:44   
So I suppose the way I had it set up was working then - I wasn't sure if using the CMAKE_FORCE_C_COMPILER() directive was the way to go.
(0034836)
Brad King   
2013-12-20 09:14   
Re 0014653:0034832: The "force" feature is specifically meant for cases like this where it is problematic to get the toolchain to work without special settings in the project (which the CMake-generated test project won't have).

You can at least use it to get things going and see if there are any other problems later. Once it is all working then you can go back and try to get the automatic compiler detection working.
(0034837)
John Theos   
2013-12-20 10:35   
Sounds good...so my initial question then comes back to light.

I'm trying to get the librarian to process the .o files and put them all in a library. I need to somehow tell the librarian (clib in this case) where to find the .o files as I have the compiler dropping them in the CMAKE_BINARY_DIRECTORY, but can't seem to figure out the syntax.


Here's what the call look likes in the Cosmic-C.cmake file:

SET(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> -v -c <TARGET> <OBJECTS>")

What I can't figure out is the syntax to add/force the CMAKE_BINARY_DIRECTORY as part of the definition. Is it even possible?
(0034838)
Brad King   
2013-12-20 11:07   
Re 0014653:0034837: CMake computes object file locations in its C++-implemented logic and provides the <OBJECT> placeholder for use in CMAKE_C_COMPILE_OBJECT. The <OBJECTS> placeholder in the archiver and linker rule variables assumes that <OBJECT> was honored.
(0034840)
John Theos   
2013-12-20 11:19   
But <OBJECTS> seems to be a relative path rather than full path to the object. I was trying it earlier today and noticed that <OBJECTS> would result is something like CMakeFiles/sample.dir/test.o rather than /myproject/binary/CMakeFiles/sample.dir/test.o so depending where/how the librarian is launched it won't be able to find the object files.

Am I just missing something?
(0034843)
Brad King   
2013-12-20 11:57   
Re 0014653:0034840: The <OBJECTS> placeholder assumes that the rule will be launched with the current working directory set to the build tree directory corresponding to the source tree directory whose CMakeLists.txt invoked the add_library command. These directories are set by the generated build system files.
(0034844)
John Theos   
2013-12-20 15:11   
So there's no way to get <OBJECTS> to use the full path rather than the relative path?
(0034845)
Brad King   
2013-12-20 15:19   
Re 0014653:0034844: Correct. Why can't your CMAKE_C_COMPILE_OBJECT rule honor <OBJECT>?

Using CMAKE_BINARY_DIRECTORY will cause conflicts if the same source is built in multiple logical targets. That's one of the reasons CMake puts them in "CMakeFiles/<target>.dir".
(0034847)
John Theos   
2013-12-21 10:07   
I have documented the issue with the compiler and how I got around it here: http://stackoverflow.com/questions/20693902/cmake-and-librarian-operation/20720297#20720297 [^]

Having addressed the compiler issue, the librarian now works. Of course the issue is that one can't really add this toolchain to CMake easily unless you modify/add the wrapper to the compiler suite which is a bit of a shame.

Based on the above however, I think this issue can be closed at this time with no further action.
(0036063)
Robert Maynard   
2014-06-02 08:37   
Closing resolved issues that have not been updated in more than 4 months.