MySQL++

Forum
Login

Suggested change

By pbyhistorian on 2018-09-23 21:42:46 [link]

I managed to get Cygwin to create the LIB and DLL.  mingw32-make worked too and I'm trying that path first.  The test programs crash, so I'm returning to Eclipse to write my own.

For (only) those people who are fine with writing make scripts, the MySQL++ source code is fine.  I'd like to propose a small change that will help the rest of us.

As I understand it, common.h uses this to determine if we're creating the DLL, using the DLL, or abandoning the DLL altogether (i.e. making a static library):
#ifdef MYSQLPP_MAKING_DLL
	// When making the DLL, export tagged symbols, so they appear
	// in the import library.
	#define MYSQLPP_EXPORT __declspec(dllexport)
#elif ! defined(MYSQLPP_NO_DLL)
	// We must be _using_ the DLL, so import symbols instead.
	#define MYSQLPP_EXPORT __declspec(dllimport)
#else
	// Not making a DLL at all, so no-op these declspecs
	#define MYSQLPP_EXPORT
#endif

The problem is that the CPP files completely ignore these settings.  When using the DLL, the CPP files re-define code that we said - with __declspec(dllimport) - exists in the DLL.  This causes a lot of errors and warnings in IDEs.

However, by flipping the explicit and implicit definitions...
#ifdef MYSQLPP_IMPORT_DLL
	// When using the DLL, import symbols.
	#define MYSQLPP_EXPORT __declspec(dllimport)
#elif ! defined(MYSQLPP_NO_DLL)
	// We must be _making_ the DLL; export tagged symbols instead,
	// so they appear in the import library.
	#define MYSQLPP_EXPORT __declspec(dllexport)
#else
	// Not using a DLL at all, so no-op these declspecs
	#define MYSQLPP_EXPORT
#endif
we get a flag with which we can wrap code that should be suppressed only when importing:
#if ! defined(MYSQLPP_IMPORT_DLL)	// #if defined(MYSQLPP_MAKING_DLL) will not work for static library
...
#endif

This eliminates a ton of warnings and errors and I think it's correct:
* it continues to prevent programmers from specifying __declspec(dllexport) and __declspec(dllimport) simultaneously
* it allows the code to be generated only when creating the DLL or making a static library.

By tangent on 2018-09-26 02:55:53

The test programs crash

If you're the one who created the other recent threads here anonymously, then I'd guess that's because of one of two different pilot errors:

  1. You told bootstrap "noex", so it didn't build the examples, so the fact that you have example programs means they're outdated artifacts, not built against your current configuration.

  2. You're mixing Cygwin and MinGW builds, which is a great way to create programs that crash. Build MySQL++ with one or the other, not both. (Or if you really do need MySQL++ built under both, create fully segregated build trees.)

The problem is that the CPP files completely ignore these settings.

If you're suggesting that every C++ definition needs to have a declspec exactly matching the one in the header file, then I have to ask why it's been working this way for about twenty years. (Note the 1998 date in the oldest ChangeLog entries!)

Are you sure the problem isn't that you aren't defining the MYSQLPP_ macros the same way the stock build system does when trying to replace that existing, working build system?

By pbyhistorian on 2018-09-26 06:11:22 [link]

Quote:
The process you're having trouble with is only needed when checking the code straight out of Fossil

Yes, I'd wondered about that.  After re-reading that paragraph a few times, I dropped the "bat" parameter.  But then the script complained that bakefilize missing, even though it was right there in the Bakefile/autoconf directory.  Cygwin is fine; it's the build process that needs far more detailed instructions.  After yae (yet another error), I realized I'd have to spend the next three months learning Bakefile, make, perl, and python before knowing I'd properly compiled MySQL++.

Quote:
* IOError: [Errno 13] Permission denied: '.bakefile_gen.state'
* Without Perl, you won't get...
* ...added the Perl library

* I couldn't find the part of bootstrap or mysql++.bkl that was creating the file as R/O.
* By re-installing Cygwin from scratch and running ./bootstrap without Perl (5.26.2) or anything else, I was able to delay compilation until after I'd changed .bakefile_gen.state to R/W - thereby avoiding the abends that would occur otherwise.
* "library"; oops - make that "package".

Anyway, Cygwin was installed in the default directory, as was Bakefile 0.2.11.
I put the MySQL++-3.2.4 directory under $USERNAME.

Quote:
...MinGW and Cygwin builds are very different...

I'll wipe and re-install Cygwin, and then try mingw32-make alone.
(Besides, I'm not sure where bootstrap puts its output.)

My IDE (Eclipse) lit up like a Christmas tree when I opened the source code.  None of the MYSQLPP_ macros were defined yet - that translates into "using the DLL" (i.e. importing the declarations).  Changing from MYSQLPP_MAKING_DLL to MYSQLPP_IMPORT_DLL gave me a flag I can use to hide what were effectively re-declarations.  Maybe IDEs have an easier way, but I was trying to stay with the #if defined() approach.

I think the reason "it's been working" is that you tell the compiler exactly what to do; it doesn't have to guess your intentions.  With an IDE, you have to tell it that everything's going to be fine.

I haven't learned what the other MYSQLPP_ flags are for yet, but I expect I can find them in the make files.

Thanks for the help!

By tangent on 2018-09-26 19:04:23 [link]

the script complained that bakefilize missing

I'm going to guess that's due to installing the native Windows version of Bakefile, rather than building Bakefile from source under Cygwin.

(If so, that also explains why you didn't need to install Python or SWIG, since the Windows installer includes those.)

In principle, there's nothing wrong with that, but Bakefile might not be putting itself in the Cygwin PATH or similar. I'll try to remember to test it the next time I get some free time on a Windows box. The closest available to me at the moment requires a reboot, and I'm not willing to reboot this machine at the moment.

I'll wipe and re-install Cygwin

That shouldn't be necessary, given that you're working from a Fossil checkout. Just say fossil clean from the checkout directory.

I'm not sure where bootstrap puts its output

It's all within the source tree unless you go out of your way to set up a separate build tree. That's why fossil clean is effective: it returns the checkout directory to its freshly-checked-out state, deleting everything extraneous.

I think the reason "it's been working" is that you tell the compiler exactly what to do

No, it's because we generate project files and Makefiles with all of the necessary defines set, at the points they need to be set. You're starting over with an unsupported build system, so you're going to have to replicate all of that work yourself.

If Bakefile had Eclipse project file output support, then you wouldn't have to think about all of this, but it doesn't, so you do.

I haven't learned what the other MYSQLPP_ flags are for yet, but I expect I can find them in the make files.

Yes, that's the best documentation, since they're basically project-internal details, not something we normally need to bother end users with.

You might consider a hybrid model: I assume it's easy to set Eclipse up to drive a Makefile based build system. That might be simpler than rediscovering all the details of how our existing build system works.

By wyetr on 2018-09-26 21:38:28 [link]

I'm going to guess that's due to installing the native Windows version of Bakefile...[which] might not be putting itself in the Cygwin PATH or similar

That guess is approximately correct. What's actually happening is that the Bakefile Windows installer is only installing the *.exe files in the PATH, apparently believing that the bakefilize Python script shouldn't be in the PATH, since Windows doesn't natively understand how to execute scripts via shebang paths. They've neglected the Cygwin case, though.

Rather than complain about it upstream, I've created a workaround for it in MySQL++'s bootstrap script. Try updating to the latest trunk and see how it goes.

I never saw the read-only filename problem. Either this implicitly worked around the problem, or you've still got a rogue NTFS ACL floating around causing you problems. ACL inheritance sounds like a good idea until you go to debug where a permission change is coming from...grrrr.