Include path relative to Makefile regarding assembler (GAS) files - makefile

Let's say I've got the following project structure:
<ASM_Project>/
├── <src>/
│ └── <boot>/
│ ├── boot.s
│ └── functions.s
└── Makefile
boot.s:
_start:
jmp testing
.include "src/boot/functions.s"
testing:
Makefile:
src/boot/boot.o: src/boot/boot.s src/boot/functions.s
as -o $# $<
boot.s and functions.s are in the same folder and yet .include "functions" doesn't seem to work in this case:
Ernie#Sanderson:~/ASM_Project$ make
as -o src/boot/boot.o src/boot/boot.s
src/boot/boot.s: Assembler messages:
src/boot/boot.s:11: Error: can't open functions.s for reading: No such file or directory
make: *** [Makefile:23: src/boot/boot.o] Error 1
Is there a way to pull it off though?

Related

Difference between compiling, debugging, executing and running

I am new to programming. Additionally, I am super confused about compiling, debugging, executing, running. What does each of them mean and what starts first?
Thanks.
without make it complicated
compile: make your code executable, creating a file that can be executed
debug: is the action of check your code for execution instruction by instruction
execute/run: make your code produce the result that you coded for
C basic example
requisite
gcc (compiler)
shell (ex: bash)
terminal emulator
getting started
the main folder:
PROJECT
│
├─ README.md
│
└─ main.c
main.c: this file contain the code
#include<stdio.h>
int main(void)
{
char ch = 'd';
printf("hello worl%c",ch);
return 0;
}
README.md: contain the explanation of the project
Compile
open the terminal in this folder and enter:
gcc -o build/out main.c
gcc: the compiler executable
-o build/out: the name of the output
main.c: the name of the file to compile
than this is what we should see
PROJECT
│
├─ README.md
│
├─ build
│ └─ out
│
└─ main.c
<!-- build is just the name of the
folder were the executable is placed -->
Execute/Run
open the terminal in this folder and enter:
./build/out
# result:
# > ./a.out
# hello world

Makefile .tar: Flatten the source files' directory structure

I want to collect some source files and tar them by using Makefile. The source files are scattering as follows:
project
│
├── Makefile
│
├── folder(name is arbitrary)
│ │
│ ├── test1.txt
│ ├── test2.txt
│ .
│ .
│ .
│
├── source.cpp
│
├── source2.cpp
│
├── source.h
.
.
Now, I want to have a flattened tarball file that includes every source files just under the root directory of this tarball file when I call make in the root directory(project), like this:
myTarball.tar.gz
│
├── Makefile
│
├── source.cpp
│
├── source2.cpp
│
├── source.h
│
├── test1.txt
│
├── test2.txt
│
.
.
.
The current make file looks something like this:
FILES=$($(wildcard Makefile *.h *.hpp *.cpp test*.txt */test*.txt))
$(NAME): $(FILES)
COPYFILE_DISABLE=true tar -vczf $(NAME) $(FILES)
I'm not familiar with makefile and bash, but I try my best to play around and do some searching but found nothing. The current one can only generate something like
NAME.tar.gz
│
├── Makefile
│
├── folder
│ │
│ ├── test1.txt
│ ├── test2.txt
│ .
│ .
│ .
│
├── source.cpp
│
├── source2.cpp
│
├── source.h
.
.
with the folder structure. I think I might first copy all source files in the folder to the root directory, and delete them after tar them up. Is there a better way to do this elegantly?
Well, you can do it that way but if you're using GNU tar then it's probably simpler to just let tar do the work for you rather than copying files around to a temporary location first.
Something like this should work:
$(NAME): $(FILES)
COPYFILE_DISABLE=true tar -vczf $(NAME) --transform='s,.*/,,' $(FILES)
which will remove all directories from files inside the generated tar file. See the manual for the --transform option.

Cmake Shared library

