Problem Overview
When following the official SIMATIC IOT2000 - Getting Started procedure with Eclipse IDE for C/C++ Developers Neon.2 (4.6.2) and the Siemens-provided Yocto/Poky SDK, the incremental build completes without errors and reports Build Finished (took 6s.565ms), yet the release folder contains only the intermediate object file example.o. The expected final executable HelloWorld is never produced, so the SCP/SFTP transfer dialog described in the Getting Started manual step 4 cannot resolve a valid host path and the OK button stays disabled. This behavior is reproducible on Windows 10 and on Linux guest VMs using the same workspace.
The problem is not in the toolchain itself; the cross-compiler i586-poky-linux-g++ and the --sysroot path resolve correctly. The defect is in the Eclipse CDT build configuration that the Getting Started wizard generates: the compile command retains the GCC stop-after-compile flag in both the global tool settings and the per-file command pattern, and the linker step is configured with the wrong artifact extension.
example.o. SCP dialog host path resolves to example.o instead of HelloWorld. OK button greyed out when typing the path manually because the file does not exist.
Affected Environment and SDK Layout
The error reproduces against the canonical Siemens IOT2000 SDK tree. The exact paths used in the failing build are listed below; if your installation differs only by drive letter or username, the same remediation applies.
| Component | Verified Value |
|---|---|
| Eclipse package | Eclipse IDE for C/C++ Developers, Neon.2 Release (4.6.2), Build id 20161208-0600 |
| Cross-compiler | i586-poky-linux-g++ |
| Target architecture | -m32 -march=i586 |
| SDK root | C:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux |
| C++ headers |
usr/include/c++/5.3.0 with target tuple i586-poky-linux
|
| mraa library |
usr/include/mraa, linked with -lmraa
|
| upm library | usr/include/upm |
| Source file | ..\example.cpp |
| Object file | example.o |
| Expected output |
HelloWorld (no extension) |
The SDK is generated by the Yocto Project and provides a self-contained sysroot with the GNU C++ 5.3.0 runtime, the libmraa userspace GPIO/I2C/SPI library and the libupm sensor repository. Reference the official Siemens Industry Online Support portal for the IOT2000 Getting Started entry ID 109741705 and the matching SDK image.
Build Console Analysis
The console output observed during the failing build is reproduced below, normalized for line wrapping. The exact sequence is critical for diagnosis.
20:23:11 **** Incremental Build of configuration IOT2000 Release for project HelloWorld ****
Info: Internal Builder is used for build
i586-poky-linux-g++ "-IC:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux\usr\include"
"-IC:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux\usr\include\c++\5.3.0"
"-IC:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux\usr\include\c++\5.3.0\i586-poky-linux"
"-IC:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux\usr\include\mraa"
"-IC:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux\usr\include\upm"
-O0 -g3 -Wall -c -fmessage-length=0 -m32 -march=i586 -c -ffunction-sections -fdata-sections
"--sysroot=C:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux"
-o example.o "..\example.cpp"
i586-poky-linux-g++ -lmraa -fno-use-linker-plugin
"--sysroot=C:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux"
-o HelloWorld example.o
20:23:17 Build Finished (took 6s.565ms)
Notice that the compile invocation contains the flag -c twice and a second -c on the same line. Although GCC tolerates duplicate -c, the second occurrence is a strong indicator that the Getting Started wizard's per-file command pattern was edited and the global C/C++ Build > Settings > GCC C++ Compiler command pattern was left at its default ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${INPUTS}, which already appends -c. Meanwhile, the linker invocation appears to run correctly. The actual root cause lies in a different setting covered in the next section.
Root Cause: Why example.o Is Produced Without HelloWorld
Three configuration defects, individually or combined, prevent Eclipse CDT's Internal Builder from generating the final executable:
-
Wrong artifact extension in the linker step. Project Properties > C/C++ Build > Settings > GCC C++ Linker > Output file. The Getting Started template leaves
${OUTPUT_PREFIX}${OUTPUT}in the command pattern but sets the artifact extension tooinstead of leaving it blank (or specifying an empty extension). The Internal Builder therefore writesHelloWorld.o, which then collides with the compile artifact name and is either overwritten or skipped. -
Per-file compile command pattern overrides the global pattern. Project Properties > C/C++ Build > Settings > GCC C++ Compiler > Command line pattern. If a custom pattern that strips
-cis inserted here, the Internal Builder treats every translation unit as a link candidate and never finalizes an executable. - Missing linker step on the build invocation. Project Properties > C/C++ Build > Tool Chain Editor. The "Current toolchain" must be "Cross GCC". If the wizard accidentally selected "No Toolchain" the link step is suppressed entirely.
example.o remains in the folder: The C++ compile step writes example.o from example.cpp. When the linker step fails silently (because the artifact extension is o and it tries to overwrite the object file with itself, or because the command pattern is missing -o ${OUTPUT}), the object file is the only persistent artifact. Project -> Clean -> Clean all removes it, but the next incremental build reproduces the same problem because the configuration is unchanged.
Diagnosis Procedure
Confirm each defect before applying the fix:
- In Eclipse, right-click the
HelloWorldproject and select Properties. - Navigate to C/C++ Build > Tool Chain Editor. Confirm Current toolchain is
Cross GCCand Current builder isGnu Make BuilderorCDT Internal Builderwith the toolchain fields populated. - Open C/C++ Build > Settings > Cross Settings. Confirm Prefix is
i586-poky-linux-and Path points to the Yocto SDK environment script directory (typicallyC:\00_Data\SDK_Destination_Folder\sysroots\i586-nlp-32-poky-linux\usr\bin\..\..\environment-setup-i586-nlp-32-poky-linuxon Windows). - Open C/C++ Build > Settings > GCC C++ Compiler. Inspect the Command line pattern field. It must read exactly:
${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${INPUTS} - Open C/C++ Build > Settings > GCC C++ Linker. Inspect Command line pattern (should be
${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${INPUTS}) and Output file (should be${OUTPUT_PREFIX}${OUTPUT}with extension blank). - Click Project > Clean..., enable Clean all projects, click OK, then Project > Build Project. Repeat the console inspection.
Solution A: Correct the Cross-Compiler Command Pattern
The duplicate -c in the console output shows that an additional flag string was injected into the command pattern. Reset it:
- Project Properties > C/C++ Build > Settings > Cross Settings > Command: set to
g++. - Project Properties > C/C++ Build > Settings > GCC C++ Compiler: set the Command line pattern to:
${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${INPUTS} - Project Properties > C/C++ Build > Settings > GCC C++ Compiler > Miscellaneous: clear the Other flags field if it contains stray
-c,-shared, or-fPICentries not required by the HelloWorld example. - Click Apply and Close.
Solution B: Configure Linker Output Artifact
This is the most common fix for the symptom where only example.o remains in the release folder.
- Project Properties > C/C++ Build > Settings > GCC C++ Linker.
- In Expert settings, click Output file. Replace the existing value with:
${OUTPUT_PREFIX}${OUTPUT} - Confirm the Command line pattern field reads:
${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${INPUTS} - Still under GCC C++ Linker > Libraries, add
mraato Libraries (-l). The Getting Started template sets this via-lmraa; if the linker output command line shows no-ltokens, add the library here instead of via Other flags. - Open the GCC C++ Linker > Miscellaneous subnode and ensure the Linker flags field contains
-fno-use-linker-pluginonly if required by the Yocto toolchain version in use; remove duplicate--sysrootentries.
Solution C: Force Full Rebuild After Clean
If Solutions A and B are in place but the executable still does not appear, force the Internal Builder to relink by removing every intermediate artifact:
- Close Eclipse.
- In Windows Explorer, navigate to the workspace folder (typically
C:\Users\<user>\workspace\HelloWorld). - Delete the entire
IOT2000 Releasesubfolder and any siblingIOT2000 Debugfolder. - Reopen Eclipse, right-click the project, and select Project > Build Project (do not use Build All; on Neon.2 CDT this can re-trigger incremental caching).
- Inspect the console. The expected sequence is now exactly two lines: one compile invocation, one link invocation.
Deploying HelloWorld to the SIMATIC IOT2000
Once the release folder contains the executable HelloWorld, proceed with the deployment step from the Getting Started manual:
- In the Eclipse Remote Systems Explorer (RSE) perspective, expand the SIMATIC IOT2000 node and connect via SSH.
- Right-click My Home (or the target folder such as
/home/iot/) and select Upload Files.... - In the host field, browse to
C:\Users\<user>\workspace\HelloWorld\IOT2000 Release\HelloWorldand confirm the OK button activates. - On the target, open a serial console or SSH session and execute:
chmod +x /home/iot/HelloWorld
/home/iot/HelloWorld
noexec on /tmp. Do not upload the executable there; the binary will load but will refuse to execute with Permission denied. Use /home/iot or /opt instead.
Verification Checklist
| Step | Expected Result |
|---|---|
| Release folder contents |
example.o AND HelloWorld present, no other ELF artifacts. |
| Console build duration | Single compile line, single link line, total time < 15 s on a modern workstation. |
| Linker command line | Contains exactly one -o token followed by HelloWorld (no extension). |
| Upload dialog | OK button enables immediately when the executable path is selected. |
| SSH execution | Program prints Hello, world! (or equivalent output of example.cpp) and returns exit code 0. |
| Clean rebuild | After Project -> Clean -> Clean all the next Build Project reproduces both artifacts in < 15 s. |
Troubleshooting Matrix
| Observed Symptom | Likely Cause | Corrective Action |
|---|---|---|
Only example.o in release folder |
Linker output extension set to o
|
Solution B: blank the extension field |
Compile command line shows two -c flags |
Custom command pattern injected | Solution A: restore default pattern |
| Build completes in < 1 s with no compile output | Toolchain set to No Toolchain | Project Properties > Tool Chain Editor > select Cross GCC |
Linker error: cannot find -lmraa
|
SDK sysroot not in linker search path | Add -L${SYSROOT}/usr/lib to linker flags |
| Upload OK button greyed out | Path typed manually instead of browsed, and file does not exist | Browse to IOT2000 Release, confirm HelloWorld (no extension) is listed |
| Permission denied on target | Executable copied to /tmp or not chmodded |
Move to /home/iot and run chmod +x
|
| GLIBC version mismatch on target | SDK glibc newer than rootfs glibc | Match SDK image to firmware version per Siemens KB 109755230 |
Linker produces HelloWorld.o
|
Output extension field still contains o
|
Edit Output file to ${OUTPUT_PREFIX}${OUTPUT} with empty extension |
FAQ
Why does the SIMATIC IOT2000 Eclipse build create example.o but not HelloWorld?
Eclipse CDT's Internal Builder produces the final executable in the linker step. If the linker output extension is incorrectly set to o, or if the toolchain is set to No Toolchain, the build stops after compilation and only the intermediate object file example.o remains. Verify Project Properties > C/C++ Build > Settings > GCC C++ Linker > Output file = ${OUTPUT_PREFIX}${OUTPUT} with an empty extension.
What does the duplicate -c flag in the build command mean?
A second -c on the GCC command line indicates the command pattern in Project Properties > C/C++ Build > Settings > GCC C++ Compiler was edited to include stop-after-compile flags while the default pattern already provides them. Reset the Command line pattern to ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${INPUTS} and clear any stray flags in the Miscellaneous > Other flags field.
How do I deploy the HelloWorld binary from Eclipse to the SIMATIC IOT2000?
Use the Remote Systems Explorer perspective, connect to the IOT2000 over SSH, right-click the target folder (/home/iot), and select Upload Files. Browse the host path to <workspace>\HelloWorld\IOT2000 Release\HelloWorld, not example.o. On the target, run chmod +x /home/iot/HelloWorld followed by /home/iot/HelloWorld.
Which Eclipse version does the SIMATIC IOT2000 Getting Started manual target?
The published Getting Started entry on Siemens Industry Online Support targets Eclipse IDE for C/C++ Developers Neon.2 (4.6.2), Build id 20161208-0600, paired with the Yocto/Poky i586 SDK containing GCC 5.3.0 and libmraa 1.0.x. Newer Eclipse versions require manually remapping the toolchain paths and tool IDs because the CDT schema changed in Oxygen and later releases.
Why does Project > Clean all followed by Build all not regenerate HelloWorld?
Clean only removes generated artifacts; it does not reset the toolchain configuration. If the linker output extension is still o, the next build reproduces the same defect. After fixing Solutions A and B, perform a manual delete of the IOT2000 Release folder before rebuilding to force the Internal Builder to regenerate the executable.