News:

When registered with our forums, feel free to send a "here I am" post here to differ human beings from SPAM bots.

Main Menu

Deleting the static library before generating it?

Started by oBFusCATed, September 26, 2012, 12:30:53 PM

Previous topic - Next topic

oBFusCATed

Here is the description of the problem:
Currently I have two build systems working on the same files - one custom and the one inside C::B.
The custom build system generates .obj files and C::B generates .o files.
This is causes problems, when I first build the project with the custom system and then change something in a source file and hit Build in C::B.
The problem is that C::B doesn't delete the .a file but just adds (replaces files if the names match) to the archive.
So the result of the build inside C::B is that I'm getting an .a file which contains two files:
  myfile.obj (the old file)
  myfile.o (the new file)
and when this archive is used for linking the old file is used again and the new file is ignored, which is not correct.

Is it possible to make the build system inside C::B to delete the .a file?
I've looked at the options of ar, but there is no option to wipe the file before creating it.

If it is possible, what should be modified?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Freem

Is not it possible to use pre-build instructions to remove it?

oBFusCATed

Quote from: Freem on September 27, 2012, 01:50:10 PM
Is not it possible to use pre-build instructions to remove it?
No because it won't be automatic/automagic/just works.
This is not a topic how to workaround the problem, but about how to fix it.  :P
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Freem


MortenMacFly

I would say its an issue with the archivar. Check, if GCC's "ar" has something like an option for that. How would you do that on the command line?
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

oBFusCATed

Quote from: MortenMacFly on September 27, 2012, 05:40:51 PM
I would say its an issue with the archivar. Check, if GCC's "ar" has something like an option for that. How would you do that on the command line?
No option I've checked as I've stated in the first post.
The non-cb build system just deletes all files, I guess it has the same problem,
but I've not checked if there are rm rules added before the ar rules in the generated Makefiles.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Alpha

Quote from: oBFusCATed on September 26, 2012, 12:30:53 PM
Is it possible to make the build system inside C::B to delete the .a file?
I think I can add this functionality.  Should deleting the archive (just before recreation) be default behavior, or should it be controlled by a switch?

oBFusCATed

(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Alpha

Try this patch.  (I am not sure what the equivalent Linux command is to only try to delete a file if it exists, so someone else will have to change that.)

Index: src/plugins/compilergcc/directcommands.cpp
===================================================================
--- src/plugins/compilergcc/directcommands.cpp  (revision 8417)
+++ src/plugins/compilergcc/directcommands.cpp  (working copy)
@@ -736,6 +736,13 @@
         break;
     }
     wxString compilerCmd = compiler->GetCommand(ct);
+    if (ct == ctLinkStaticCmd) // static libraries should be deleted before recreation
+    {
+        if (platform::windows)
+            compilerCmd.Prepend(wxT("cmd /c if exist $static_output del $static_output\n"));
+        else
+            compilerCmd.Prepend(wxT("rm $static_output\n"));
+    }
     compiler->GenerateCommandLine(compilerCmd,
                                   target,
                                   0,

MortenMacFly

Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

oBFusCATed

Because the delete command won't be executed just before the ar command, probably.
But does the direct commands support executing two commands put in a single command and separated by \n?
On *nix you can use &&, maybe.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Alpha

Quote from: MortenMacFly on September 29, 2012, 05:39:00 AM
Why don't you simply use wxRemoveFile?
Quote from: oBFusCATed on September 29, 2012, 09:31:01 AM
Because the delete command won't be executed just before the ar command, probably.
Yes; so, for example, if the build is aborted, the previous library will not have been prematurely deleted.

Quote from: oBFusCATed on September 29, 2012, 09:31:01 AM
But does the direct commands support executing two commands put in a single command and separated by \n?
Yes; directcommands.cpp line 79:

void DirectCommands::AddCommandsToArray(const wxString& cmds, wxArrayString& array, bool isWaitCmd, bool isLinkCmd)
{
    wxString cmd = cmds;
    while (!cmd.IsEmpty())
    {
        int idx = cmd.Find(_T("\n"));
        wxString cmdpart = idx != -1 ? cmd.Left(idx) : cmd;
        cmdpart.Trim(false);
        cmdpart.Trim(true);
        if (!cmdpart.IsEmpty())
        {
            if (isWaitCmd)
                array.Add(wxString(COMPILER_WAIT));
            if (isLinkCmd)
                array.Add(wxString(COMPILER_WAIT_LINK));
            array.Add(cmdpart);
        }
        if (idx == -1)
            break;
        cmd.Remove(0, idx + 1);
    }
}

MortenMacFly

Quote from: Alpha on September 30, 2012, 12:13:08 AM
Yes; so, for example, if the build is aborted, the previous library will not have been prematurely deleted.
OK -but in that casw we should check if:
- it works on Mac, too
- the deletion succeeded (i.e. the file is not restricted in its access)
- the commands used with their parametrisation are available on all target platforms
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

Alpha

Well, Mac says it will work, but I do not have access to a Mac to test it.
Using -f on non-Windows will prevent from waiting for a prompt if it failed.  Also, I believe this is the correct way to only try to delete if the file exists.

Index: src/plugins/compilergcc/directcommands.cpp
===================================================================
--- src/plugins/compilergcc/directcommands.cpp (revision 8428)
+++ src/plugins/compilergcc/directcommands.cpp (working copy)
@@ -733,6 +733,13 @@
         break;
     }
     wxString compilerCmd = compiler->GetCommand(ct);
+    if (ct == ctLinkStaticCmd) // static libraries should be deleted before recreation
+    {
+        if (platform::windows)
+            compilerCmd.Prepend(wxT("cmd /c if exist $static_output del $static_output\n"));
+        else
+            compilerCmd.Prepend(wxT("if [ -f $static_output ]; then rm -f $static_output; fi\n"));
+    }
     compiler->GenerateCommandLine(compilerCmd,
                                   target,
                                   0,

Alpha

Alternatively,

if [ -w $static_output ]; then rm -f $static_output; fi

could be used to only try to delete if write access is available on the file (under non-Windows).