I have been trying to compile an asm file with tasm running on windows XP.
Tasm32 version - Turbo Assembler Version 5.0 Copyright (c) 1988, 1996 Borland International
Turbo Link Version 1.6.71.0 Copyright (c) 1993,1996 Borland International
With my current directory set to tasm\bin I have been able to do the following-
TASM32 /m29A /ml filename.asm
This generates the normal .Obj file. So far so good. Then I try to link using -
TLINK32 -Tpe -aa -x filename.obj,,,"kernel32.lib"
I am using the appropriate path to the kernel32.lib
But it is throwing up the following errors -
Fatal: Unable to open file 'filename.obj,,,C:\Program Files\Microsoft SDKs\Windo
ws\v6.0A\Lib\Kernel32.lib'
I have very little knowledge of asm and did Google around for a solution but I can't seem to find one. It seems that the linker is taking everything to be one single file.
Any help will be appreciated as I am completely at sea how to solve this.
Thank you.
I have Borland C++ Builder 5 installed, which includes tasm32 and tlink32.
The command-line options for TASM32 print as follows:
Turbo Assembler Version 5.3 Copyright (c) 1988, 2000 Inprise Corporation
Syntax: TASM [options] source [,object] [,listing] [,xref]
/a,/s Alphabetic or Source-code segment ordering
/c Generate cross-reference in listing
/dSYM[=VAL] Define symbol SYM = 0, or = value VAL
/e,/r Emulated or Real floating-point instructions
/h,/? Display this help screen
/iPATH Search PATH for include files
/jCMD Jam in an assembler directive CMD (eg. /jIDEAL)
/kh# Hash table capacity # symbols
/l,/la Generate listing: l=normal listing, la=expanded listing
/ml,/mx,/mu Case sensitivity on symbols: ml=all, mx=globals, mu=none
/mv# Set maximum valid length for symbols
/m# Allow # multiple passes to resolve forward references
/n Suppress symbol tables in listing
/os,/o,/op,/oi Object code: standard, standard w/overlays, Phar Lap, IBM
/p Check for code segment overrides in protected mode
/q Suppress OBJ records not needed for linking
/t Suppress messages if successful assembly
/uxxxx Set version emulation, version xxxx
/w0,/w1,/w2 Set warning level: w0=none, w1=w2=warnings on
/w-xxx,/w+xxx Disable (-) or enable (+) warning xxx
/x Include false conditionals in listing
/z Display source line with error message
/zi,/zd,/zn Debug info: zi=full, zd=line numbers only, zn=none
The command-line options for TLINK32 print as follows:
Turbo Link Version 2.5.0.0 Copyright (c) 1993,1998 Borland International
Syntax: TLINK32 objfiles, exefile, mapfile, libfiles, deffile, resfiles
#xxxx indicates use response file xxxx
-m Map file with publics -x No map
-s Detailed segment map -L Specify library search paths
-M Map with mangled names -j Specify object search paths
-c Case sensitive link -v Full symbolic debug information
-Enn Max number of errors -n No default libraries
-P- Disable code packing -H:xxxx Specify app heap reserve size
-OS Do smart linking
-B:xxxx Specify image base addr -Hc:xxxx Specify app heap commit size
-wxxx Warning control -S:xxxx Specify app stack reserve size
-Txx Specify output file type -Sc:xxxx Specify app stack commit size
-Tpx PE image -Af:nnnn Specify file alignment
(x: e=EXE, d=DLL) -Ao:nnnn Specify object alignment
-ax Specify application type -o Import by ordinals
-ap Windowing Compatible -Vd.d Specify Windows version
-aa Uses Windowing API -r Verbose link
So your linker command line
TLINK32 -Tpe -aa -x filename.obj,,,"kernel32.lib"
has the following options: -Tpe means output file type PE exe,
-aa means application type "uses Windowing API",
-x means no map.
Since the -n option was not specified, the default runtime libraries will be included.
Then there are six lists of filenames. The lists are separated by commas. The filenames are separated by spaces if I remember correctly.
Currently you have objfiles = filename.obj, resfiles=kernel32.lib, and the other four lists of filenames are empty. I think you actually mean kernel32.lib to be in the list of libfiles. Try this:
TLINK32 -Tpe -aa -x filename.obj, , , kernel32.lib, ,
This project will be easier to build and maintain if you create a makefile, because all it takes is one extra comma to make the linker stage fail. You've already experienced the frustration of trying to debug a mysterious build recipie.
# makefile for Borland make
# *** not tested yet! no source code.
# Not compatible with nmake.
# May be compatible with gnu make.
#
# Borland Turbo Assembler
$(TASM32)=TASM32.exe
$(TASM32FLAGS)=/m29A /ml
#
# Borland Turbo Link
$(TLINK32)=TLINK32.exe
$(TLINK32FLAGS)=-Tpe -aa -x
#
# objfiles
$(OBJ)=filename.obj
#
# exefile
$(BIN)=filename.exe
#
# mapfile
$(MAP)=
#
# libfiles
$(LIBS)=kernel32.lib
#
# deffile
$(DEF)=
#
# resfiles
$(RES)=
all: all-before $(BIN) all-after
$(BIN): filename.asm
# Turbo Assembler Version 5.3 Copyright (c) 1988, 2000 Inprise Corporation
# Syntax: TASM [options] source [,object] [,listing] [,xref]
.asm.o:
$(TASM32) $(TASM32FLAGS) $<
# Turbo Link Version 2.5.0.0 Copyright (c) 1993,1998 Borland International
# Syntax: TLINK32 objfiles, exefile, mapfile, libfiles, deffile, resfiles
# Note the commas separate the lists of filenames, not the filenames themselves
$(BIN): $(OBJ)
$(TLINK32) $(TLINK32FLAGS) $(OBJ), $(BIN), $(MAP), $(LIBS), $(DEF), $(RES)
Sorry this is about as far as I can get with this question, there's not much here that I can actually test. Hopefully this is enough to get your build on the right track. Good luck!
Related
I'm enabling IPO (inter-procedural optimization) for a C compilation of mine, using CMake:
set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
As expected, this causes an -flto compiler flag to be added. However, it also adds -fno-fat-lto-objects: That means that the resulting object file will only have intermediate code, rather than both properly-compiled and intermediate code; and that means that the linker must support my system compiler's intermediate representation and be IPO/LTO-aware.
I didn't ask for -fno-fat-lto-objects, nor did I want it. Can I get CMake to not add this option?
IMNSHO opinion this is a CMake bug... which I have filed as:
https://gitlab.kitware.com/cmake/cmake/-/issues/23136
The developers have simply made the incorrect assumption that this is what people want.
if(CMAKE_C_COMPILER MATCHES "GNU")
set(CMAKE_C_COMPILE_OPTIONS_IPO "-flto")
endif()
How to find it:
Navigate to your CMake installation directory and to Modules, most of the stuff is there.
It's /usr/share/cmake/Modules on my Linux system
Find the string or similar string that you are interested in
on my system, I do:
$ grep fno-fat-lto-objects -r .
./Compiler/GNU.cmake: list(APPEND __lto_flags -fno-fat-lto-objects)
Navigate and inspect the resulting files, the context where the string is used:
# '-flto' introduced since GCC 4.5:
# * https://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Option-Summary.html (no)
# * https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Option-Summary.html (yes)
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.5)
set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
set(__lto_flags -flto)
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.7)
# '-ffat-lto-objects' introduced since GCC 4.7:
# * https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Option-Summary.html (no)
# * https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html (yes)
list(APPEND __lto_flags -fno-fat-lto-objects)
endif()
set(CMAKE_${lang}_COMPILE_OPTIONS_IPO ${__lto_flags})
Come up with a workaround to implement custom behavior of such coe.
I'm writing firmware using an older C compiler called HC12. Currently I use GNU Make for the build system. I'm hoping to start using CMake, but ran into an issue:
The compiler does not support some standard C compiler syntax, namely the "-o" flag.
I've made a custom toolchain file and added all my c flags, but CMake seems to implicitly add the "-o" to compile source files, in the generated GNU Makefiles.
The HC12 compiler allows me to use -objn="name_of_file" to specify the output filename.
My question: Is there a way to get CMake to stop putting the implicit "-o" so that I can use this compiler?
I know there is a GCC port for this processor, but changing compilers at this point isn't an option.
You could take a file like the Modules/Compiler/ti.cmake as a reference and create one for your HC12 compiler, and also change these macros defined there:
# the input file options from TI, change to what your compiler needs
# They are used below in the command where ${lang} is either C, CXX or ASM
set(__COMPILER_HC12C_SOURCE_FLAG_C "--c_file")
set(__COMPILER_HC12C_SOURCE_FLAG_CXX "--cpp_file")
set(__COMPILER_HC12C_SOURCE_FLAG_ASM "--asm_file")
# add output file option
set(__COMPILER_HC12C_OUTPUT_FLAG_C "--objn")
macro(__compiler_HC12C lang)
# ...
set(CMAKE_${lang}_COMPILE_OBJECT "<CMAKE_${lang}_COMPILER> --compile_only ${__COMPILER_HC12C_SOURCE_FLAG_${lang}}=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> ${__COMPILER_HC12C_OUTPUT_FLAG_${lang}}=<OBJECT>")
# --------------------------------------- ---------------------------------------
# ...
endmacro()
Hope, this will help.
I've been exploring compilers and cross compilers. I'm reading the GCC manual.
Specifically, there are these statements in the manual that I have queries regarding:
The linker searches a standard list of directories for the library. The directories searched include several standard system directories plus any that you specify with -L.
The -isystem and -idirafter options also mark the directory as a system directory, so that it gets the same special treatment that is applied to the standard system directories.
Alright, what are these "system directories"? On a Linux machine, what are the system directories for the native compiler?
And if I've built a cross compiler (like the one shown here: https://wiki.osdev.org/GCC_Cross-Compiler), what are the "system directories" with respect to this compiler?
Can I change the system directory when I build GCC? Moreover, Where does sysroot come into the picture?
The "standard" system directories aren't specific directories - it may vary across installations/distributions.
gcc has an option -print-search-dirs. Using which you can get the list of directories, it looks for.
Something like:
gcc -print-search-dirs | grep libraries | sed 's/libraries: =//g' | tr ':' '\n' | xargs readlink -f
It's the same for cross compiler's too (you'd call cross compiler's front-end instead of plain gcc).
--sysroot is straightward:
--sysroot=dir Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers
in /usr/include and libraries in /usr/lib, it instead searches
dir/usr/include and dir/usr/lib.
If you use both this option and the -isysroot option, then the
--sysroot option applies to libraries, but the -isysroot option applies to header files.
The GNU linker (beginning with version 2.16) has the necessary support
for this option. If your linker does not support this option, the
header file aspect of --sysroot still works, but the library aspect
does not.
GCC is nothing if not configurable.
When you build an instance GCC, you need to completely specify the target environment. (Fortunately, most of this has already been done for you.) If necessary, you can tweak any of these settings before you do the build. The settings are described in detail in the GCC internals manual, but the particular ones you're interested in are in the chapter describing Target Macros, and particularly the section on Controlling the Compilation Driver. In this last section, you'll find descriptions of the various macros which define include paths. (Search for the word "include" in that page. Read everything you find :-); GCC documentation is not a tutorial.)
I installed masm32 on my Windows XP SP3 machine. I downloaded masm32 from here:
http://www.masm32.com/masmdl.htm
Installed it. I added the path, C:\masm32\bin to the PATH environment variable. Now, I am trying to assemble and link an example program. It creates the object file but does not create the executable file.
sample program:
include \masm32\include\masm32rt.inc
.data
MyTitle db "ASM!",0
MyText db "Some Text!",0
.code
start:
push 0
push offset MyTitle
push offset MyText
push 0
call MessageBoxA
call ExitProcess
end start
Also, please note that the default link.exe file which was present in the c:\masm32\bin directory was throwing an error while linking as shown below:
Assembling: sample.asm
***********
ASCII build
***********
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/z2
"sample.obj+"
"sample.obj"
"sample.exe"
NUL
LINK : warning LNK4044: unrecognized option "z2"; ignored
LINK : fatal error LNK1181: cannot open input file "sample.obj+"
I got another version of link.exe from here:
http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe
when I assemble and link using the following command:
ml.exe sample.asm sample.obj
It gives the error:
Assembling: sample.asm
***********
ASCII build
***********
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Object Modules [.obj]: sample.obj+
Object Modules [.obj]: "sample.obj"
Run File [sample.exe]: "sample.exe"
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:
LINK : fatal error L1104: \masm32\lib\masm32.lib : not valid library
Well, you definitely don't want to use the Segmented linker, this is for 16bit code. Continue using the Incremental Linker Version 5.12.8078
So, your getting an obj file? That is what ML.exe does. It is the MASM Assembler and it will Assemble your code into an obj file that you pass to the linker of your choice to create the exe. I say the linker of your choice, since there are a few linkers that you can use all with their own pros and cons.
To create an object file: ml /c /coff /Cp sample.asm
The /c option tells ml to Assemble only and not attempt to link
The /Cp option tells ml to preserve the case of all identifiers
/coff creates the obj file in the Common Object File Format, this is what we use for x86 on Windows.
Now, you need to link the obj file into the exe: link /subsystem:windows sample.obj
/subsystem:windows creates a GUI Windows exe. Change to console to create a console based app (NOT the same as a DOS app)
I need to build gcc-4.3.4 in a non-standard location (NFS mounted). I configured:
../gcc-4.3.4/configure --prefix={install dir} --with-gmp={install dir} --with-mpfr={install dir} --with-local-prefix={install dir} --disable-shared
I ran make -j1. But I keep getting:
checking for suffix of object files... configure: error: cannot compute suffix of object files: cannot compile
In x86_64-unknown-linux-gnu/libgcc/config.log, I can see:
/home/panthdev/apps/gcc-4.3.4-compliant/compiler/objdir/./gcc/cc1: error while loading shared libraries: libmpfr.so.1: cannot open shared object file: No such file or directory
libmpfr.so.1 is there in {install dir}/lib. Also if I set LD_LIBRARY_PATH to {install dir}/lib, then it finds the libmpfr.so.1 but config.log starts complaining:
/tmp/cce9YhFK.s: Assembler messages:
/tmp/cce9YhFK.s:16: Error: bad register name `%rbp'
/tmp/cce9YhFK.s:18: Error: bad register name `%rsp'
As I read here you have 32bit binutils where as gcc is trying to do a 64bit build. Make sure your binutils & gcc has the same configuration.
You should maybe try using --with-sysroot instead of --prefix.
In the GCC 4.5.2 configure script (I have that available, but not 4.3.4), at around line 4500 (of 15.5K lines), there is the stanza:
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if test "${ac_cv_objext+set}" = set; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { { ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then :
for ac_file in conftest.o conftest.obj conftest.*; do
test -f "$ac_file" || continue;
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error "cannot compute suffix of object files: cannot compile
See \`config.log' for more details." "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
Basically, the script is trying to compile 'conftest.c' and trying to find the extension of the object file created - and, for some reason, your compiler is not creating a conftest.o.
This isn't the first test it does on the compiler, so there seems to be something rather odd going on in your environment.
I've built GCC numerous times over the years - on Solaris and MacOS X - and I've always used the --prefix option. That is not the problem. The GMP, MPFR, MPC directories are necessary; the only option you've used that I'm not familiar with is the --with-local-prefix.
Are you specifying the bootstrap compiler somehow? Consider trying your current configure line with the addition of CC=/usr/bin/gcc or something similar, identifying a fully working compiler on your machine. I'm not convinced that'll solve the problem, but there is something funny about the way the compiler is behaving, or about the object file extensions that it produces. I assume you have several GB of spare space on the disk system? You'll need that.
Poking around the 'Installing GCC: Configuration' page, I find:
--with-local-prefix=dirname
Specify the installation directory for local include files. The default is /usr/local. Specify this option if you want the compiler to search directory dirname/include for locally installed header files instead of /usr/local/include.
You should specify --with-local-prefix only if your site has a different convention (not /usr/local) for where to put site-specific files.
The default value for --with-local-prefix is /usr/local regardless of the value of --prefix. Specifying --prefix has no effect on which directory GCC searches for local header files. This may seem counterintuitive, but actually it is logical.
The purpose of --prefix is to specify where to install GCC. The local header files in /usr/local/include—if you put any in that directory—are not part of GCC. They are part of other programs—perhaps many others. (GCC installs its own header files in another directory which is based on the --prefix value.)
Both the local-prefix include directory and the GCC-prefix include directory are part of GCC's “system include” directories. Although these two directories are not fixed, they need to be searched in the proper order for the correct processing of the include_next directive. The local-prefix include directory is searched before the GCC-prefix include directory. Another characteristic of system include directories is that pedantic warnings are turned off for headers in these directories.
Some autoconf macros add -I directory options to the compiler command line, to ensure that directories containing installed packages' headers are searched. When directory is one of GCC's system include directories, GCC will ignore the option so that system directories continue to be processed in the correct order. This may result in a search order different from what was specified but the directory will still be searched.
GCC automatically searches for ordinary libraries using GCC_EXEC_PREFIX. Thus, when the same installation prefix is used for both GCC and packages, GCC will automatically search for both headers and libraries. This provides a configuration that is easy to use. GCC behaves in a manner similar to that when it is installed as a system compiler in /usr.
Sites that need to install multiple versions of GCC may not want to use the above simple configuration. It is possible to use the --program-prefix, --program-suffix and --program-transform-name options to install multiple versions into a single directory, but it may be simpler to use different prefixes and the --with-local-prefix option to specify the location of the site-specific files for each version. It will then be necessary for users to specify explicitly the location of local site libraries (e.g., with LIBRARY_PATH).
The same value can be used for both --with-local-prefix and --prefix provided it is not /usr. This can be used to avoid the default search of /usr/local/include.
Do not specify /usr as the --with-local-prefix! The directory you use for --with-local-prefix must not contain any of the system's standard header files. If it did contain them, certain programs would be miscompiled (including GNU Emacs, on certain targets), because this would override and nullify the header file corrections made by the fixincludes script.
Indications are that people who use this option use it based on mistaken ideas of what it is for. People use it as if it specified where to install part of GCC. Perhaps they make this assumption because installing GCC creates the directory.
Are you sure you're using that correctly? You probably are since you have to search to find the option -- ../gcc-4.x.y/configure --help does not mention the option.