I am learning CMake but I am struggling to understand how to link a binary file to a shared library and then install these files in a release folder.
These is the structure of my project:
├── CMakeLists.txt
├── build
├── main
│   ├── CMakeLists.txt
│   └── main.cpp
├── release
|_______bin
│   ├── include
│   │   └── math.h
│   └── lib
│   └── libmathLib.dylib
└── shared_lib
├── CMakeLists.txt
├── include
│   └── math.h
└── src
└── math.cpp
In the root CMakeLists.txt I've defined the project settings and the subdirectory.
Root CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
project (Math)
set(CMAKE_BUILD_TYPE Release)
set(MAKE_INCLUDE_CURRENT_DIR ON)
ADD_SUBDIRECTORY(shared_lib)
ADD_SUBDIRECTORY(main)
Main CMakeLists.txt:
add_executable(main main.cpp)
TARGET_LINK_LIBRARIES(main LINK_PUBLIC mathLib)
Math lib ( shared lib )
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(mathLib SHARED src/math.cpp)
install(TARGETS mathLib DESTINATION /Users/giuseppe/development/cmake/release/lib LIBRARY NAMELINK_ONLY)
install(FILES include/math.h DESTINATION /Users/giuseppe/development/cmake/release/include)
When I build the project with Make, it doesn't link main.o to the shared library. Error :
Scanning dependencies of target mathLib
[ 50%] Building CXX object shared_lib/CMakeFiles/mathLib.dir/src/math.cpp.o
Linking CXX shared library libmathLib.dylib
[ 50%] Built target mathLib
Scanning dependencies of target main
[100%] Building CXX object main/CMakeFiles/main.dir/main.cpp.o
/Users/giuseppe/development/cmake/main/main.cpp:8:12: error: use of undeclared identifier 'sum'
count << sum(5,6) << endl;
^
1 error generated.
make[2]: *** [main/CMakeFiles/main.dir/main.cpp.o] Error 1
make[1]: *** [main/CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2
Release phase:
How can I make sure that the builds in the bin folder within the release folder use the shared lib in 'path/release/lib'? Possibly using a relative path such as '../lib/' ?
You must add include directory for library to main/CMakeLists.txt. Adding it to shared_lib/CMakeLists.txt is not enough. Try this line:
include_directories("../shared_lib/include")

SCons env.Install("path_to_folder") does not show folder files in dependency tree

In SCons when a folder is installed the dependency tree is not aware of the contents of the folder. This means that implicit relationships cannot be created.
env.Install("out/bin","path/to/folder")
env.Install("out/archive", Glob("out/bin/folder/library.lib"))
In this sample code the Glob returns [] because SCons is unaware the folder contains a file called library.lib.
The only workaround I've found for this is to walk the directory and install each individual file.
Does the SCons Install not have an option to do this for you?
I have run into this as well. I have not found any other solution than to walk the directories as you describe. Though the contents of the folder are copied, to SCons there is just one target, and just one source, unless you specify each one individually.
import os
def recursive_install(target, source, env):
source_dirname = os.path.dirname(source)
for root, dirnames, filenames in os.walk(source):
for filename in filenames:
env.Install(os.path.join(
target, os.path.relpath(root, os.path.dirname(source))),
os.path.join(root, filename))
env = Environment()
recursive_install("out/bin", "path/to/folder", env)
env.Install("out/archive", "out/bin/folder/library.lib")
Which when run produces...
>> scons --version
SCons by Steven Knight et al.:
script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation
>> tree
.
├── path
│   └── to
│   └── folder
│   └── library.lib
└── SConstruct
3 directories, 2 files
>> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "path/to/folder/library.lib" as "out/bin/folder/library.lib"
Install file: "out/bin/folder/library.lib" as "out/archive/library.lib"
scons: done building targets.
>> tree
.
├── out
│   ├── archive
│   │   └── library.lib
│   └── bin
│   └── folder
│   └── library.lib
├── path
│   └── to
│   └── folder
│   └── library.lib
└── SConstruct
7 directories, 4 files
SCons doesn't have an option for recursively installing all files under a top-folder, because that's considered to be a rare case (note, how SCons prefers in-source-tree builds, such that you'd have to exclude a lot of files from the Install call otherwise). If you are creating the "files to install" within the same build, the preferred method would be to use the emitted list of targets from your Builder, and put it as second argument to the Install method:
mylibs = env.AnyBuilder('library', sources)
env.Install("out/bin", mylibs)
Then you don't have to manually list all the target files again with a recursive os.walk as in Kenneth's answer.

SWIG, perl, DynaLoader can't find boot_$Module on OS X

I am trying to build and install a SWIG-generated perl API on OS X 10.10.2. (It's for the FreeLing 3.1 language analysis toolkit.) I have generated and compiled the SWIG files, producing freeling.so.
But when I try to use freeling in a perl script, I get the error:
Can't find 'boot_freeling' symbol in /usr/local/lib/libfreeling.dylib at freeling.pm line 11.
But boot_freeling should be defined in the SWIG-generated freeling.so, not in libfreeling.dylib (the FreeLing package lib). (nm -U confirms this: _boot_freeling is defined in freeling.so; I'm assuming the leading underscore is just part of the object file format.)
I have made sure that freeling.so comes before libfreeling.dylib in LD_LIBRARY_PATH. I've also tried unshifting the path to freeling.so onto #DynaLoader::dl_library_path.
I suspect this is not a path problem, but something about building for OS X. In the past, I have built this on Ubuntu and it works fine. I have tweaked the gcc options (-bundle instead of -shared).
Additional info:
perl -V:dlext => dlext='bundle';
Building SOso-0.01.patch.txt produces:
blib
├── blib/arch
│   └── blib/arch/auto
│   └── blib/arch/auto/SOso
│   └── blib/arch/auto/SOso/SOso.bundle
├── blib/bin
├── blib/lib
│   ├── blib/lib/SOso.pm
│   └── blib/lib/auto
│   └── blib/lib/auto/SOso
├── blib/man1
├── blib/man3
└── blib/script
Makefile target:
freeling.bundle: freeling_perlAPI.cxx
g++ -v -bundle -o freeling.bundle freeling_perlAPI.cxx -lfreeling -lperl -lboost_system -I $(FREELINGDIR)/include -I $(BOOSTDIR)/include -I $(ICU4CDIR)/include -L $(FREELINGDIR)/libfreeling -I $(PERLDIR)/CORE -L $(LIBDIR) -L $(BOOSTDIR)/lib -L $(PERLDIR)/CORE -fPIC
Ok, promoting to answer :)
What do you get for perl -V:dlext ?
When you compile this module SOso-0.01.patch.txt what files are created in blib?
Well :) if your os/perl is configured to look for a freeling.bundle, I don't think its going to try to look at freeling.so .... so I'd try to do something about that ... rename the file to use the dlext

Resources