I'm trying to implement my template matching (with drawing) in AOT form and when I was testing whether the different methods work by including separate static libraries that are compiled from another project, I got build errors like:
Severity Code Description Project File Line Suppression State
Error LNK2005 _ZN6Halide7Runtime8Internal13custom_mallocE already defined in template_matching_ccorr.lib(template_matching_ccorr.lib.obj) Halide Template Matching v2 AOT Run c:\Users\Admin\documents\visual studio 2015\Projects\Halide Template Matchign v2 AOT Run\Halide Template Matchign v2 AOT Run\template_matching_sqdiff.lib(template_matching_sqdiff.lib.obj) 1
Is there a way to be able to include multiple libraries and be able to run different functions?
Also is there a similar function as realize that can be used in a AOT compilation code or would that require me to make two different AOT functions (assuming I can call multiple functions to begin with)
EDIT: a quick fix seems to be adding /FORCE:MULTIPLE to linker's command line
EDIT2: managed to get it to compile with adding
Target target = get_host_target();
target.set_feature(Target::NoRuntime, true);
to most of the pipelines except one which solves the multiple definitions. Now I'm wondering why I have to have one pipeline with the runtime even though I could just include HalideRuntime.h but it doesn't really work.
/FORCE:MULTIPLE works. So does judicious use of the no_runtime target feature. See http://halide-lang.org/tutorials/tutorial_lesson_15_generators_usage.html for details.
You can compile each pipeline without a runtime, and then link them together with a standalone runtime. Or you can just compile one of your pipelines with a runtime.
Related
I am new to Visual Studio, so if I say something wrong, please point me to the right direction.
I have a large C++ project that consists of shared library of around 20 classes and 7 executables, built by CMake in Linux. Each executable has its own CMake setup that links against the library.
I watched couple of videos on VS, managed to understand how to structure code and dependent libraries and successfully compiled the library statically.
I even managed to setup CMake in Visual studio, but started receiving an error that my .dll file is not Win32 application when I tried to build a project that links to it, so I dropped CMake and built the library by first making empty project and then adding necessary files (I thought it's CMake issue).
Long story short, now I have new setup for my library in VS that builds without issues. However I want my library to be dynamic because it makes ton of sense as 7 different projects depend on it and that's how I did it in Linux.
To my big surprise, even though selecting .dll will build, it cannot be linked to (I started all of this as empty project, not .dll template).
What I just discovered that building .dll library requires a macro that looks like (taken from https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170):
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
and before return type of any function in library I need to add the macro as:
MATHLIBRARY_API double some_function();
So if I understand correctly, this macro is "exporting" function names to .dll. Does that then mean that I need to open all 20 header files and wrap every single function in it with the macro?
Note that most header files are class declarations, do I need to wrap every single class method, just the public methods and is there a way to make a whole class "exported"?
It seems quite a cumbersome task just to build a shared library. I realize now this is why cmake failed and kinda begs the question on its cross platform capabilities if this wrapping to make .dll in VS needs to be done like this.
I am considering building my library statically, and in the same solution, add additional projects, and make a reference to the static library.
It kills modularity of the project, but it should work fine.
I am working on a few libraries for coding Arduinos in Ada. Each library is its own project, and I have an aggregate project that aggregates the libraries. I need to specify the runtime for each project since they are running on different chips. So for example I have something like this:
aggregate project Agg is
for Project_Files use ("due/arduino_due.gpr",
"uno/arduino_uno.gpr",
"nano/arduino_nano.gpr");
-- ...
end Agg;
library project Arduino_Due is
-- Library_Dir, _Name, and _Kind attributes ...
-- Target attribute ...
for Runtime ("Ada") use "../runtimes/arduino_due_runtime";
package Compiler is
-- Driver and Switches attributes ...
end Compiler;
And similar projects for the Uno and Nano. Building arduino_due.gpr directly works fine. It finds my runtime in the specified folder as it should. However, when I build agg.gpr, I get
fatal error, run-time library not installed correctly
cannot locate file system.ads
This occurs whether I use an absolute path or a relative path, and also occurs when the relative path is concatenated with Project'Project_Dir. However, if rather than using the Runtime attribute I use the compiler switch --RTS=..., then it works, but only if I use a relative path that is prefixed with Project'Project_Dir. An absolute path or a plain relative path will result in the error gprbuild: invalid runtime directory runtimes/arduino_due_runtime.
So what's going on here? This behavior seems inconsistent and I couldn't find anything in the docs about it so I suspect a bug. But I thought I'd ask here first in case I'm doing something wrong. Maybe I should just be using child projects, or project extension?
This isn’t a bug, it’s a feature :-).
See this rejected issue.
There are two things:
Several options are only recognised in the main project, and if you use an aggregate project that is the main project.
Package Builder is ignored in aggregated projects.
My conclusion: aggregate projects don’t suit your use case, or mine. As I said in the issue noted above, back to Makefiles (or scripts).
Part of the design intent is that aggregate projects should share code and compilations: as 2.8.4 of the manual says,
The loading of aggregate projects is optimized in GPRbuild, so that all files are searched for only once on the disk (thus reducing the number of system calls and yielding faster compilation times, especially on systems with sources on remote servers). As part of the loading, GPRbuild computes how and where a source file should be compiled, and even if it is located several times in the aggregated projects it will be compiled only once.
Since there is no ambiguity as to which switches should be used, files can be compiled in parallel (through the usual -j switch) and this can be done while maximizing the use of CPUs (compared to launching multiple GPRbuild commands in parallel).
I am currently looking at an issue where a project is generating a DLL. Now it is built upon a chain of other projects which are all C++, so they're just .lib files being linked in.
In this case one project uses OpenCL, however I don't believe those code paths are being run. However it would appear that just having OpenCL linked in causes the output .DLL to have a dependency on OpenCL.dll.
Please correct me if I am wrong here (in which case I'll go over the code with a fine-toothed comb to ensure no OpenCL calls are being executed).
I am not sure how Visual Studio (or dependency walker?) figures out which DLL's are dependencies for a given DLL. However I don't want the OpenCL.dll dependency.
What are my options?
One possible one is to take the project with the OpenCL code and refactor so some portion of it can be build with the OpenCL portion excluded from the build. However this will be a fair chunk of work so I am really hoping for something simpler.
If you link a lib you depend on the dll. The easiest thing for you would be to add /DELAYLOAD for this dll:
The /DELAYLOAD option causes the DLL that's specified by dllname to be loaded only on the first call by the program to a function in that DLL.
This generates a 'soft' dependency which only kicks in if you call a function that actually needs the DLL. Make sure you read Constraints of Delay Loading DLLs.
The other option (which I don't recommend) is to use runtime binding via LoadModule and GetProcAddress, then invoke functions via the pointer to function. This removes any dependency, but you are tasked to implement all check, all errors if the DLL is missing, and it can easy go astray if you mismatch the function signature/call convention. Ultimately, you'd be implementing /DELOAYLOAD manually.
I have C project of a library (using CDT). Configurations for both static and dynamic linking for several platforms. Several examples of the library usage is also included in the project. What is the best way to build these examples with the library? If I would like to build both the library and examples (linking the library just built) in one configuration?
I suppose I have to use custom makefile. Do I have to create makefile for the whole project (several of them, one for each platform), or is there any way how to include examples makefile to the automatic one?
Each example has only one source file, so the only things I need to do in my makefile are to determine which compiler is used, add some flags and link with the library which was built (I would include the make examples command as the post-build step).
As I didn't find any solution for this, I use custom makefile for the whole build. I also found a nice advice somewhere: if you want advanced build functions, use advanced build system.
I have a project compiled using __cdecl calling convention (msvc2010) and I compiled boost using the same compiler using the default settings.
The project linked with boost but I at runtime I got an assert message like this:
File: ...\boost\boost\program_options\detail\parsers.hpp
Line: 79
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
There are the following questions:
what calling convention does boost build with by default on Windows (msvc2010)
how to I compile boost with __cdecl calling convention
why boost wasn't able to prevent linking with code with different calling conventions? I understood that boost has really smart library auto-inclusion code.
Update #1
It looks that boost does compile and link with proper calling convention, still at runtime I get the above problem. I did a sample application using the same code and it works but in my application it fails. The only difference could be from project configuration or includes/stdafx.h
Just use
bjam ... **cxxflags=/Zp4**
while building boost libraries.
As far as I know there's not way to make C++ use cdecl calling conventions (see MSDN Calling Convention). The C++ method calling is just different from C. The only opportunity that you have to use one of the C calling conventions is for functions, which include class static functions in C++. If you know that's the case you can try forcing the option when building by adding the option during the build:
bjam cxxflags=/Gd ...
(see BBv2 Builtin features)
Or to make it "permanent" set up a user-config.jam with your compiler and add it to the build options for all BBv2 msvc builds (see BBv2 Configuration and related docs). As for you other questions:
Boost uses the default calling convention MSVC uses, except for cases where it overrides it at the code level. I don't know where those are as they are library specific. So you'd have to search the code for the "__*" code decorators.
See above for partial answer.
Detection; there are two reasons: There is a limit to how many different options we can reasonably detect for for building as it's an exponential growth of different possible variations so we limit it to the most important cases. And in the case of calling convention, it's not actually possible since it's something that can be changed on a per function basis.
I found the cause of the problem inside one of the shared property files: <StructMemberAlignment>4Bytes</StructMemberAlignment>
If I remove it the code will work. Still, I'm not sure why this is happening and how could I solve it without removing the above code (that was required by another library).
I added another question regarding boost and structure member alignment.