Is it possible for codelets to reference code in other files, like header files?
If I have a codelet file
//FileA.cpp
#include "FileB.h"
class SomeCustomVertex : public Vertex {
public:
bool compute() {
int a = SomeConstantDefinedInFileB;
}
...
}
and some other "codelet" file
//FileB.h
const int SomeConstantDefineInFileB = 42;
and in the host graph program:
graph.addCodelets({"codelets/FileA.cpp", "codelets/FileB.h"});
I get a compile error from popc:
fatal error: 'FileB.h' file not found
#include "FileB.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
terminate called after throwing an instance of 'poplar::graph_program_compilation_error'
what(): Codelet compilation failed (see compiler output for details)
I figured this out.
Graph::addCodelets has a parameter StringRef compileFlags = "", which you can use to inject compiler options.
popc --help shows an option
-I arg Add directory to include search path
So when I use graph.addCodelets({"codelets/FileA.cpp"}, "-I codelets"); in the host program, and have my codelets in 'codelets' subdirectory, this works. No need to explicitly list the ".h" files in the arguments.
Incidentally, also a good way to ensure compiler optimisation (-O3) for the custom codelets.
CMake adds the following compile definition to all source code files automatically when simply compiling a target:
-Dlibname_EXPORTS
Why is this done and how can I disable it?
cmake add <libname>_EXPORTS macros only for shared libraries. It's useful when exporting API's in Windows DLL.
#if defined(_WINDOWS) && defined(testlib_EXPORTS)
# define API_DLL extern "C" __declspec(dllexport)
#else
# define API_DLL
#endif
API_DLL void foo();
It could be disabled by setting the DEFINE_SYMBOL property of target to empty.
# disable the <libname>_EXPORTS
set_target_properties(sharedlib
PROPERTIES
DEFINE_SYMBOL ""
)
Reference
http://www.cmake.org/cmake/help/v3.0/prop_tgt/DEFINE_SYMBOL.html
I am aiming at calling a dll file from a fortran compiler. I am doing all this in windows using the mingw compiler.
The dll was created using a g++ compiler
The code for which I am trying to create a dll
// example_dll.cpp
#include <stdio.h>
#include "example_dll.h"
__stdcall void hello()
{
printf("Hello");
}
command entered in the command prompt
g++ -c -DBUILDING_EXAMPLE_DLL example_dll.cpp
g++ -shared -o example_dll.dll example_dll.o -Wl,--out-implib,libexample_dll.a
The above two commands creates the dll file.
The job now is to create a fortran script to compile the dll file previously created.
For this purpose I am looking forward to create a fortran file capable of linking to the dll previously created.
Any help will be appreciated.
Thanks,
Adarsh
Later I tried some of the possibilities. My updated files are as follows
C file for which the DLL is created is as follows
// example_dll.c
#include <stdio.h>
#include "example_dll.h"
EXPORT void tstfunc (void)
{
printf("Hello\n");
}
EXPORT int Double11(int x)
{
printf("From the Double11\n");
printf("%d\n",x);
return x;
}
.h file used to create the DLL is as follows
// example_dll.h
#ifdef EXAMPLE_DLL_H
// the dll exports
#define EXPORT __declspec(dllexport)
#else
// the exe imports
#define EXPORT __declspec(dllimport)
#endif
// function to be imported/exported
EXPORT void tstfunc (void);
EXPORT int Double11(int x);
Fortran file used to link the dll is as follows
! fortcall.f90
program ForCall
IMPLICIT NONE
integer :: sum
integer :: inte3
INTERFACE
SUBROUTINE write() BIND(C,NAME='tstfunc')
END SUBROUTINE write
END INTERFACE
INTERFACE
SUBROUTINE get_integer(inte,inte2) BIND(C,NAME='Double11')
USE ISO_C_BINDING
IMPLICIT NONE
INTEGER (C_INT), VALUE :: inte
INTEGER (C_INT), INTENT(OUT) :: inte2
END SUBROUTINE get_integer
END INTERFACE
CALL write
CALL get_integer(1,inte3)
print*,"the output is",inte3
END PROGRAM ForCall
After entering the following directive in the command prompt
gfortran -o dll_foo_test fortcall.f90 -L. example_dll.dll
The output will be as follows
Hello
From the Double11
1
the output is -2
At this point something is not right. The code is capable of passing a value from FORTRAN to the DLL, whereas the code is not returning the right value from the dll. Some junk value of -2 is being displayed instead of 1.
I would like to fix that part in the code.
I have had success getting my debug builds to stop execution when a condition is programmatically specified, using the standard NSAssert(condition_which_should_evaluate_true, #"error message") statement in Objective C, and adding in an "All Exceptions" breakpoint in the Breakpoint Navigator.
Well and good, but most of the time when I'm debugging, I'd also like to continue normal program execution after that point. Often continuing the program after a failed assertion helps to track down the source of the confusion/bug. At least as far as I remember when I was programming on a different platform.
Is there a standard way to do so in Objective C development?
There's a way. It's not an Objective-C thing, it's a Unix thing.
kill(getpid(), SIGSTOP);
or simply:
raise(SIGSTOP);
In Swift:
raise(SIGSTOP)
This will break in the debugger in the __kill or __pthread_kill function. You will need to then go up a few stack frames to look at the frame that called kill or raise. You can use the debugger`s continue command to resume execution.
Note that if you're not running under the debugger and you execute this, your app will just hang. Take a look at [Technical Q&A QA1631: Detecting the Debugger](http://developer.apple.com/library/mac/#qa/qa1361/_index.html. You can use that information to write a wrapper function or macro that only sends SIGSTOP when running under the debugger. This answer may help.
Also, the Foundation framework provides a different assert macro for use in regular functions. It's NSCAssert.
Sounds like you want to use Conditional Breakpoints. If you set a breakpoint by clicking in the margin of your source code, then ctrl-click the little blue breakpoint thing, you can edit some options, including making the breakpoint conditional on the value of a variable.
Here's a blog post with some screenshots and more info.
This Stack Overflow question has some good pointers, too.
If you insist on triggering the breakpoint programmatically, then write a function and put a breakpoint inside it:
void MyConditionalBreak(BOOL condition, NSString *comment)
{
if (condition) {
NSLog(#"Stopped because %#", comment); // SET BREAKPOINT ON THIS LINE
}
}
Then you can call this function in a similar manner to NSAssert. If you declare the function in your project's precompiled header file (Whatever.pch) it will be available in all of your source files, without having to explicitly #import anything.
Here is how I do it:
First, in breakpoints tab I set my apps to break if any exception is raised:
Then In code (I usually have common header file containing common definitions like this that I import everywhere):
static void ThrowException(NSString* reason)
{
#try
{
#throw [NSException
exceptionWithName:#"DebugAssertionException"
reason:reason
userInfo:nil];
}
#catch (NSException * e)
{
NSLog(#"%#", e);
}
}
#define MYAssert(test, fmt, ...) if (!(test)) { ThrowException([NSString stringWithFormat:#"%s !!! ASSERT !!! " fmt, __PRETTY_FUNCTION__, ##__VA_ARGS__]); }
Now, You can use it like NSAssert, but instead of killing your app, you merely trigger a breakpoint:
MYAssert(bEverythingOkay, #"Something went wrong!");
// Or with arguments of course
MYAssert(bEverythingOkay, #"Something went wrong (TestValue=%zd; Reason=%#)", myTestValue, [this getLastError]);
I'm by no means an expert in this field but I use code that can break into the debugger via keyboard input.
DCIntrospect by domesticcatsoftware on github does this.
Take a look at the top of it's main file DCIntrospect.m and see how it does it.
It references a few sources, but from my experience it's quite up to date with the current assembly required to break into the debugger on armv6/7 and the simulator
External references for more background info
http://blog.timac.org/?p=190
http://developer.apple.com/library/mac/#qa/qa1361/_index.html
http://cocoawithlove.com/2008/03/break-into-debugger.html
Not sure why nobody else gave a clear straightforward answer... It's been five years but better late than never..
Preprocessor:
#ifdef DEBUG
#define manualBreakpoint() \
NSLog(#"\n\n\
Breakpoint called on: \n\n\
File: %s \n\n\
Line number: %i", __FILE__, __LINE__);\
\
raise(SIGSTOP)
#else
#define manualBreakpoint() ;
#endif
Usage:
To use it simply just type the following: manualBreakpoint();
Notes:
This will halt the app when that code is called and display the current method in your stack trace (as well as logging the file name and line number your app has halted on) IFF you are in debug mode, if you are in production mode for appstore (aka release, distribution, or archive) it will do nothing.
Using Rob's comments, and some ideas from "ios5 Programming: Pushing the Limits", and the Lumberjack framework, here's a macro to get the debugger to stop and allow for continuation during an assertion in DEBUG build, but to otherwise do as it always does during RELEASE (or actually any non-DEBUG) build.
#ifdef DEBUG
#define MyAssert(condition, desc, ...) \
if (!(condition)) { \
NSLog((desc), ## __VA_ARGS__); \
if (AmIBeingDebugged()) \
kill (getpid(), SIGSTOP); \
else { \
NSLog(#"%#, %d: could not break into debugger.", THIS_FILE, __LINE__); \
} \
}
#define MyCAssert(condition, desc, ...) \
if (!(condition)) { \
NSLog((desc), ## __VA_ARGS__); \
if (AmIBeingDebugged()) \
kill (getpid(), SIGSTOP); \
else \
NSLog(#"%#, %d: could not break into debugger.", THIS_FILE, __LINE__)); \
} \
}
#else //NOT in DEBUG
#define MyAssert(condition, desc, ...) \
if (!(condition)) { \
DDLogError((desc), ## __VA_ARGS__); \ //use NSLog if not using Lumberjack
NSAssert((condition), (desc), ## __VA_ARGS__); \
}
#define MyCAssert(condition, desc, ...) \
if (!(condition)) { \
DDLogError((desc), ## __VA_ARGS__); \ //use NSLog if not using Lumberjack
NSCAssert((condition), (desc), ## __VA_ARGS__); \
}
#endif //end DEBUG
#endif
These macros require the function AmIBeingDebugged(), which you can get from Apple at the link Rob gave: Technical Q&A QA1631: Detecting the Debugger. (You will also need to define DEBUG in your build settings.)
Note that I've chosen Lumberjack's DDLogError() over NSLog() in non-DEBUG builds because it will spit out the method, file and line number where the fatal assertion occurred.
A simple trick, if you want to use the console, is:
if (!condition_which_should_evaluate_true) {
; // Put breakpoint here
}
Then you put your breakpoint inside that line. If the condition evaluates to NO, then your breakpoint is invoked.
I'm building a zipper application, but it has a declaration that I want to separate it in another file (compress-file.m), but only when I separate the files I got an error when compiling with a variable, see it:
[ubuntu#eeepc:~/Desktop] make
This is gnustep-make 2.0.2. Type 'make print-gnustep-make-help' for help.
Making all for app LeafZip...
Creating LeafZip.app/....
Compiling file main.m ...
main.m: In function ‘main’:
main.m:7: error: ‘PATH_MAX’ undeclared (first use in this function)
main.m:7: error: (Each undeclared identifier is reported only once
main.m:7: error: for each function it appears in.)
main.m:12: warning: implicit declaration of function ‘compressFile’
main.m:7: warning: unused variable ‘outFileName’
make[1]: *** [obj/main.o] Error 1
make: *** [LeafZip.all.app.variables] Error 2
Also see the line 7 of main.m file:
char outFileName[PATH_MAX] = { 0 };
And see some lines of compress-file.m:
#include <stdio.h>
#include <zlib.h>
#include <limits.h>
/* Buffer to hold data read */
char buf[BUFSIZ] = { 0 };
size_t bytes_read = 0;
gzFile *out = gzopen(outFileName, "wb");
I know that is Objective-C extension, but it's only because when I solve this problem I will need to continue the development in Objective-C. What I need to do to correct this?
PATH_MAX is not always defined by including <limits.h>. If you want to use it, you probably need to fall back on the fragment:
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX _POSIX_PATH_MAX /* Or possibly _XOPEN_PATH_MAX */
#endif /* PATH_MAX */
Did you even include limits.h in your main program? If not, you need to do so.
Looks like main.m needs to #include <limits.h>. It also seems like it will need to include a header describing compressFile (which I guess you moved into compress-file.m.