Bug 311235 - building project from command line with -cleanBuild or -build switch triggers extra unnecessary clean
Summary: building project from command line with -cleanBuild or -build switch triggers...
Status: ASSIGNED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-build-managed (show other bugs)
Version: 7.0   Edit
Hardware: PC All
: P3 normal with 3 votes (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2010-04-30 15:31 EDT by Norman Yee CLA
Modified: 2020-09-04 15:20 EDT (History)
4 users (show)

See Also:


Attachments
simple C project to build (10.46 KB, application/x-zip-compressed)
2010-04-30 15:31 EDT, Norman Yee CLA
no flags Details
.bat file for building debug configuration (172 bytes, application/octet-stream)
2010-04-30 15:32 EDT, Norman Yee CLA
no flags Details
.bat file for building release configuration (176 bytes, application/octet-stream)
2010-04-30 15:33 EDT, Norman Yee CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Norman Yee CLA 2010-04-30 15:31:10 EDT
Build Identifier: 20100417-2043

When I build a C project from the command line like this:

eclipsec.exe -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -data c:\tmp -importAll C:\project\test2 -cleanBuild test2/Debug

Here is the output:

Create.
Opening 'test2'.
Refreshing '/test2'.

**** Clean-only build of configuration Debug for project test2 ****

make clean
rm -rf  ./src/test2.o  ./src/test2.d  test2.exe


**** Clean-only build of configuration Debug for project test2 ****

make clean
rm -rf  ./src/test2.o  ./src/test2.d  test2.exe


**** Build of configuration Debug for project test2 ****

make all
Building file: ../src/test2.c
Invoking: Cygwin C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test2.d" -MT"src/test2.
d" -o"src/test2.o" "../src/test2.c"
Finished building: ../src/test2.c

Building target: test2.exe
Invoking: Cygwin C Linker
gcc  -o"test2.exe"  ./src/test2.o
Finished building target: test2.exe

Note that the debug configuration is cleaned twice.  It should happen only once.

If I try building the release configuration with the -cleanBuild switch with this command line:

eclipsec.exe -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -data c:\tmp -importAll C:\eclipse_helios_cpp_2010417-2045\project\test2 -cleanBuild test2/Release

I also see the debug configuration cleaned in this case but it's unnecessary since I'm building the release configuration.


Reproducible: Always

Steps to Reproduce:
1. Unzip the attached test project to your root c: drive
2. Run the attached .bat files.  Note that the debug configuration is cleaned an extra time.
Comment 1 Norman Yee CLA 2010-04-30 15:31:47 EDT
Created attachment 166667 [details]
simple C project to build
Comment 2 Norman Yee CLA 2010-04-30 15:32:56 EDT
Created attachment 166668 [details]
.bat file for building debug configuration
Comment 3 Norman Yee CLA 2010-04-30 15:33:19 EDT
Created attachment 166669 [details]
.bat file for building release configuration
Comment 4 Norman Yee CLA 2010-04-30 15:37:45 EDT
I also see a similar problem when using the -build switch.  If you change the -cleanBuild to -build switch in the attached .bat file and then run it, it performs a clean before a build.  With the -build switch, I don't expect it to do any clean.
Comment 5 James Blackburn CLA 2010-04-30 15:38:49 EDT
It turns out the first build of a freshly imported project is a full build which cdt interprets as clean followed by full. 
Presumably if you do this with an existing workspace, it works as expected?
Comment 6 James Blackburn CLA 2010-04-30 15:42:26 EDT
We'll aim to take a look at this when we rejig CommonBuilder
Comment 7 Andrew Gvozdev CLA 2010-04-30 16:04:57 EDT
(In reply to comment #5)
> It turns out the first build of a freshly imported project is a full build which
> cdt interprets as clean followed by full.
Yeah, and the meaning of "full build" event sent by platform is opposite, that build in progress is "build after clean". It gives a builder a hint that no cleaning is needed and it is safe to discard internal build state. I don't think we can fix it easy in CDT though.
Comment 8 Norman Yee CLA 2010-04-30 16:12:11 EDT
> It turns out the first build of a freshly imported project is a full build
> which cdt interprets as clean followed by full. 
> Presumably if you do this with an existing workspace, it works as expected?

It depends on the last built configuration.  If I do a -cleanBuild of the release configuration followed by a -cleanBuild of the debug configuration, I see the debug configuration cleaned twice.  Changing configurations between builds seems to trigger an extra clean.

Also, if I do a -cleanBuild of the release configuration followed by another -cleanBuild of the release configuration, I see the debug configuration cleaned.  It should be cleaning the release configuration.
Comment 9 James Blackburn CLA 2010-04-30 16:20:26 EDT
(In reply to comment #7)
> Yeah, and the meaning of "full build" event sent by platform is opposite, that
> build in progress is "build after clean". It gives a builder a hint that no
> cleaning is needed and it is safe to discard internal build state. I don't
> think we can fix it easy in CDT though.

That's not quite right. A FULL build is one where core.resources doesn't have a delta for the builder. It can also be requested by API callers (although there's no UI for this.

 - For external builders FULL should be treated the same as INCREMENTAL. 
 - For managed, we need to regenerate the Makefile and run make (no clean).  
 - For internal recompile all files (or check timestamps like make would if we want to be cleverer).
Comment 10 James Blackburn CLA 2010-04-30 16:26:08 EDT
Hmm HeadlessBuilder seems to always do FULL_BUILD. That's just wrong as we'll never get incremental with the current behaviour.

I'm reluctant to change this before 7 though given the state of common builder.
Comment 11 Andrew Gvozdev CLA 2010-04-30 16:56:10 EDT
(In reply to comment #9)
> (In reply to comment #7)
> > Yeah, and the meaning of "full build" event sent by platform is opposite, that
> > build in progress is "build after clean". It gives a builder a hint that no
> > cleaning is needed and it is safe to discard internal build state. I don't
> > think we can fix it easy in CDT though.
> 
> That's not quite right. A FULL build is one where core.resources doesn't have a
> delta for the builder. It can also be requested by API callers (although there's
> no UI for this.
James, could you comment on bug 70554 comment#13? In particular, this quote from John:
> FULL_BUILD in Eclipse 3.0 really means "the first build after a "clean".
> Thus, if you are adding a free "clean" in the implementation of FULL_BUILD,
> you will always get the duplication of cleaning.
Comment 12 James Blackburn CLA 2010-04-30 17:05:04 EDT
(In reply to comment #11)
> > That's not quite right. A FULL build is one where core.resources doesn't have a
> > delta for the builder. It can also be requested by API callers (although there's
> > no UI for this.
> James, could you comment on bug 70554 comment#13? In particular, this quote
> from John:
> > FULL_BUILD in Eclipse 3.0 really means "the first build after a "clean".
> > Thus, if you are adding a free "clean" in the implementation of FULL_BUILD,
> > you will always get the duplication of cleaning.

Yep, that's right. 
A FULL_BUILD is one where there's no build state from the platform (i.e. delta since the last build: getDelta() == NULL). That's all it means.
So any builder that relies on the platform delta would need to build everything from scratch. If it uses an external mechanism (like make) then it can just do an incremental build.

What the platform actually does:
  - If an API user calls build(... FULL_BUILD...) it throws away any existing delta tree.
  - If the tree is missing, for whatever reason, an INCREMENTAL_BUILD is turned into a FULL_BUILD.

The easiest way to think of it is that a  a FULL_BUILD is an INCREMENTAL_BUILD build where getDelta() == null, take a look at BuildManager.basicBuild, it's relatively straightforward.

Does that make sense?
Comment 13 Andrew Gvozdev CLA 2010-05-04 22:46:42 EDT
OK, let me rephrase it this way to fit my cdt-shaped brains. When a build is initiated, the platform will send a build request to builders. It will send INCREMENTAL_BUILD when delta is available and FULL_BUILD when it does not know what the delta is. It is up to the builders how to do their builds. FULL_BUILD means nothing but a generic build request. If a builder can make use of the delta on INCREMENTAL_BUILD, it should. If a builder received FULL_BUILD but knows well which pieces have been built and which not it should proceed to build those missing. There also can be context passed in arguments and builder can decide to build its own thing considering the context (like specific CDT build configurations). "FULL_BUILD" wording and JavaDoc on it are artifacts from the old good times Java incremental builder was initially developed. All the cleaning should be done by builder on CLEAN_BUILD.
Is that about right?
Comment 14 James Blackburn CLA 2010-05-05 04:05:38 EDT
(In reply to comment #13)
> Is that about right?

Yes, spot on. I agree the JavaDoc on FULL_BUILD is misleading... If a user wants a build to to be clean they must use the 'new' CLEAN_BUILD type, otherwise the it's up to them how best to incrementally build.
Comment 15 James Blackburn CLA 2010-05-05 04:10:51 EDT
(In reply to comment #14)
> up to them how best to incrementally build.

It's up to the *builder* how best to incrementally build.
Comment 16 Chansol Kim CLA 2014-09-24 00:17:43 EDT
I am wondering whether this has been fixed?

My problem is:
- Checkout once
- Import once
- -cleanBuild test1/Debug
- -cleanBuild test2/Release  (<-- here Debug built binaries gets cleaned)

The reason I am doing clean build separately is if there is a link error in one of the configuration headless build does not seem to report the error, when all is specified.

The work around I am using is to -cleanBuild of the configuration that gets cleaned.

Or, could any one shed light on a better workaround?
Comment 17 Chansol Kim CLA 2014-09-24 00:18:03 EDT
I am wondering whether this has been fixed?

My problem is:
- Checkout once
- Import once
- -cleanBuild test1/Debug
- -cleanBuild test2/Release  (<-- here Debug built binaries gets cleaned)

The reason I am doing clean build separately is if there is a link error in one of the configuration headless build does not seem to report the error, when all is specified.

The work around I am using is to -cleanBuild of the configuration that gets cleaned.

Or, could any one shed light on a better workaround?