How did I migrate from windows to wine?

    image

    Preamble


    I have several old projects written in C ++, which are still developing as far as possible. It would seem - what's the matter? Alas, this is a bunch of regular plugins for my favorite Adobe InDesign.

    And every time a new Creative Suite comes out, you have to port this business. Interestingly, the main effort is to assemble a new version according to the new rules, and bend the installer. Because if it has reached the stage of "it compiles", then as a rule it works. Although of course there are nuances - for example, at one point, PlaceGun stopped laying out several selected images, only the first. But more about that next time.

    And of course - I would like to collect it for all versions and all platforms at a time, and not "opened the widget - collected - closed - repeated . "

    So, for assembly, we need both

    • MS VS 2005
    • MS VS 2005 sp1
    • MS VS 2008
    • MS VS 2010
    • MS VS 2012




    image

    Going to gmake - profit


    Why is that? Ah, I didn’t say - there is still MacOSX. So goodbye nmake no options.

    And in the end we get such a nightmare:
    Hidden text
    1. cl-cs3.mak
    2. cl-cs4.mak
    3. cl-cs5.mak
    4. cl-cs55.mak
    5. cl-cs6.mak
    6. cl-cc.mak
    7. cl-cc2014.mak
    8. cl.mak
    9. commplugs.mak
    10. gcc-cs3.mak
    11. gcc-cs4.mak
    12. gcc-cs5.mak
    13. gcc-cs55.mak
    14. gcc-cs6.mak
    15. gcc-cc.mak
    16. gcc-cc2014.mak
    17. gcc.mak
    18. mac-defs.mak
    19. platform-impl.mak
    20. platform-targets.mak
    21. platform.mak
    22. win-defs.mak



    And it starts like this:
    make ARCH=x64 INDD=cc2014 compile
    


    What is obvious, the platform is defined through uname. And each part is assembled in the standard way as make -C foo.

    The description of each component looks something like this
    Hidden text
    include ../../make/platform.mak
    TARGET=../../../lib/$(ARCH)/$(INDD)/libz.$(LibSuffix)
    OBJS=\
        $(ARCH)/$(INDD)/adler32.$(OBJSuffix) \
        $(ARCH)/$(INDD)/compress.$(OBJSuffix) \
        $(ARCH)/$(INDD)/crc32.$(OBJSuffix) \
        $(ARCH)/$(INDD)/deflate.$(OBJSuffix) \
        $(ARCH)/$(INDD)/gzio.$(OBJSuffix) \
        $(ARCH)/$(INDD)/infback.$(OBJSuffix) \
        $(ARCH)/$(INDD)/inffast.$(OBJSuffix) \
        $(ARCH)/$(INDD)/inflate.$(OBJSuffix) \
        $(ARCH)/$(INDD)/inftrees.$(OBJSuffix) \
        $(ARCH)/$(INDD)/trees.$(OBJSuffix) \
        $(ARCH)/$(INDD)/uncompr.$(OBJSuffix) \
        $(ARCH)/$(INDD)/zutil.$(OBJSuffix) \
    all: $(TARGET)
    $(TARGET): $(OBJS)
    	 $(AR) $(LFLAGS) $(OBJS)
    clean:
     	$(RMRF) $(TARGET) $(OBJS)
    


    And all this worked on a separate dedicated virtual machine under WinXP (and the same under hackintosh).

    I do not seem to paint these passions from and to the point, I will give only the most interesting excerpts. For example, this is how we calculate the project root and the platform on which the compilation will now be performed:

    PR:=$(subst make/,,$(dir $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
    OSA:=$(shell uname -o)
    ifeq (Darwin,$(OSA))
    OS=mac
    else
    OS=win
    endif
    


    And this is how it is determined where to look for Boost (adobes in each version manage to shift, so there are two parts here - we define the macro and then use it):
    ifeq ($(ARCH),x86)
    BoostARCH=32
    else
    BoostARCH=64
    endif
    BoostLib=$(subst \,/,$(AdobeSDK))/external/dva/third_party/boost_libraries/bin.v2/libs/boost_$1/lib/$(OS)/release/$(BoostARCH)/boost_$1.$(LibSuffix)
    BoostFilesystemLib=$(call BoostLib,filesystem)
    BoostThreadLib=$(call BoostLib,threads)
    BoostRegexLib=$(call BoostLib,regex)
    BoostSystemLib=$(call BoostLib,system)
    


    It’s clear that I didn’t type this with my hands, but wrote a pack of batch files, but under MinGW:

    genmake-for-dll.bat component-name [path-to-sources [target-directory]]
    @echo off
    rem genmake component-name [path-to-sources [target-directory]]
    set CN=%1
    set FP=%2
    if -%1==- set CN=default
    if -%2==- set FP=.
    if -%3==- set TD=.
    echo>  MakeF COMPONENT=%CN%
    echo>> MakeF include ../make/platform.mak
    echo>> MakeF TARGET=$(OBJDIR)/$(COMPONENT).$(DLLSuffix)
    echo>> MakeF OBJS=\
    find %FP% -type f -name '*.c*' | grep -v .svn | awk '{ print "\t$(OBJDIR)/" $1 ".$(OBJSuffix)\t\\\"; }' | sed -e 's/\.cpp\./\./' | sed -e 's/\.cxx\./\./' | sed -e 's?/%FP%??' >> MakeF
    echo>> MakeF #
    echo>> MakeF HEADERS=\
    find %FP% -type f -name '*.h*' | grep -v .svn | awk '{ print "\t" $1 "\t\\\"; }' > headers  >> MakeF
    echo>> MakeF #
    echo>> MakeF #
    echo>> MakeF all: $(TARGET)
    echo>> MakeF #
    echo>> MakeF $(TARGET): $(OBJS)
    echo>> MakeF 	$(LINK) $(LDFLAGS) $(OBJS) $(XLIBS)
    echo>> MakeF	if [ -f $@.manifest ] ; then mt -nologo -manifest $@.manifest "-outputresource:$@;2"; fi
    echo>> MakeF #
    echo>> MakeF clean:
    echo>> MakeF 	rm -f $(TARGET) $(OBJS)
    echo>> MakeF #
    find %FP% -type f -name '*.c*' | grep -v .svn | awk '{ print "$(OBJDIR)/" $1 ".$(OBJSuffix) : " $1 " $(HEADERS)\n\t$(CC) $(CFLAGS) " $1 "\n"; }' | sed -e 's/.cpp././' | sed -e 's/\.cxx\./\./' | sed -e 's?/%FP%/?/?' >> MakeF
    echo>> MakeF #EOF
    mv MakeF Makefile
    


    genmake-for-lib.dll component-name [path-to-sources [target-directory]]
    @echo off
    rem genmake component-name [path-to-sources [target-directory]]
    set CN=%1
    set FP=%2
    if -%1==- set CN=default
    if -%2==- set FP=.
    if -%3==- set TD=.
    echo>  MakeF COMPONENT=%CN%
    echo>> MakeF include ../make/platform.mak
    echo>> MakeF TARGET=$(OBJDIR)/lib$(COMPONENT).$(LibSuffix)
    echo>> MakeF OBJS=\
    find %FP% -type f -name '*.c*' | grep -v .svn | awk '{ print "\t$(OBJDIR)/" $1 ".$(OBJSuffix)\t\\\"; }' | sed -e 's/\.cpp\./\./' | sed -e 's/\.cxx\./\./' | sed -e 's?/%FP%??' >> MakeF
    echo>> MakeF #
    echo>> MakeF HEADERS=\
    find %FP% -type f -name '*.h*' | grep -v .svn | awk '{ print "\t" $1 "\t\\\"; }' > headers  >> MakeF
    echo>> MakeF #
    echo>> MakeF #
    echo>> MakeF $(TARGET): $(OBJS)
    echo>> MakeF 	$(AR) $(LFLAGS) $(OBJS)
    echo>> MakeF #
    echo>> MakeF clean:
    echo>> MakeF 	rm -f $(TARGET) $(OBJS)
    echo>> MakeF #
    find %FP% -type f -name '*.c*' | grep -v .svn | awk '{ print "$(OBJDIR)/" $1 ".$(OBJSuffix) : " $1 " $(HEADERS)\n\t$(CC) $(CFLAGS) " $1 "\n"; }' | sed -e 's/.cpp././' | sed -e 's/\.cxx\./\./' | sed -e 's?/%FP%/?/?' >> MakeF
    echo>> MakeF #EOF
    mv MakeF Makefile
    


    genmake-for-indd.bat plugin-name [path-to-sources [target-directory]]
    @echo off
    setlocal
    rem genmake plugin-name [path-to-sources [target-directory]]
    set CN=%1
    set FP=%2
    if -%1==- set CN=plugin
    if -%2==- set FP=.
    if -%3==- set TD=.
    echo>  MakeF COMPONENT=%CN%
    echo>> MakeF include ../make/platform.mak
    echo>> MakeF PluginName=$(COMPONENT)
    echo>> MakeF TARGET_DIR=$(OBJDIR)/$(PluginPrefix)
    echo>> MakeF TARGET=$(TARGET_DIR)/$(PluginName)$(PluginSuffix)
    echo>> MakeF CFLAGS+=-I ../common
    echo>> MakeF LIBS+=$(call add_component_ref,vl) $(call add_component_ref,common)
    echo>> MakeF OBJS=\
    find %FP% -type f -name '*.c*' | grep -v .svn | awk '{ print "\t$(OBJDIR)/" $1 ".$(OBJSuffix)\t\\\"; }' | sed -e 's/\.cpp\./\./' | sed -e 's/\.cxx\./\./' | sed -e 's?/%FP%??' >> MakeF
    echo>> MakeF     $(COMMON_PLUGIN_OBJS)
    echo>> MakeF #
    echo>> MakeF HEADERS=\
    find %FP% -type f -name '*.h*' | grep -v .svn | awk '{ print "\t" $1 "\t\\\"; }' > headers  >> MakeF
    echo>> MakeF #
    echo>> MakeF #
    echo>> MakeF ifeq (win,$(OS))
    echo>> MakeF OBJS+= $(OBJDIR)/$(COMPONENT).res
    echo>> MakeF FRES_TGT=$(OBJDIR)/$(COMPONENT)_w.$(FRES)
    echo>> MakeF else
    echo>> MakeF FRES_TGT=$(OBJDIR)/R/$(COMPONENT)_w.$(FRES)
    echo>> MakeF endif
    echo>> MakeF #
    echo>> MakeF ifeq (mac,$(OS))
    echo>> MakeF ifeq (x64,$(ARCH))
    echo>> MakeF TARGET:=
    echo>> MakeF endif
    echo>> MakeF endif
    echo>> MakeF #
    echo>> MakeF all: $(TARGET)
    echo>> MakeF #
    echo>> MakeF clean:
    echo>> MakeF 	rm -rf $(TARGET) $(OBJS) $(TARGET_DIR)/*
    echo>> MakeF #
    echo>> MakeF #
    echo>> MakeF $(TARGET): $(OBJS) $(LIBS) $(FRES_TGT)
    echo>> MakeF 	$(LINK) $(LDFLAGS) $(LDFLAGS_InDesignPlugin) $(OBJS) $(LIBS) $(AdobeLIBS) $(XLIBS)
    echo>> MakeF #
    echo>> MakeF #
    echo>> MakeF ifeq ($(OS),win)
    echo>> MakeF $(OBJDIR)/$(COMPONENT)_w.$(FRES): $(COMPONENT).fr
    echo>> MakeF 	$(ODFRC) $(ODFRCFLAGS) -o $(call unix_to_dos,$(OBJDIR)/$(COMPONENT)_w.$(FRES)) $(COMPONENT).fr
    echo>> MakeF #
    echo>> MakeF $(OBJDIR)/$(COMPONENT).res: $(COMPONENT).rc $(OBJDIR)/$(COMPONENT)_w.$(FRES)
    echo>> MakeF 	$(RSC)  $(RSCFLAGS) $(CFLAGS_INCLUDE) $(COMPONENT).rc
    echo>> MakeF 	$(AdobeSDK)\devtools\bin\merge_res.cmd $(call unix_to_dos,$(OBJDIR)) $(COMPONENT) $(COMPONENT)_w
    echo>> MakeF 	mkdir -p "$(TARGET_DIR)/($(PluginName) Resources)"
    echo>> MakeF 	cp -r $(OBJDIR)/idrc_* "$(TARGET_DIR)/($(PluginName) Resources)"
    echo>> MakeF endif
    echo>> MakeF ifeq ($(OS),mac)
    echo>> MakeF $(OBJDIR)/R/$(COMPONENT)_w.$(FRES): $(COMPONENT).fr
    echo>> MakeF 	mkdir -p $(TARGET_DIR)/Resources
    echo>> MakeF 	mkdir -p $(OBJDIR)/R
    echo>> MakeF 	$(ODFRC) $(ODFRCFLAGS) $(CFLAGS_IXA_OF) -o $@ $(COMPONENT).fr
    echo>> MakeF 	/Developer/Tools/ResMerger -dstIs DF $@ -o $(OBJDIR)/$(PluginName).$(FRES)
    echo>> MakeF 	/Developer/Tools/ResMerger $(OBJDIR)/$(PluginName).$(FRES) -dstIs DF -o $(TARGET_DIR)/Resources/$(PluginName).rsrc
    echo>> MakeF 	cp -r $(OBJDIR)/R/idrc_* Info.plist $(TARGET_DIR)/Resources
    echo>> MakeF 	( cd $(TARGET_DIR)/..; ln -s A Current ; cd .. ; ln -s Versions/Current/Resources Resources ; ln -s Versions/Current/$(PluginName) $(PluginName) )
    echo>> MakeF endif
    echo>> MakeF include ../make/commplugs.mak
    echo>> MakeF #
    echo>> MakeF #
    find %FP% -type f -name '*.c*' | grep -v .svn | awk '{ print "$(OBJDIR)/" $1 ".$(OBJSuffix) : " $1 " $(HEADERS)\n\t$(CC) $(CFLAGS) " $1 "\n"; }' | sed -e 's/.cpp././' | sed -e 's/\.cxx\./\./' | sed -e 's?/%FP%/?/?' >> MakeF
    echo>> MakeF #EOF
    rem mv MakeF Makefile
    endlocal
    


    image

    Nothing foreshadowed, and yeah


    And all this worked perfectly until Adobe InDesign CC 2014 came out. And I wanted a visual studio 2012. That's where the white fur-bearing animal jumped!

    No, of course, in theory, I knew that visual studio did not work for Khryusha a long time ago . But here that cl.exe suddenly turned out to be not valid Win32 image - it was a blow.

    I’ll explain a little - since the time of two visual studios 2005 with a service pack and without a service pack at the same time, I honestly do not put anything on the build machine. To do this, there is a clean virtual machine in which I put the visual studio express edition, I roll up the correct platform sdk, and copy what happened (licensed clean and so on) into the appropriate folder. And I roll back the virtual computer to the state "there was nothing."

    And since the installer of the 2012 studio wanted a newer one - no question, here's Windows 8.1. Any whim is for microsoft.

    I bet, I copy - a shit.

    image

    Monsieur knows a lot about perversions



    And then the question arose - what should I do?

    There are few options.

    1. Install and settle in a new virtual machine for Windows 8.1, starting from MinGW and ending with indesigns. And you need to find licenses - of course I have everything, but they lie in completely different places. Long and tedious.
    2. Moving to the Amazon cloud - on w2k12, is enough for a long time and will work quickly. But again the same problem - long and tedious. And all these accumulated versions and copies - 25 gigabytes to transfer. Lazy.
    3. Dodge so that you don’t have to change anything.

    I scratched the mackerel, and thought - and purkua would not na ? After all, I’m open host.

    Typing
    wine где-там-скопировал-2012-студию\vc\bin\cl.exe /help
    

    and it still works.

    - Aha! - said the harsh Siberian men.

    Not without a rake, of course, it passed - it turned out that some of the libraries from the visual studio runtime in Vine are not quite like that. This is not a problem - visual studio has a reference, I copied visual studio from daddies.

    But what surprised me, a completely simple mt.exe not only fell, but also called SIGSEGV for wine. Shamanism with libraries did not give a solution, I had to quickly write my substitute with the poetesses.

    Hidden text
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    static void usage() {
    	printf("Usage: mt.exe -manifest foo.dll.manifest -outputresource:foo.dll[;2]\n");
    }
    static void alert(char* fn, char* msg, int code) {
        static char* lpstrError;
        FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |  FORMAT_MESSAGE_ALLOCATE_BUFFER,
             NULL, GetLastError(), LANG_USER_DEFAULT, &lpstrError, 1, NULL);
        fprintf(stderr, "%s: %s: %s, %d\n", fn, msg, lpstrError, code);
        LocalFree(lpstrError);
    }
    static int update_res(char* ou, int resk, char* mf) {
    	HANDLE hUpdateRes;
    	LPVOID buf;
    	BOOL result;
    	FILE* fp;
    	struct _stat st;
    	int ressz = 0, outk;
    	fp = fopen(mf, "rb");
    	if(!fp) {
    		alert(mf, "could not open manifest file", errno);
    		return 2;
    	}
    	if(_fstat( fileno(fp), &st) != 0) {
    		fclose(fp);
    		alert(mf, "could not determine manifest file size", errno);
    		return 2;
    	}
    	ressz = st.st_size;
    	buf = (void*)malloc(ressz);
    	if(!buf) {
    		fclose(fp);
    		free(buf);
    		alert(mf, "could not allocate buffer for resource", ressz);
    		return 2;
    	}
    	outk = fread(buf, 1, ressz, fp);
    	if(outk != ressz) {
    		fclose(fp);
    		free(buf);
    		alert(mf, "could not read manifest", ressz - outk);
    		return 2;
    	}
    	fclose(fp);
    	hUpdateRes = BeginUpdateResourceA(ou, FALSE);
    	if (hUpdateRes == NULL) {
    		free(buf);
    	    alert(ou, "Could not open file for writing.", 0);
        	return 3;
    	}
    	result = UpdateResourceA(hUpdateRes,
        	RT_MANIFEST,
        	MAKEINTRESOURCE(resk),
        	MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
        	buf,
        	ressz);
    	if (result == FALSE) {
    		alert(ou, "could not add resource", 0);
    		free(buf);
        	return 4;
    	}
    	if (!EndUpdateResource(hUpdateRes, FALSE)) {
        	alert(ou, "could not write changes to file", 0);
    		free(buf);
        	return 4;
    	}
    	free(buf);
        return 0;
    }
    int main(int argc, char** argv)
    {
    	char* mf = NULL;
    	char* ou = NULL;
    	char* v;
    	int resk = 1;
    	int k;
    	if(argc < 2) {
    		usage();
    		return 2;
    	}
    	for(k=1; k < argc; ++k) {
    		if(argv[k][0] == '-') {
    			if(argv[k][1] =='m') { // manifest
    				mf = argv[k+1];
    				++k;
    				continue;
    			}
    			else if(argv[k][1] == 'o' ) { // outputresource
    				if(argv[k+1]) 
    					ou = argv[k+1];
    				else {
    					ou = strchr(argv[k], ':');
    					if(!ou) {
    						usage();
    						return 3;
    					}
    					++ou;
    				}
    				++k;
    				v = strchr(ou, ';');
    				if(v) {
    					resk = atoi(v + 1);
    					*v = '\0';
    				}
    				else
    					resk = 1;
    				continue;
    			}
    		}
    		usage();
    		return 2;
    	}
    	if(!mf || !ou) {
    		usage();
    		return 2;
    	}
    	return update_res(ou, resk, mf);
    }
    


    But InnoSetup against expectations - did not bring surprises, collects with a whistle.

    So far, so, and then I will go to the cloud, the moment has ripened.

    But nevertheless, I decided to share it with the community - all of a sudden I’m missing something, suddenly someone will come in handy ...

    Only registered users can participate in the survey. Please come in.

    Was the game worth the candle?

    • 18.6% had to switch to Windows 8 for a long time, which is why the author sloup - incomprehensibly 85
    • 27.1% had to transfer everything to Linux 124 for a long time
    • 27.1% well, you smoke there ;-) 124
    • 26.3% however, wine is a great thing, since the whole farm from different versions of visual studios works in it 120
    • 0.6% your option 3

    Also popular now: