When I create a project in Eclipse (e.g. in Kinetis Design Studio with the GNU ARM Eclipse plugins), I have to specify the name of the project during creation time:
But what if I change my mind later on and want to use a different name? How to rename the project?
Outline
Renaming a project requires some knowledge about the internals how Eclipse (CDT, actually) works with project names. This post explains how the work together and how to rename a project.
Where is the Name?
First, lets have a look where the project name (in my case ‘MyProject’ is visible and used in the Eclipse Project Explorer. The following is for an ARM Cortex-M4 project (Freescale/NXP Kinetis K20 device):
All these name references are defined by the program or wizard creating that project. So they are not that much Eclipse specific, but specific to the tool creating that project.
As shown in the above example, the project name is used basically in three places:
- The project name and project folder on disk
- The output files of the linker (.elf file and linker map file)
- The names of the debugger launch configuration files
Project Name and Project Folder
The first thing to learn is where Eclipse knows the project name.
In the Eclipse Project Explorer my project shows up like this:
You might think that this name comes from the folder name on disk. Indeed, the project folder on the disk has the same name: ‘MyProject’:
There are two important files:
- .cproject contain all the project settings and compiler options (Eclipse CDT level, notice the ‘c’ in the file name for ‘C/C++’)
- .project has the information about the project (Eclipse level)
The .project file is usually filtered in the Eclipse Project view. If I open it in a text editor it has this content:
<?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>MyProject</name> <comment></comment> <projects> </projects> <buildSpec> <buildCommand> <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> <triggers>clean,full,incremental,</triggers> <arguments> </arguments> </buildCommand> <buildCommand> <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> <triggers>full,incremental,</triggers> <arguments> </arguments> </buildCommand> </buildSpec> <natures> <nature>org.eclipse.cdt.core.cnature</nature> <nature>org.eclipse.cdt.core.ccnature</nature> <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> </natures> </projectDescription>
The project name is defined by the <name> tag on line 3. So technically I *could* use a different project name than the folder name, although this is more for expert users. My recommendation is to keep the folder name on disk in sync with the project name for Eclipse.
Renaming the folder *and* the project name in that .project file can be done with the Rename menu:
With a dialog I can rename that ‘Resource’:
The above is a *Core Eclipse* (or Framework) function and unfortunately is not aware of the Eclipse CDT. So it only changes the folder name on disk and the <name> entry in the .project file. Everything else remains the same:
💡 This separation of the Eclipse framework and the CDT (or JDT) makes Eclipse very modular, but not user friendly as each part does not know much about each other. I would say that’s one of the pains of Eclipse for years, and probably will not go away in the near future :-(.
In the next steps I’m going to update the changed project name on the CDT part.
Build Output
The build output file (.elf file) is named ‘artifact’ in CDT. The setting for it is in the project properties, C/C++ Build > Settings > Build Artifact:
I can change the name to anything I want. If I want to keep the name in sync with the Eclipse project name, I can use one of the Eclipse build variables:
${ProjName}
Now my .elf artifact will be always named after the project name :-).
After such a change, I should do a Project > Clean to make sure that it will do a full build. To make a ‘clean-clean’ I even recommend to delete the output folder (‘Debug’ in my case) and then do a build.
That way, my new binary has the new name too:
What remains is the part about the debugger…
Debugger Launch Files
What I said above between the separation of the Eclipse Framework and the Eclipse CDT Build system is true as well for the Debug system in Eclipse: Changing the build output does not tell the debugger that the file name has changed :-(. So we need to do do some changes for the debugger too.
The debugger configurations are stored in other XML (text) files with .lauch extension. They are for the debug ‘lauch’ configurations.
The first obvious thing would be to rename the .launch files to match my new project name. I easily can do this again with the ‘rename’ context menu:
But this will only rename the file name, nothing else. The debugger in Eclipse CDT only scans for the .launch file name extension, and does not care about the file name itself. What it cares about what is inside the file.
Opening such a lauch file with a text editor will show something like this and there are several lines still referring to my old project name:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration type="ilg.gnuarmeclipse.debug.gdbjtag.openocd.launchConfigurationType"> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doConnectToRunning" value="false"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doContinue" value="true"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doSecondReset" value="true"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/> <booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.enableSemihosting" value="true"/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.firstResetType" value="init"/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/> <intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbServerOther" value="-f kinetis.cfg"/> <intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/> <stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU ARM OpenOCD"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> <intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/> <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/> <stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/> <booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/> <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/> <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/MyProject.elf"/> <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="MyProject"/> <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listEntry value="/MyProject"/> </listAttribute> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listEntry value="4"/> </listAttribute> <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="reserved-for-future-use"/> "/> <stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/> </launchConfiguration>
From the XML attributes I can see that it references the build artifact (PROGRAM_NAME), the project name (PROJECT_ATTR).
I could change the references to my old project name with a text editor (actually, this is what I do most of the time). But it is possible to use the graphical user interface (GUI) too.
Use the menu Run > Debug Configurations to show the launch configurations:
Because the .lauch files still reference the old project name, Eclipse does not show the launch configurations (they are filtered). Use the ‘triangle’ menu to disable that filter:
Now the hidden launch configurations are visible again:
For the configurations, use the ‘Browse…’ and ‘Search Project…’ buttons to update the project name and the artifact/elf name:
💡 Keep in mind that you only can ‘search project…’ for the .elf file you have to run a build before: you cannot browse for a file if it does not exist!
With this, I have updated my launch configurations and can debug my project again.
Refresh Policy
Oh wait! There is one (important) thing to check: I have seen some improperly renamed projects where the ‘Refresh Policy’ was not updated correctly. I recommend that you read “Eclipse Project ‘Refresh Policy’: Broken Incremental Build with External Make?” and make sure that the Refresh Policy settings are correct. Otherwise strange things could happen.
Summary
Renaming an Eclipse CDT project is not a ‘single step’ things: it requires some understanding how Eclipse works. Unfortunately the Eclipse Framework is not very well-connected to the Eclipse CDT and Debugger about the project name. So it requires not only to change the project name on the Framework level, but as well to update the CDT/Debugger settings.
I hope with this now things are easier to handle, and renaming projects is not that hard any more.
Happy renaming 🙂
Hi Erich,
great summary of the rename issues.
Artifact name:
The “Artifact name” issue has been solved in CDT (https://bugs.eclipse.org/bugs/show_bug.cgi?id=230165) so if you’re using a new Eclipse version (> 2010) new projects will automatically use the ${ProjName} variable. This will still be a problem for legacy projects and as you suggest the project name literal should be replaced with ${ProjName}.
Refresh policy:
I’ve updated your great blog about this with a comment saying its fixed in our product.
Debugger Launch Files:
SOMNIUM is currently working on a new feature to “sniff” out issues like this and offer to solve them automatically, along with other usability improvements. This will be available in a future release.
cheers john
LikeLike
Thanks a lot for this. What I am used to doing after I screw up a project by renaming it is create a new one, copy the source files into the new ones and delete the old. This understanding of how eclipse works helps a lot. Especially the use of defined variables ${ProjName}
LikeLike